mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-04 08:16:16 +00:00
Merge remote-tracking branch 'upstream/develop' into 7656-custom-mime-type-hdb-files
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.core/10
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
|
||||
OpenIDE-Module-Implementation-Version: 35
|
||||
OpenIDE-Module-Implementation-Version: 36
|
||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||
AutoUpdate-Show-In-Client: true
|
||||
AutoUpdate-Essential-Module: true
|
||||
|
||||
@@ -109,8 +109,8 @@ file.reference.protobuf-java-util-3.7.0.jar=release\\modules\\ext\\protobuf-java
|
||||
file.reference.Rejistry-1.1-SNAPSHOT.jar=release\\modules\\ext\\Rejistry-1.1-SNAPSHOT.jar
|
||||
file.reference.sevenzipjbinding-AllPlatforms.jar=release\\modules\\ext\\sevenzipjbinding-AllPlatforms.jar
|
||||
file.reference.sevenzipjbinding.jar=release\\modules\\ext\\sevenzipjbinding.jar
|
||||
file.reference.sleuthkit-4.10.2.jar=release/modules/ext/sleuthkit-4.10.2.jar
|
||||
file.reference.sleuthkit-caseuco-4.10.2.jar=release/modules/ext/sleuthkit-caseuco-4.10.2.jar
|
||||
file.reference.sleuthkit-4.11.0.jar=release/modules/ext/sleuthkit-4.11.0.jar
|
||||
file.reference.sleuthkit-caseuco-4.11.0.jar=release/modules/ext/sleuthkit-caseuco-4.11.0.jar
|
||||
file.reference.slf4j-api-1.7.6.jar=release\\modules\\ext\\slf4j-api-1.7.6.jar
|
||||
file.reference.slf4j-log4j12-1.7.6.jar=release\\modules\\ext\\slf4j-log4j12-1.7.6.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release\\modules\\ext\\SparseBitSet-1.1.jar
|
||||
@@ -128,4 +128,4 @@ nbm.homepage=http://www.sleuthkit.org/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
|
||||
spec.version.base=10.23
|
||||
spec.version.base=10.24
|
||||
|
||||
@@ -682,8 +682,8 @@
|
||||
<binary-origin>release\modules\ext\grpc-alts-1.19.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.10.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.10.2.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.11.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.11.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
|
||||
@@ -802,8 +802,8 @@
|
||||
<binary-origin>release\modules\ext\sevenzipjbinding-AllPlatforms.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-4.10.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.10.2.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-4.11.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.11.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jutf7-1.0.0.jar</runtime-relative-path>
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
AddBlackboardArtifactTagAction.pluralTagResult=Add Result Tags
|
||||
AddBlackboardArtifactTagAction.singularTagResult=Add Result Tag
|
||||
AddBlackboardArtifactTagAction.taggingErr=Tagging Error
|
||||
# {0} - artifactName
|
||||
AddBlackboardArtifactTagAction.unableToTag.msg=Unable to tag {0}.
|
||||
AddContentTagAction.cannotApplyTagErr=Cannot Apply Tag
|
||||
AddContentTagAction.pluralTagFile=Add File Tags
|
||||
AddContentTagAction.singularTagFile=Add File Tag
|
||||
# {0} - fileName
|
||||
# {1} - tagName
|
||||
AddContentTagAction.tagExists={0} has been tagged as {1}. Cannot reapply the same tag.
|
||||
AddContentTagAction.taggingErr=Tagging Error
|
||||
# {0} - fileName
|
||||
AddContentTagAction.unableToTag.msg=Unable to tag {0}, not a regular file.
|
||||
# {0} - fileName
|
||||
AddContentTagAction.unableToTag.msg2=Unable to tag {0}.
|
||||
CTL_DumpThreadAction=Thread Dump
|
||||
CTL_ShowIngestProgressSnapshotAction=Ingest Status Details
|
||||
DeleteBlackboardArtifactTagAction.deleteTag=Remove Selected Tag(s)
|
||||
DeleteBlackboardArtifactTagAction.tagDelErr=Tag Deletion Error
|
||||
# {0} - tagName
|
||||
DeleteBlackboardArtifactTagAction.unableToDelTag.msg=Unable to delete tag {0}.
|
||||
DeleteContentTagAction.deleteTag=Remove Selected Tag(s)
|
||||
DeleteContentTagAction.tagDelErr=Tag Deletion Error
|
||||
@@ -84,8 +78,6 @@ CTL_OpenOutputFolder=Open Case Folder
|
||||
OpenOutputFolder.error1=Case Folder Not Found: {0}
|
||||
OpenOutputFolder.noCaseOpen=No open case, therefore no current case folder available.
|
||||
OpenOutputFolder.CouldNotOpenOutputFolder=Could not open case folder
|
||||
# {0} - old tag name
|
||||
# {1} - artifactID
|
||||
ReplaceBlackboardArtifactTagAction.replaceTag.alert=Unable to replace tag {0} for artifact {1}.
|
||||
# {0} - old tag name
|
||||
# {1} - content obj id
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Thu Jul 01 11:56:41 UTC 2021
|
||||
AddBlackboardArtifactTagAction.pluralTagResult=\u7d50\u679c\u30bf\u30b0\u3092\u8ffd\u52a0
|
||||
AddBlackboardArtifactTagAction.singularTagResult=\u7d50\u679c\u30bf\u30b0\u3092\u8ffd\u52a0
|
||||
AddBlackboardArtifactTagAction.taggingErr=\u30bf\u30b0\u4ed8\u3051\u30a8\u30e9\u30fc
|
||||
@@ -17,6 +17,7 @@ AddTagAction.noTags=\u30bf\u30b0\u306a\u3057
|
||||
AddTagAction.quickTag=\u30af\u30a4\u30c3\u30af\u30bf\u30b0
|
||||
AddTagAction.tagAndComment=\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8...
|
||||
CTL_DumpThreadAction=\u30b9\u30ec\u30c3\u30c9 \u30c0\u30f3\u30d7
|
||||
CTL_ExitAction=\u51fa\u53e3
|
||||
CTL_OpenLogFolder=\u30ed\u30b0\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f
|
||||
CTL_OpenOutputFolder=\u51fa\u529b\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f
|
||||
CTL_OpenPythonModulesFolderAction=Python\u30d7\u30e9\u30b0\u30a4\u30f3
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#Thu Jul 01 11:56:40 UTC 2021
|
||||
CTL_ResetWindowsAction=\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30ea\u30bb\u30c3\u30c8
|
||||
ResetWindowAction.caseCloseFailure.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306f\u518d\u8d77\u52d5\u3057\u3001\u6b21\u306b\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u9589\u3058\u308b\u3068\u304d\u306bWindows\u306e\u5834\u6240\u304c\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3059\u3002
|
||||
ResetWindowAction.caseSaveMetadata.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u30d1\u30b9\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3002\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306f\u518d\u8d77\u52d5\u3057\u3001Windows\u306e\u5834\u6240\u306f\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u307e\u3059\u304c\u3001\u518d\u8d77\u52d5\u6642\u306b\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u306f\u958b\u304b\u308c\u307e\u305b\u3093\u3002
|
||||
ResetWindowAction.confirm.text=\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u5834\u6240\u306e\u30ea\u30bb\u30c3\u30c8\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u3001\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306f\u9589\u3058\u3066\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002 \u30b1\u30fc\u30b9\u304c\u73fe\u5728\u958b\u3044\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u9589\u3058\u3089\u308c\u307e\u3059\u3002 \u53d6\u308a\u8fbc\u307f\u307e\u305f\u306f\u691c\u7d22\u304c\u73fe\u5728\u5b9f\u884c\u4e2d\u306e\u5834\u5408\u3001\u305d\u308c\u306f\u5f37\u5236\u7d42\u4e86\u3057\u307e\u3059\u3002 \u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u518d\u8d77\u52d5\u3057\u3066\u3001\u3059\u3079\u3066\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u306e\u5834\u6240\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f
|
||||
@@ -247,15 +247,10 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi
|
||||
AddImageWizardIngestConfigVisual.getName.text=Configure Ingest
|
||||
AddImageWizardIterator.stepXofN=Step {0} of {1}
|
||||
AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1}
|
||||
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
|
||||
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open!
|
||||
Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0}
|
||||
Case.open.msgDlg.updated.title=Case Database Schema Update
|
||||
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\
|
||||
this case are missing. Would you like to search for them now?\n\
|
||||
Previously, the image was located at:\n\
|
||||
{0}\n\
|
||||
Please note that you will still be able to browse directories and generate reports\n\
|
||||
if you choose No, but you will not be able to view file content or run the ingest process.
|
||||
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process.
|
||||
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
||||
Case.addImg.exception.msg=Error adding image to the case
|
||||
Case.updateCaseName.exception.msg=Error while trying to update the case name.
|
||||
@@ -274,12 +269,9 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type
|
||||
Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted.
|
||||
Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
|
||||
Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}
|
||||
CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\
|
||||
Case Name: {0}\n\
|
||||
Case Directory: {1}
|
||||
CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1}
|
||||
CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case
|
||||
CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\
|
||||
Close the folder and file and try again or you can delete the case manually.
|
||||
CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually.
|
||||
CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use
|
||||
CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted.
|
||||
CaseOpenAction.autFilter.title={0} Case File ( {1})
|
||||
@@ -311,8 +303,7 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case
|
||||
NewCaseWizardAction.databaseProblem2.text=Error
|
||||
NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > |
|
||||
NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists.
|
||||
NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\
|
||||
Do you want to create that directory?
|
||||
NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory?
|
||||
NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory
|
||||
NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0}
|
||||
NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0}
|
||||
@@ -341,7 +332,6 @@ OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone:
|
||||
OptionalCasePropertiesPanel.orgainizationPanel.border.title=Organization
|
||||
RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of range.
|
||||
RecentCases.getName.text=Clear Recent Cases
|
||||
# {0} - case name
|
||||
RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists.
|
||||
SelectDataSourceProcessorPanel.name.text=Select Data Source Type
|
||||
StartupWindow.title.text=Welcome
|
||||
@@ -354,7 +344,6 @@ StartupWindowProvider.openCase.noFile=Unable to open previously open case becaus
|
||||
UnpackagePortableCaseDialog.title.text=Unpackage Portable Case
|
||||
UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001)
|
||||
UnpackagePortableCaseDialog.validatePaths.badExtension=File extension must be .zip or .zip.001
|
||||
# {0} - case folder
|
||||
UnpackagePortableCaseDialog.validatePaths.caseFolderExists=Folder {0} already exists
|
||||
UnpackagePortableCaseDialog.validatePaths.caseIsNotFile=Selected path is not a file
|
||||
UnpackagePortableCaseDialog.validatePaths.caseNotFound=File does not exist
|
||||
@@ -369,8 +358,8 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene
|
||||
UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases
|
||||
UpdateRecentCases.menuItem.empty=-Empty-
|
||||
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
|
||||
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive
|
||||
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system
|
||||
NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive
|
||||
NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system
|
||||
NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive.
|
||||
NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases
|
||||
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
|
||||
@@ -378,7 +367,7 @@ CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
|
||||
MissingImageDialog.lbWarning.text=
|
||||
MissingImageDialog.lbWarning.toolTipText=
|
||||
NewCaseVisualPanel1.caseParentDirWarningLabel.text=
|
||||
NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User
|
||||
NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User\t\t
|
||||
NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User
|
||||
NewCaseVisualPanel1.caseTypeLabel.text=Case Type:
|
||||
SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AddImageAction.ingestConfig.ongoingIngest.msg=<html>\u5225\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u65b0\u898f\u30bd\u30fc\u30b9\u3092\u4eca\u8ffd\u52a0\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u51e6\u7406\u304c\u9045\u304f\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002<br />\u7d9a\u884c\u3057\u3066\u65b0\u898f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u4eca\u3059\u3050\u8ffd\u52a0\u3057\u307e\u3059\u304b?</html>
|
||||
AddImageAction.ingestConfig.ongoingIngest.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059
|
||||
AddImageAction.wizard.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
||||
@@ -25,10 +25,17 @@ AddImageWizardChooseDataSourceVisual.getName.text=\u30c7\u30fc\u30bf\u30bd\u30fc
|
||||
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=\u53d6\u308a\u6d88\u3057
|
||||
AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002
|
||||
AddImageWizardIngestConfigPanel.name.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210
|
||||
AddImageWizardIngestConfigVisual.getName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u69cb\u6210
|
||||
AddImageWizardIngestConfigPanel.name.text=\u53d6\u8fbc\u307f\u306e\u69cb\u6210
|
||||
AddImageWizardIngestConfigVisual.getName.text=\u53d6\u8fbc\u307f\u306e\u69cb\u6210
|
||||
AddImageWizardIterator.stepXofN=\u624b\u9806 {0} / {1}
|
||||
AddImageWizardSelectDspVisual.multiUserWarning.text=\u3053\u306e\u30bf\u30a4\u30d7\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30e2\u30fc\u30c9\u3067\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
AddImageWizardSelectHostPanel_title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0\u3059\u308b\u30db\u30b9\u30c8\u306e\u9078\u629e
|
||||
AddImageWizardSelectHostVisual.generateNewRadio.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d\u306b\u57fa\u3065\u3044\u3066\u65b0\u30db\u30b9\u30c8\u540d\u306e\u4f5c\u6210
|
||||
AddImageWizardSelectHostVisual.hostDescription.text=\u30db\u30b9\u30c8\u306f\u3001\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3084\u305d\u306e\u4ed6\u306e\u30c7\u30fc\u30bf\u3092\u6574\u7406\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002
|
||||
AddImageWizardSelectHostVisual.specifyNewHostRadio.text=\u65b0\u30db\u30b9\u30c8\u540d\u306e\u6307\u5b9a
|
||||
AddImageWizardSelectHostVisual.useExistingHostRadio.text=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u306e\u4f7f\u7528
|
||||
AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=\u65e2\u5b58\u306e\u30db\u30b9\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
AddImageWizardSelectHostVisual_title=\u30db\u30b9\u30c8\u306e\u9078\u629e
|
||||
AddLocalFilesTask.localFileAdd.progress.text=\u6b21\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\: {0}/{1}
|
||||
CTL_AddImage=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
||||
CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
||||
@@ -60,6 +67,7 @@ Case.deleteCaseFailureMessageBox.title=\u30b1\u30fc\u30b9\u3092\u524a\u9664\u306
|
||||
Case.deleteReports.deleteFromDiskException.log.msg=\u30c7\u30a3\u30b9\u30af\u304b\u3089\u30ec\u30dd\u30fc\u30c8\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
Case.deleteReports.deleteFromDiskException.msg=\u30c7\u30a3\u30b9\u30af\u304b\u3089\u30ec\u30dd\u30fc\u30c8 {0} \u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002\n{1} \u304b\u3089\u624b\u52d5\u3067\u524a\u9664\u3067\u304d\u307e\u3059
|
||||
Case.exception.errGetRootObj=\u30eb\u30fc\u30c8\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
Case.exceptionMessage.cancelled=\u30ad\u30e3\u30f3\u30bb\u30eb\u3002
|
||||
Case.exceptionMessage.cancelledByUser=\u30e6\u30fc\u30b6\u30fc\u306b\u3088\u3063\u3066\u53d6\u308a\u6d88\u3055\u308c\u307e\u3057\u305f\u3002
|
||||
Case.exceptionMessage.cannotDeleteCurrentCase=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002\u6700\u521d\u306b\u9589\u3058\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
Case.exceptionMessage.cannotGetLockToDeleteCase=\u5225\u306e\u30e6\u30fc\u30b6\u30fc\u307e\u305f\u306f\u30db\u30b9\u30c8\u304c\u958b\u3044\u3066\u3044\u308b\u305f\u3081\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
@@ -74,9 +82,12 @@ Case.exceptionMessage.couldNotOpenRemoteEventChannel=\u30ea\u30e2\u30fc\u30c8\u3
|
||||
Case.exceptionMessage.couldNotSaveCaseMetadata=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}\u3002
|
||||
Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\u3092\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}\u3002
|
||||
Case.exceptionMessage.couldNotUpdateCaseNodeData=\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}\u3002
|
||||
Case.exceptionMessage.dataSourceNotFound=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
Case.exceptionMessage.deletionInterrupted=\u30b1\u30fc\u30b9 {0} \u306e\u524a\u9664\u304c\u53d6\u308a\u6d88\u3055\u308c\u307e\u3057\u305f\u3002
|
||||
Case.exceptionMessage.emptyCaseDir=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u30d1\u30b9\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
Case.exceptionMessage.emptyCaseName=\u30b1\u30fc\u30b9\u540d\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=\u30c6\u30ad\u30b9\u30c8\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u304b\u3089\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
Case.exceptionMessage.errorsDeletingCase=\u30b1\u30fc\u30b9\u306e\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u8a73\u7d30\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b0\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
Case.exceptionMessage.execExceptionWrapperMessage={0}
|
||||
Case.exceptionMessage.failedToConnectToCoordSvc=\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\:\n{0}.
|
||||
@@ -86,6 +97,8 @@ Case.exceptionMessage.failedToReadMetadata=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\
|
||||
Case.exceptionMessage.metadataUpdateError=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
|
||||
Case.exceptionMessage.unsupportedSchemaVersionMessage=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059\:\n{0}\u3002
|
||||
Case.getCurCase.exception.noneOpen=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002\u30b1\u30fc\u30b9\u304c\u958b\u304b\u308c\u3066\u3044\u307e\u305b\u3093\!
|
||||
Case.lockingException.couldNotAcquireExclusiveLock=\u30b1\u30fc\u30b9\u306e\u6392\u4ed6\u30ed\u30c3\u30af\u304c\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
Case.lockingException.couldNotAcquireSharedLock=\u30b1\u30fc\u30b9\u306e\u5171\u6709\u30ed\u30c3\u30af\u304c\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
Case.metaDataFileCorrupt.exception.msg=\u30b1\u30fc\u30b9\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb(.aut)\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002
|
||||
Case.open.exception.multiUserCaseNotEnabled=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u304c\u6709\u52b9\u3067\u306a\u3044\u5834\u5408\u306f\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002[\u30c4\u30fc\u30eb]\u3001[\u30aa\u30d7\u30b7\u30e7\u30f3]\u3001[\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc] \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
Case.open.msgDlg.updated.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\:\n {0}
|
||||
@@ -96,6 +109,7 @@ Case.progressIndicatorCancelButton.label=\u53d6\u308a\u6d88\u3057
|
||||
Case.progressIndicatorTitle.closingCase=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u3066\u3044\u307e\u3059
|
||||
Case.progressIndicatorTitle.creatingCase=\u30b1\u30fc\u30b9\u3092\u4f5c\u6210\u4e2d\u3067\u3059
|
||||
Case.progressIndicatorTitle.deletingCase=\u30b1\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u3067\u3059
|
||||
Case.progressIndicatorTitle.deletingDataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u524a\u9664\u4e2d
|
||||
Case.progressIndicatorTitle.openingCase=\u30b1\u30fc\u30b9\u3092\u958b\u3044\u3066\u3044\u307e\u3059
|
||||
Case.progressMessage.cancelling=\u53d6\u308a\u6d88\u3057\u4e2d\u3067\u3059...
|
||||
Case.progressMessage.clearingTempDirectory=\u30b1\u30fc\u30b9\u306e\u4e00\u6642\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u6d88\u53bb\u4e2d\u3067\u3059...
|
||||
@@ -109,6 +123,7 @@ Case.progressMessage.creatingCaseNodeData=\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u
|
||||
Case.progressMessage.deletingCaseDatabase=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664\u4e2d\u3067\u3059...
|
||||
Case.progressMessage.deletingCaseDirCoordSvcNode=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u306e\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u524a\u9664\u4e2d\u3067\u3059...
|
||||
Case.progressMessage.deletingCaseDirectory=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u524a\u9664\u4e2d\u3067\u3059...
|
||||
Case.progressMessage.deletingDataSource=\u30b1\u30fc\u30b9\u304b\u3089\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u4e2d...
|
||||
Case.progressMessage.deletingResourcesCoordSvcNode=\u30b1\u30fc\u30b9\u30ea\u30bd\u30fc\u30b9\u306e\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u524a\u9664\u4e2d\u3067\u3059...
|
||||
Case.progressMessage.deletingTextIndex=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u3092\u524a\u9664\u4e2d\u3067\u3059...
|
||||
Case.progressMessage.fetchingCoordSvcNodeData=\u30b1\u30fc\u30b9\u306e\u5ea7\u6a19\u30b5\u30fc\u30d3\u30b9\u30ce\u30fc\u30c9\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u3067\u3059...
|
||||
@@ -179,6 +194,11 @@ CueBannerPanel.openCaseLabel.text=\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||
CueBannerPanel.openRecentCaseButton.text=
|
||||
CueBannerPanel.openRecentCaseLabel.text=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||
CueBannerPanel.title.text=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||
DeleteDataSourceAction.confirmationDialog.message=\u9078\u629e\u3057\u305f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u30b1\u30fc\u30b9\u304b\u3089\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f\n\u6ce8\u610f\uff1a\u524a\u9664\u4e2d\u306b\u30b1\u30fc\u30b9\u304c\u9589\u3058\u3089\u308c\u3001\u518d\u3073\u958b\u304b\u308c\u307e\u3059\u3002\u300d
|
||||
DeleteDataSourceAction.exceptionMessage.couldNotReopenCase=\u30b1\u30fc\u30b9\u3092\u518d\u958b\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a\n{0}\n\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b0\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
DeleteDataSourceAction.exceptionMessage.dataSourceDeletionError=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a\n{0}\n\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b0\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
DeleteDataSourceAction.ingestRunningWarningDialog.message=\u53d6\u8fbc\u307f\u306e\u5b9f\u884c\u4e2d\u306f\u3001\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u30b1\u30fc\u30b9\u304b\u3089\u524a\u9664\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
DeleteDataSourceAction.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u524a\u9664\u3059\u308b
|
||||
EditOptionalCasePropertiesPanel.cancelButton.text=\u53d6\u308a\u6d88\u3057
|
||||
EditOptionalCasePropertiesPanel.saveButton.text=\u4fdd\u5b58
|
||||
GeneralFilter.encaseImageDesc.text=\u30a4\u30e1\u30fc\u30b8(*.e01)\u3092\u5305\u542b
|
||||
@@ -297,7 +317,6 @@ LogicalEvidenceFilePanel.selectButton.toolTipText=\u30ed\u30fc\u30ab\u30eb\u30d5
|
||||
LogicalEvidenceFilePanel.validatePanel.nonL01Error.text=\u3053\u3053\u3067\u306f .l01\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u3092\u6301\u3064\u30d5\u30a1\u30a4\u30eb\u306e\u307f\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u3059\u3002
|
||||
LogicalFilesDspPanel.subTypeComboBox.l01FileOption.text=\u8ad6\u7406\u8a3c\u62e0\u30d5\u30a1\u30a4\u30eb(L01)
|
||||
LogicalFilesDspPanel.subTypeComboBox.localFilesOption.text=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30d5\u30a9\u30eb\u30c0\u30fc
|
||||
Menu/Case/OpenRecentCase=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||
MissingImageDialog.ErrorSettingImage=\u30a4\u30e1\u30fc\u30b8\u30d1\u30b9\u306e\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002
|
||||
MissingImageDialog.browseButton.text=\u53c2\u7167
|
||||
MissingImageDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
|
||||
@@ -349,6 +368,7 @@ OpenMultiUserCaseDialog.title=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u30b1\u
|
||||
OpenMultiUserCasePanel.cancelButton.text=\u53d6\u308a\u6d88\u3057
|
||||
OpenMultiUserCasePanel.openSelectedCaseButton.text=\u9078\u629e\u3057\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||
OpenMultiUserCasePanel.openSingleUserCaseButton.tex=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u304f...
|
||||
OpenMultiUserCasePanel.openSingleUserCaseButton.text=\u5358\u72ec\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9\u3092\u958b\u304f...
|
||||
OpenMultiUserCasePanel.searchLabel.text=\u4efb\u610f\u306e\u30b1\u30fc\u30b9\u3092\u9078\u629e\u3057\u3001\u5165\u529b\u3092\u958b\u59cb\u3057\u3066\u30b1\u30fc\u30b9\u540d\u3067\u691c\u7d22
|
||||
OpenRecentCasePanel.cancelButton.text=\u53d6\u308a\u6d88\u3057
|
||||
OpenRecentCasePanel.colName.caseName=\u30b1\u30fc\u30b9\u540d
|
||||
@@ -384,7 +404,7 @@ ReviewModeCasePanel.StatusIconHeaderText=\u30b9\u30c6\u30fc\u30bf\u30b9
|
||||
ReviewModeCasePanel.cannotOpenCase=\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093
|
||||
ReviewModeCasePanel.caseIsLocked=\u30b7\u30f3\u30b0\u30eb\u30e6\u30fc\u30b6\u30fc\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059\u3002
|
||||
ReviewModeCasePanel.casePathNotFound=\u30b1\u30fc\u30b9\u30d1\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
|
||||
SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u8ffd\u52a0
|
||||
SelectDataSourceProcessorPanel.name.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u306e\u9078\u629e
|
||||
SingleUserCaseConverter.AlreadyMultiUser=\u30b1\u30fc\u30b9\u306f\u3059\u3067\u306b\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u3067\u3059\!
|
||||
SingleUserCaseConverter.BadDatabaseFileName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\!
|
||||
SingleUserCaseConverter.CanNotOpenDatabase=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093
|
||||
@@ -395,6 +415,9 @@ SolrNotConfiguredDialog.messageLabel.text=<html>\u30de\u30eb\u30c1\u30e6\u30fc\u
|
||||
SolrNotConfiguredDialog.okButton.text=OK
|
||||
SolrNotConfiguredDialog.title=Solr8\u30b5\u30fc\u30d0\u30fc\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
|
||||
StartupWindow.title.text=\u3088\u3046\u3053\u305d
|
||||
StartupWindowProvider.openCase.cantOpen=\u4ee5\u524d\u306b\u958b\u3044\u305f\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u4ed8\u304d\u306e\u30b1\u30fc\u30b9\u3092\u958b\u304f\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\uff1a{0}
|
||||
StartupWindowProvider.openCase.deleteOpenFailure=\u4ee5\u524d\u306b\u958b\u3044\u305f\u30d1\u30b9{0}\u3092\u542b\u3080\u30b1\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u3044\u305f\u308a\u524a\u9664\u3092\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
StartupWindowProvider.openCase.noFile=\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u304c{0}\u306b\u898b\u3064\u304b\u3089\u306a\u3044\u305f\u3081\u3001\u4ee5\u524d\u306b\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=\u30dd\u30fc\u30bf\u30d6\u30eb\u30b1\u30fc\u30b9\u30d1\u30c3\u30b1\u30fc\u30b8(.zip, .zip.001)
|
||||
UnpackagePortableCaseDialog.caseErrorLabel.text=jLabel1
|
||||
UnpackagePortableCaseDialog.caseLabel.text=\u30dd\u30fc\u30bf\u30d6\u30eb\u30b1\u30fc\u30b9\:
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils;
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.awt.Cursor;
|
||||
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -85,13 +86,16 @@ import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceNameChangedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsChangedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsRemovedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountChangedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsAddedToPersonEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsUpdatedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.HostsRemovedFromPersonEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountsAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountsUpdatedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountsDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAcctInstancesAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.PersonsAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.PersonsChangedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.PersonsUpdatedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.PersonsDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData.CaseNodeDataException;
|
||||
@@ -190,7 +194,7 @@ public class Case {
|
||||
private final SleuthkitEventListener sleuthkitEventListener;
|
||||
private CollaborationMonitor collaborationMonitor;
|
||||
private Services caseServices;
|
||||
|
||||
|
||||
private volatile boolean hasDataSource = false;
|
||||
private volatile boolean hasData = false;
|
||||
|
||||
@@ -434,43 +438,54 @@ public class Case {
|
||||
*/
|
||||
CR_COMMENT_CHANGED,
|
||||
/**
|
||||
* OSAccount associated with the current case added. Call getOsAccount
|
||||
* to get the added account;
|
||||
* One or more OS accounts have been added to the case.
|
||||
*/
|
||||
OS_ACCOUNT_ADDED,
|
||||
OS_ACCOUNTS_ADDED,
|
||||
/**
|
||||
* OSAccount associated with the current case has changed. Call
|
||||
* getOsAccount to get the changed account;
|
||||
* One or more OS accounts in the case have been updated.
|
||||
*/
|
||||
OS_ACCOUNT_CHANGED,
|
||||
OS_ACCOUNTS_UPDATED,
|
||||
/**
|
||||
* OSAccount associated with the current case has been deleted.
|
||||
* One or more OS accounts have been deleted from the case.
|
||||
*/
|
||||
OS_ACCOUNT_REMOVED,
|
||||
OS_ACCOUNTS_DELETED,
|
||||
/**
|
||||
* Hosts associated with the current case added.
|
||||
* One or more OS account instances have been added to the case.
|
||||
*/
|
||||
OS_ACCT_INSTANCES_ADDED,
|
||||
/**
|
||||
* One or more hosts have been added to the case.
|
||||
*/
|
||||
HOSTS_ADDED,
|
||||
/**
|
||||
* Hosts associated with the current case has changed.
|
||||
* One or more hosts in the case have been updated.
|
||||
*/
|
||||
HOSTS_CHANGED,
|
||||
HOSTS_UPDATED,
|
||||
/**
|
||||
* Hosts associated with the current case has been deleted.
|
||||
* One or more hosts have been deleted from the case.
|
||||
*/
|
||||
HOSTS_DELETED,
|
||||
/**
|
||||
* Persons associated with the current case added.
|
||||
* One or more persons have been added to the case.
|
||||
*/
|
||||
PERSONS_ADDED,
|
||||
/**
|
||||
* Persons associated with the current case has changed.
|
||||
* One or more persons in the case have been updated.
|
||||
*/
|
||||
PERSONS_CHANGED,
|
||||
PERSONS_UPDATED,
|
||||
/**
|
||||
* Persons associated with the current case has been deleted.
|
||||
* One or more persons been deleted from the case.
|
||||
*/
|
||||
PERSONS_DELETED;
|
||||
PERSONS_DELETED,
|
||||
/**
|
||||
* One or more hosts have been added to a person.
|
||||
*/
|
||||
HOSTS_ADDED_TO_PERSON,
|
||||
/**
|
||||
* One or more hosts have been removed from a person.
|
||||
*/
|
||||
HOSTS_REMOVED_FROM_PERSON;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -505,18 +520,14 @@ public class Case {
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void publishOsAccountAddedEvent(TskEvent.OsAccountsAddedTskEvent event) {
|
||||
public void publishOsAccountsAddedEvent(TskEvent.OsAccountsAddedTskEvent event) {
|
||||
hasData = true;
|
||||
for (OsAccount account : event.getOsAcounts()) {
|
||||
eventPublisher.publish(new OsAccountAddedEvent(account));
|
||||
}
|
||||
eventPublisher.publish(new OsAccountsAddedEvent(event.getOsAcounts()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void publishOsAccountChangedEvent(TskEvent.OsAccountsChangedTskEvent event) {
|
||||
for (OsAccount account : event.getOsAcounts()) {
|
||||
eventPublisher.publish(new OsAccountChangedEvent(account));
|
||||
}
|
||||
public void publishOsAccountsUpdatedEvent(TskEvent.OsAccountsUpdatedTskEvent event) {
|
||||
eventPublisher.publish(new OsAccountsUpdatedEvent(event.getOsAcounts()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -526,12 +537,14 @@ public class Case {
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to retrieve the hasData status from the db", ex);
|
||||
}
|
||||
|
||||
for (Long accountId : event.getOsAcountObjectIds()) {
|
||||
eventPublisher.publish(new OsAccountDeletedEvent(accountId));
|
||||
}
|
||||
eventPublisher.publish(new OsAccountsDeletedEvent(event.getOsAccountObjectIds()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void publishOsAccountInstancesAddedEvent(TskEvent.OsAcctInstancesAddedTskEvent event) {
|
||||
eventPublisher.publish(new OsAcctInstancesAddedEvent(event.getOsAccountInstances()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an autopsy event from the sleuthkit HostAddedEvent
|
||||
* indicating that hosts have been created.
|
||||
@@ -541,8 +554,7 @@ public class Case {
|
||||
@Subscribe
|
||||
public void publishHostsAddedEvent(TskEvent.HostsAddedTskEvent event) {
|
||||
hasData = true;
|
||||
eventPublisher.publish(new HostsAddedEvent(
|
||||
event == null ? Collections.emptyList() : event.getHosts()));
|
||||
eventPublisher.publish(new HostsAddedEvent(event.getHosts()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -552,9 +564,8 @@ public class Case {
|
||||
* @param event The sleuthkit event for the updating of hosts.
|
||||
*/
|
||||
@Subscribe
|
||||
public void publishHostsChangedEvent(TskEvent.HostsChangedTskEvent event) {
|
||||
eventPublisher.publish(new HostsChangedEvent(
|
||||
event == null ? Collections.emptyList() : event.getHosts()));
|
||||
public void publishHostsUpdatedEvent(TskEvent.HostsUpdatedTskEvent event) {
|
||||
eventPublisher.publish(new HostsUpdatedEvent(event.getHosts()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,9 +581,8 @@ public class Case {
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to retrieve the hasData status from the db", ex);
|
||||
}
|
||||
|
||||
eventPublisher.publish(new HostsRemovedEvent(
|
||||
event == null ? Collections.emptyList() : event.getHosts()));
|
||||
|
||||
eventPublisher.publish(new HostsDeletedEvent(event.getHostIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -583,8 +593,7 @@ public class Case {
|
||||
*/
|
||||
@Subscribe
|
||||
public void publishPersonsAddedEvent(TskEvent.PersonsAddedTskEvent event) {
|
||||
eventPublisher.publish(new PersonsAddedEvent(
|
||||
event == null ? Collections.emptyList() : event.getPersons()));
|
||||
eventPublisher.publish(new PersonsAddedEvent(event.getPersons()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -594,9 +603,8 @@ public class Case {
|
||||
* @param event The sleuthkit event for the updating of persons.
|
||||
*/
|
||||
@Subscribe
|
||||
public void publishPersonsChangedEvent(TskEvent.PersonsChangedTskEvent event) {
|
||||
eventPublisher.publish(new PersonsChangedEvent(
|
||||
event == null ? Collections.emptyList() : event.getPersons()));
|
||||
public void publishPersonsUpdatedEvent(TskEvent.PersonsUpdatedTskEvent event) {
|
||||
eventPublisher.publish(new PersonsUpdatedEvent(event.getPersons()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -607,9 +615,19 @@ public class Case {
|
||||
*/
|
||||
@Subscribe
|
||||
public void publishPersonsDeletedEvent(TskEvent.PersonsDeletedTskEvent event) {
|
||||
eventPublisher.publish(new PersonsDeletedEvent(
|
||||
event == null ? Collections.emptyList() : event.getPersons()));
|
||||
eventPublisher.publish(new PersonsDeletedEvent(event.getPersonIds()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void publishHostsAddedToPersonEvent(TskEvent.HostsAddedToPersonTskEvent event) {
|
||||
eventPublisher.publish(new HostsAddedToPersonEvent(event.getPerson(), event.getHosts()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void publisHostsRemovedFromPersonEvent(TskEvent.HostsRemovedFromPersonTskEvent event) {
|
||||
eventPublisher.publish(new HostsRemovedFromPersonEvent(event.getPerson(), event.getHostIds()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1232,106 +1250,107 @@ public class Case {
|
||||
/**
|
||||
* Update the GUI to to reflect the current case.
|
||||
*/
|
||||
private static void updateGUIForCaseOpened(Case newCurrentCase) {
|
||||
/*
|
||||
* If the case database was upgraded for a new schema and a
|
||||
* backup database was created, notify the user.
|
||||
*/
|
||||
SleuthkitCase caseDb = newCurrentCase.getSleuthkitCase();
|
||||
String backupDbPath = caseDb.getBackupDatabasePath();
|
||||
if (null != backupDbPath) {
|
||||
JOptionPane.showMessageDialog(
|
||||
mainFrame,
|
||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", backupDbPath),
|
||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
private static void updateGUIForCaseOpened(Case newCurrentCase) {
|
||||
/*
|
||||
* If the case database was upgraded for a new schema and a backup
|
||||
* database was created, notify the user.
|
||||
*/
|
||||
SleuthkitCase caseDb = newCurrentCase.getSleuthkitCase();
|
||||
String backupDbPath = caseDb.getBackupDatabasePath();
|
||||
if (null != backupDbPath) {
|
||||
JOptionPane.showMessageDialog(
|
||||
mainFrame,
|
||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", backupDbPath),
|
||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for the files for the data sources listed in the case
|
||||
* database and give the user the opportunity to locate any that
|
||||
* are missing.
|
||||
*/
|
||||
Map<Long, String> imgPaths = getImagePaths(caseDb);
|
||||
for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
|
||||
long obj_id = entry.getKey();
|
||||
String path = entry.getValue();
|
||||
boolean fileExists = (new File(path).isFile() || DriveUtils.driveExists(path));
|
||||
if (!fileExists) {
|
||||
try {
|
||||
// Using invokeAndWait means that the dialog will
|
||||
// open on the EDT but this thread will wait for an
|
||||
// answer. Using invokeLater would cause this loop to
|
||||
// end before all of the dialogs appeared.
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int response = JOptionPane.showConfirmDialog(
|
||||
/*
|
||||
* Look for the files for the data sources listed in the case database
|
||||
* and give the user the opportunity to locate any that are missing.
|
||||
*/
|
||||
Map<Long, String> imgPaths = getImagePaths(caseDb);
|
||||
for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
|
||||
long obj_id = entry.getKey();
|
||||
String path = entry.getValue();
|
||||
boolean fileExists = (new File(path).isFile() || DriveUtils.driveExists(path));
|
||||
if (!fileExists) {
|
||||
try {
|
||||
// Using invokeAndWait means that the dialog will
|
||||
// open on the EDT but this thread will wait for an
|
||||
// answer. Using invokeLater would cause this loop to
|
||||
// end before all of the dialogs appeared.
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int response = JOptionPane.showConfirmDialog(
|
||||
mainFrame,
|
||||
NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", path),
|
||||
NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"),
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
if (response == JOptionPane.YES_OPTION) {
|
||||
MissingImageDialog.makeDialog(obj_id, caseDb);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "User proceeding with missing image files"); //NON-NLS
|
||||
if (response == JOptionPane.YES_OPTION) {
|
||||
MissingImageDialog.makeDialog(obj_id, caseDb);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "User proceeding with missing image files"); //NON-NLS
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} catch (InterruptedException | InvocationTargetException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to show missing image confirmation dialog", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} catch (InterruptedException | InvocationTargetException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to show missing image confirmation dialog", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the case-specific actions.
|
||||
*/
|
||||
CallableSystemAction.get(AddImageAction.class).setEnabled(FeatureAccessUtils.canAddDataSources());
|
||||
CallableSystemAction.get(OpenHostsAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCurrentCase());
|
||||
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(true);
|
||||
|
||||
/*
|
||||
* Enable the case-specific actions.
|
||||
*/
|
||||
CallableSystemAction.get(AddImageAction.class).setEnabled(FeatureAccessUtils.canAddDataSources());
|
||||
CallableSystemAction.get(OpenHostsAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(FeatureAccessUtils.canDeleteCurrentCase());
|
||||
CallableSystemAction.get(OpenTimelineAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenCommVisualizationToolAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(CommonAttributeSearchAction.class).setEnabled(true);
|
||||
CallableSystemAction.get(OpenOutputFolderAction.class).setEnabled(false);
|
||||
CallableSystemAction.get(OpenDiscoveryAction.class).setEnabled(true);
|
||||
|
||||
/*
|
||||
* Add the case to the recent cases tracker that supplies a list of
|
||||
* recent cases to the recent cases menu item and the open/create case
|
||||
* dialog.
|
||||
*/
|
||||
RecentCases.getInstance().addRecentCase(newCurrentCase.getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString());
|
||||
final boolean hasData = newCurrentCase.hasData();
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
/*
|
||||
* Add the case to the recent cases tracker that supplies a list
|
||||
* of recent cases to the recent cases menu item and the
|
||||
* open/create case dialog.
|
||||
* Open the top components (windows within the main application
|
||||
* window).
|
||||
*
|
||||
* Note: If the core windows are not opened here, they will be
|
||||
* opened via the DirectoryTreeTopComponent 'propertyChange()'
|
||||
* method on a DATA_SOURCE_ADDED event.
|
||||
*/
|
||||
RecentCases.getInstance().addRecentCase(newCurrentCase.getDisplayName(), newCurrentCase.getMetadata().getFilePath().toString());
|
||||
final boolean hasData = newCurrentCase.hasData();
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
/*
|
||||
* Open the top components (windows within the main application
|
||||
* window).
|
||||
*
|
||||
* Note: If the core windows are not opened here, they will be
|
||||
* opened via the DirectoryTreeTopComponent 'propertyChange()'
|
||||
* method on a DATA_SOURCE_ADDED event.
|
||||
*/
|
||||
if (hasData) {
|
||||
CoreComponentControl.openCoreWindows();
|
||||
} else {
|
||||
//ensure that the DirectoryTreeTopComponent is open so that it's listener can open the core windows including making it visible.
|
||||
DirectoryTreeTopComponent.findInstance();
|
||||
}
|
||||
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
if (hasData) {
|
||||
CoreComponentControl.openCoreWindows();
|
||||
} else {
|
||||
//ensure that the DirectoryTreeTopComponent is open so that it's listener can open the core windows including making it visible.
|
||||
DirectoryTreeTopComponent.findInstance();
|
||||
}
|
||||
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
|
||||
/*
|
||||
* Reset the main window title to:
|
||||
*
|
||||
* [curent case display name] - [application name].
|
||||
*/
|
||||
mainFrame.setTitle(newCurrentCase.getDisplayName() + " - " + getNameForTitle());
|
||||
});
|
||||
/*
|
||||
* Reset the main window title to:
|
||||
*
|
||||
* [curent case display name] - [application name].
|
||||
*/
|
||||
mainFrame.setTitle(newCurrentCase.getDisplayName() + " - " + getNameForTitle());
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1684,16 +1703,16 @@ public class Case {
|
||||
|
||||
/**
|
||||
* Returns true if there is any data in the case.
|
||||
*
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
public boolean hasData() {
|
||||
return hasData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if there is one or more data sources in the case.
|
||||
*
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
public boolean hasDataSource() {
|
||||
@@ -1858,72 +1877,6 @@ public class Case {
|
||||
eventPublisher.publish(new BlackBoardArtifactTagDeletedEvent(deletedTag));
|
||||
}
|
||||
|
||||
public void notifyOsAccountAdded(OsAccount account) {
|
||||
eventPublisher.publish(new OsAccountAddedEvent(account));
|
||||
}
|
||||
|
||||
public void notifyOsAccountChanged(OsAccount account) {
|
||||
eventPublisher.publish(new OsAccountChangedEvent(account));
|
||||
}
|
||||
|
||||
public void notifyOsAccountRemoved(Long osAccountObjectId) {
|
||||
eventPublisher.publish(new OsAccountDeletedEvent(osAccountObjectId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify via an autopsy event that a host has been added.
|
||||
*
|
||||
* @param host The host that has been added.
|
||||
*/
|
||||
public void notifyHostAdded(Host host) {
|
||||
eventPublisher.publish(new HostsAddedEvent(Collections.singletonList(host)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify via an autopsy event that a host has been changed.
|
||||
*
|
||||
* @param newValue The host that has been updated.
|
||||
*/
|
||||
public void notifyHostChanged(Host newValue) {
|
||||
eventPublisher.publish(new HostsChangedEvent(Collections.singletonList(newValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify via an autopsy event that a host has been deleted.
|
||||
*
|
||||
* @param host The host that has been deleted.
|
||||
*/
|
||||
public void notifyHostDeleted(Host host) {
|
||||
eventPublisher.publish(new HostsRemovedEvent(Collections.singletonList(host)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify via an autopsy event that a person has been added.
|
||||
*
|
||||
* @param person The person that has been added.
|
||||
*/
|
||||
public void notifyPersonAdded(Person person) {
|
||||
eventPublisher.publish(new PersonsAddedEvent(Collections.singletonList(person)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify via an autopsy event that a person has been changed.
|
||||
*
|
||||
* @param newValue The person that has been updated.
|
||||
*/
|
||||
public void notifyPersonChanged(Person newValue) {
|
||||
eventPublisher.publish(new PersonsChangedEvent(Collections.singletonList(newValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify via an autopsy event that a person has been deleted.
|
||||
*
|
||||
* @param person The person that has been deleted.
|
||||
*/
|
||||
public void notifyPersonDeleted(Person person) {
|
||||
eventPublisher.publish(new PersonsDeletedEvent(Collections.singletonList(person)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a report to the case.
|
||||
*
|
||||
@@ -1966,7 +1919,7 @@ public class Case {
|
||||
throw new TskCoreException(errorMsg, ex);
|
||||
}
|
||||
hasData = true;
|
||||
|
||||
|
||||
Report report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
|
||||
eventPublisher.publish(new ReportAddedEvent(report));
|
||||
return report;
|
||||
@@ -1996,16 +1949,16 @@ public class Case {
|
||||
for (Report report : reports) {
|
||||
this.caseDb.deleteReport(report);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
hasData = dbHasData();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to retrieve the hasData status from the db", ex);
|
||||
}
|
||||
|
||||
|
||||
for (Report report : reports) {
|
||||
eventPublisher.publish(new AutopsyEvent(Events.REPORT_DELETED.toString(), report, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3538,17 +3491,17 @@ public class Case {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the hasData and hasDataSource parameters by checking the
|
||||
* Initialize the hasData and hasDataSource parameters by checking the
|
||||
* database.
|
||||
*
|
||||
*
|
||||
* hasDataSource will be true if any data Source exists the db.
|
||||
*
|
||||
* hasData will be true if hasDataSource is true or if there are entries
|
||||
* in the tsk_object or tsk_host tables.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*
|
||||
* hasData will be true if hasDataSource is true or if there are entries in
|
||||
* the tsk_object or tsk_host tables.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private void updateDataParameters() throws TskCoreException {
|
||||
hasDataSource = dbHasDataSource();
|
||||
@@ -3559,13 +3512,13 @@ public class Case {
|
||||
hasData = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true of there are any data sources in the case database.
|
||||
*
|
||||
*
|
||||
* @return True if this case as a data source.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private boolean dbHasDataSource() throws TskCoreException {
|
||||
String query = "SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
|
||||
@@ -3580,35 +3533,35 @@ public class Case {
|
||||
throw new TskCoreException("Error accessing case databse", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the case has data. A case has data if there is at least
|
||||
* one row in either the tsk_objects or tsk_hosts table.
|
||||
*
|
||||
*
|
||||
* @return True if there is data in this case.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private boolean dbHasData() throws TskCoreException {
|
||||
// The LIMIT 1 in the subquery should limit the data returned and
|
||||
// make the overall query more efficent.
|
||||
String query = "SELECT SUM(cnt) total FROM "
|
||||
+ "(SELECT COUNT(*) AS cnt FROM "
|
||||
+ "(SELECT * FROM tsk_objects LIMIT 1)t "
|
||||
+ "(SELECT * FROM tsk_objects LIMIT 1)t "
|
||||
+ "UNION ALL "
|
||||
+ "SELECT COUNT(*) AS cnt FROM "
|
||||
+ "(SELECT * FROM tsk_hosts LIMIT 1)r) s";
|
||||
try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
|
||||
ResultSet resultSet = dbQuery.getResultSet();
|
||||
if (resultSet.next()) {
|
||||
return resultSet.getLong("total") > 0;
|
||||
return resultSet.getLong("total") > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch ( SQLException ex) {
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Error accessing case database", ex); //NON-NLS
|
||||
throw new TskCoreException("Error accessing case databse", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 32767]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
@@ -16,6 +11,7 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
@@ -35,9 +31,6 @@
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="contentPanel">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 32767]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[625, 150]"/>
|
||||
</Property>
|
||||
@@ -60,9 +53,6 @@
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[16, 16]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="null"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
@@ -85,6 +75,12 @@
|
||||
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
|
||||
<TableColumnModel selectionModel="1"/>
|
||||
</Property>
|
||||
<Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" id="InternalFrame.borderColor" palette="3" red="f0" type="palette"/>
|
||||
</Property>
|
||||
<Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[4, 2]"/>
|
||||
</Property>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="false" resizingAllowed="true"/>
|
||||
</Property>
|
||||
@@ -157,6 +153,12 @@
|
||||
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
|
||||
<TableColumnModel selectionModel="0"/>
|
||||
</Property>
|
||||
<Property name="gridColor" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" id="InternalFrame.borderColor" palette="3" red="f0" type="palette"/>
|
||||
</Property>
|
||||
<Property name="intercellSpacing" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[4, 2]"/>
|
||||
</Property>
|
||||
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
|
||||
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
|
||||
</Property>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2016-2019 Basis Technology Corp.
|
||||
* Copyright 2016-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -26,8 +26,11 @@ import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
@@ -50,13 +53,14 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
private static final Logger logger = Logger.getLogger(IngestJobInfoPanel.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
|
||||
private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE);
|
||||
|
||||
private List<IngestJobInfo> ingestJobs;
|
||||
private static final int EXTRA_ROW_HEIGHT = 4;
|
||||
private final List<IngestJobInfo> ingestJobs = new ArrayList<>();
|
||||
private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>();
|
||||
private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
|
||||
private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null);
|
||||
private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
private DataSource selectedDataSource;
|
||||
private static SwingWorker<Boolean, Void> refreshWorker = null;
|
||||
|
||||
/**
|
||||
* Creates new form IngestJobInfoPanel
|
||||
@@ -76,19 +80,19 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
this.ingestModuleTable.setModel(this.ingestModuleTableModel);
|
||||
});
|
||||
|
||||
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST , (PropertyChangeEvent evt) -> {
|
||||
IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
|
||||
if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString())
|
||||
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|
||||
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
|
||||
if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Check whether we have a case open or case close event.
|
||||
if ((CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName()))) {
|
||||
if (evt.getNewValue() != null) {
|
||||
@@ -100,6 +104,9 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
ingestJobTable.setRowHeight(ingestJobTable.getRowHeight() + EXTRA_ROW_HEIGHT);
|
||||
ingestModuleTable.setRowHeight(ingestModuleTable.getRowHeight() + EXTRA_ROW_HEIGHT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,27 +137,53 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
* Get the updated complete list of ingest jobs.
|
||||
*/
|
||||
private void refresh() {
|
||||
try {
|
||||
if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
this.ingestJobs = skCase.getIngestJobs();
|
||||
setDataSource(selectedDataSource);
|
||||
} else {
|
||||
this.ingestJobs = new ArrayList<>();
|
||||
setDataSource(null);
|
||||
}
|
||||
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
|
||||
JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
|
||||
if (refreshWorker != null && !refreshWorker.isDone()) {
|
||||
refreshWorker.cancel(true);
|
||||
}
|
||||
refreshWorker = new SwingWorker<Boolean, Void>() {
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground() throws Exception {
|
||||
ingestJobs.clear();
|
||||
try {
|
||||
if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
ingestJobs.addAll(skCase.getIngestJobs());
|
||||
setDataSource(selectedDataSource);
|
||||
} else {
|
||||
setDataSource(null);
|
||||
}
|
||||
return true;
|
||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
if (!get()) {
|
||||
JOptionPane.showMessageDialog(IngestJobInfoPanel.this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex);
|
||||
} catch (CancellationException ignored){
|
||||
logger.log(Level.INFO, "The refreshing of the IngestJobInfoPanel was cancelled");
|
||||
}
|
||||
}
|
||||
};
|
||||
refreshWorker.execute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the panel.
|
||||
*/
|
||||
private void reset() {
|
||||
this.ingestJobs = new ArrayList<>();
|
||||
if (refreshWorker != null) {
|
||||
refreshWorker.cancel(true);
|
||||
}
|
||||
this.ingestJobs.clear();
|
||||
setDataSource(null);
|
||||
}
|
||||
|
||||
@@ -267,19 +300,18 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
javax.swing.JScrollPane ingestModulesScrollPane = new javax.swing.JScrollPane();
|
||||
ingestModuleTable = new javax.swing.JTable();
|
||||
|
||||
setMaximumSize(new java.awt.Dimension(32767, 32767));
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
contentPanel.setMaximumSize(new java.awt.Dimension(32767, 32767));
|
||||
contentPanel.setMinimumSize(new java.awt.Dimension(625, 150));
|
||||
contentPanel.setPreferredSize(new java.awt.Dimension(625, 150));
|
||||
contentPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
ingestJobsScrollPane.setBorder(null);
|
||||
ingestJobsScrollPane.setMinimumSize(new java.awt.Dimension(16, 16));
|
||||
ingestJobsScrollPane.setPreferredSize(null);
|
||||
|
||||
ingestJobTable.setModel(ingestJobTableModel);
|
||||
ingestJobTable.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
|
||||
ingestJobTable.setIntercellSpacing(new java.awt.Dimension(4, 2));
|
||||
ingestJobTable.getTableHeader().setReorderingAllowed(false);
|
||||
ingestJobsScrollPane.setViewportView(ingestJobTable);
|
||||
ingestJobTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
@@ -315,6 +347,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
|
||||
ingestModulesScrollPane.setPreferredSize(new java.awt.Dimension(254, 16));
|
||||
|
||||
ingestModuleTable.setModel(ingestModuleTableModel);
|
||||
ingestModuleTable.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
|
||||
ingestModuleTable.setIntercellSpacing(new java.awt.Dimension(4, 2));
|
||||
ingestModulesScrollPane.setViewportView(ingestModuleTable);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
|
||||
@@ -70,9 +70,7 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
||||
final WizardDescriptor wizardDescriptor = new WizardDescriptor(getNewCaseWizardPanels());
|
||||
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
||||
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
|
||||
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
|
||||
// Workaround to ensure new case dialog is not hidden on macOS
|
||||
dialog.setAlwaysOnTop(true);
|
||||
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor, WindowManager.getDefault().getMainWindow());
|
||||
dialog.setVisible(true);
|
||||
dialog.toFront();
|
||||
if (wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION) {
|
||||
|
||||
@@ -23,17 +23,21 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
|
||||
/**
|
||||
* Event fired when new hosts are added.
|
||||
* Application events published when hosts have been added to the Sleuth Kit
|
||||
* data model for a case.
|
||||
*/
|
||||
public class HostsAddedEvent extends HostsEvent {
|
||||
|
||||
public final class HostsAddedEvent extends HostsEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* @param dataModelObjects The hosts that have been added.
|
||||
* Constructs an application event published when hosts have been added to
|
||||
* the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param hosts The hosts that have been added.
|
||||
*/
|
||||
public HostsAddedEvent(List<Host> dataModelObjects) {
|
||||
super(Case.Events.HOSTS_ADDED.name(), dataModelObjects);
|
||||
public HostsAddedEvent(List<Host> hosts) {
|
||||
super(Case.Events.HOSTS_ADDED.name(), hosts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
import org.sleuthkit.datamodel.Person;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Application events published when one or more hosts have been added to a
|
||||
* person.
|
||||
*/
|
||||
public final class HostsAddedToPersonEvent extends TskDataModelChangedEvent<Person, Host> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an application event published when one or more hosts have
|
||||
* been added to a person.
|
||||
*
|
||||
* @param person The person.
|
||||
* @param hosts The hosts.
|
||||
*/
|
||||
public HostsAddedToPersonEvent(Person person, List<Host> hosts) {
|
||||
super(Case.Events.HOSTS_ADDED_TO_PERSON.toString(), Collections.singletonList(person), Person::getPersonId, hosts, Host::getHostId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the person.
|
||||
*
|
||||
* @return The person.
|
||||
*/
|
||||
public Person getPerson() {
|
||||
return getOldValue().get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hosts.
|
||||
*
|
||||
* @return The hosts.
|
||||
*/
|
||||
public List<Host> getHosts() {
|
||||
return getNewValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Person> getOldValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
List<Person> persons = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
Optional<Person> person = caseDb.getPersonManager().getPerson(id);
|
||||
if (person.isPresent()) {
|
||||
persons.add(person.get());
|
||||
}
|
||||
}
|
||||
return persons;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Host> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
List<Host> hosts = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
Optional<Host> host = caseDb.getHostManager().getHostById(id);
|
||||
if (host.isPresent()) {
|
||||
hosts.add(host.get());
|
||||
}
|
||||
}
|
||||
return hosts;
|
||||
}
|
||||
|
||||
}
|
||||
Regular → Executable
+21
-9
@@ -20,20 +20,32 @@ package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
|
||||
/**
|
||||
* Event fired when hosts are removed.
|
||||
* Application events published when hosts have been deleted from the Sleuth
|
||||
* Kit data model for a case.
|
||||
*/
|
||||
public class HostsRemovedEvent extends HostsEvent {
|
||||
|
||||
public final class HostsDeletedEvent extends TskDataModelObjectsDeletedEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* @param dataModelObjects The list of hosts that have been deleted.
|
||||
* Constructs an application event published when hosts have been deleted
|
||||
* from the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param hostIds The host IDs of the deleted hosts.
|
||||
*/
|
||||
public HostsRemovedEvent(List<Host> dataModelObjects) {
|
||||
super(Case.Events.HOSTS_DELETED.name(), dataModelObjects);
|
||||
public HostsDeletedEvent(List<Long> hostIds) {
|
||||
super(Case.Events.HOSTS_DELETED.name(), hostIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the host IDs of the hosts that have been deleted.
|
||||
*
|
||||
* @return The host IDs.
|
||||
*/
|
||||
public List<Long> getHostIds() {
|
||||
return getOldValue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,71 +19,51 @@
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
import org.sleuthkit.datamodel.HostManager;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Base event class for when something pertaining to hosts changes.
|
||||
* A base class for application events published when hosts in the Sleuth Kit
|
||||
* data model for a case have been added or updated.
|
||||
*/
|
||||
public class HostsEvent extends TskDataModelChangeEvent<Host> {
|
||||
public class HostsEvent extends TskDataModelChangedEvent<Host, Host> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Retrieves a list of ids from a list of hosts.
|
||||
*
|
||||
* @param hosts The hosts.
|
||||
* @return The list of ids.
|
||||
*/
|
||||
private static List<Long> getIds(List<Host> hosts) {
|
||||
return getSafeList(hosts).stream()
|
||||
.filter(h -> h != null)
|
||||
.map(h -> h.getHostId()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hosts or an empty list.
|
||||
*
|
||||
* @param hosts The host list.
|
||||
* @return The host list or an empty list if the parameter is null.
|
||||
*/
|
||||
private static List<Host> getSafeList(List<Host> hosts) {
|
||||
return hosts == null ? Collections.emptyList() : hosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* Constructs the base class part of an application event published when
|
||||
* hosts in the Sleuth Kit data model for a case have been added or updated.
|
||||
*
|
||||
* @param eventName The name of the Case.Events enum value for the event
|
||||
* type.
|
||||
* @param dataModelObjects The list of hosts for the event.
|
||||
* type.
|
||||
* @param hosts The hosts.
|
||||
*/
|
||||
protected HostsEvent(String eventName, List<Host> dataModelObjects) {
|
||||
super(eventName, getIds(dataModelObjects), new ArrayList<>(getSafeList(dataModelObjects)));
|
||||
HostsEvent(String eventName, List<Host> hosts) {
|
||||
super(eventName, null, null, hosts, Host::getHostId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hosts that have been added or updated.
|
||||
*
|
||||
* @return The hosts.
|
||||
*/
|
||||
public List<Host> getHosts() {
|
||||
return getNewValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Host> getDataModelObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
HostManager hostManager = caseDb.getHostManager();
|
||||
List<Host> toRet = new ArrayList<>();
|
||||
if (ids != null) {
|
||||
for (Long id : ids) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<Host> thisHostOpt = hostManager.getHostById(id);
|
||||
thisHostOpt.ifPresent((h) -> toRet.add(h));
|
||||
protected List<Host> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
List<Host> hosts = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
Optional<Host> host = caseDb.getHostManager().getHostById(id);
|
||||
if (host.isPresent()) {
|
||||
hosts.add(host.get());
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
return hosts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
import org.sleuthkit.datamodel.Person;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Application events published when one or more hosts have been removed from a
|
||||
* person.
|
||||
*/
|
||||
public class HostsRemovedFromPersonEvent extends TskDataModelChangedEvent<Person, Long> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an application event published when one or more hosts have
|
||||
* been removed from a person.
|
||||
*
|
||||
* @param person The person.
|
||||
* @param hostIds The host IDs of the removed hosts.
|
||||
*/
|
||||
public HostsRemovedFromPersonEvent(Person person, List<Long> hostIds) {
|
||||
super(Case.Events.HOSTS_REMOVED_FROM_PERSON.toString(), Collections.singletonList(person), Person::getPersonId, hostIds, (id -> id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the person.
|
||||
*
|
||||
* @return The person.
|
||||
*/
|
||||
public Person getPerson() {
|
||||
return getOldValue().get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the host IDs of the removed hosts.
|
||||
*
|
||||
* @return The host IDs.
|
||||
*/
|
||||
public List<Long> getHostIds() {
|
||||
return getNewValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Person> getOldValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
List<Person> persons = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
Optional<Person> person = caseDb.getPersonManager().getPerson(id);
|
||||
if (person.isPresent()) {
|
||||
persons.add(person.get());
|
||||
}
|
||||
}
|
||||
return persons;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Long> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
return ids;
|
||||
}
|
||||
|
||||
}
|
||||
Regular → Executable
+9
-7
@@ -23,19 +23,21 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
|
||||
/**
|
||||
* Event fired when hosts are changed.
|
||||
* Application events published when hosts in the Sleuth Kit data model for
|
||||
* a case have been updated.
|
||||
*/
|
||||
public class HostsChangedEvent extends HostsEvent {
|
||||
public class HostsUpdatedEvent extends HostsEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* Constructs an application event published when hosts in the Sleuth Kit
|
||||
* data model for a case have been updated.
|
||||
*
|
||||
* @param dataModelObjects The new values for the hosts that have been
|
||||
* changed.
|
||||
* @param hosts The updated persons.
|
||||
*/
|
||||
public HostsChangedEvent(List<Host> dataModelObjects) {
|
||||
super(Case.Events.HOSTS_CHANGED.name(), dataModelObjects);
|
||||
public HostsUpdatedEvent(List<Host> hosts) {
|
||||
super(Case.Events.HOSTS_UPDATED.name(), hosts);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
|
||||
/**
|
||||
* Event published when an OsAccount is deleted.
|
||||
*
|
||||
* oldValue will contain the objectId of the account that was removed. newValue
|
||||
* will be null.
|
||||
*/
|
||||
public final class OsAccountDeletedEvent extends AutopsyEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OsAccountDeletedEvent(Long osAccountObjectId) {
|
||||
super(Case.Events.OS_ACCOUNT_REMOVED.toString(), osAccountObjectId, null);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Parent class for specific OsAccount event classes.
|
||||
*/
|
||||
class OsAccountEvent extends TskDataModelChangeEvent<OsAccount> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Construct a new OsAccountEvent.
|
||||
*
|
||||
* @param eventName The name of the event.
|
||||
* @param account The OsAccount the event applies to.
|
||||
*/
|
||||
OsAccountEvent(String eventName, OsAccount account) {
|
||||
super(eventName, Stream.of(account.getId()).collect(Collectors.toList()), Stream.of(account).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OsAccount that changed.
|
||||
*
|
||||
* @return The OsAccount that was changed.
|
||||
*/
|
||||
public OsAccount getOsAccount() {
|
||||
List<OsAccount> accounts = getNewValue();
|
||||
return accounts.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<OsAccount> getDataModelObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
Long id = ids.get(0);
|
||||
OsAccount account = caseDb.getOsAccountManager().getOsAccountByObjectId(id);
|
||||
List<OsAccount> accounts = new ArrayList<>();
|
||||
accounts.add(account);
|
||||
return accounts;
|
||||
}
|
||||
}
|
||||
+16
-7
@@ -18,17 +18,26 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import java.util.List;
|
||||
import static org.sleuthkit.autopsy.casemodule.Case.Events.OS_ACCOUNTS_ADDED;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
|
||||
/**
|
||||
* Event published when an OsAccount is updated.
|
||||
* An application event published when OS accounts are added to the Sleuth Kit
|
||||
* data model for a case.
|
||||
*/
|
||||
public final class OsAccountChangedEvent extends OsAccountEvent {
|
||||
public final class OsAccountsAddedEvent extends OsAccountsEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OsAccountChangedEvent(OsAccount account) {
|
||||
super(Case.Events.OS_ACCOUNT_CHANGED.toString(), account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an application event published when OS accounts are added to
|
||||
* the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param osAccounts The OS accounts that were added.
|
||||
*/
|
||||
public OsAccountsAddedEvent(List<OsAccount> osAccounts) {
|
||||
super(OS_ACCOUNTS_ADDED.toString(), osAccounts);
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
|
||||
/**
|
||||
* An application event published when OS accounts have been deleted from the
|
||||
* Sleuth Kit data model for a case.
|
||||
*/
|
||||
public final class OsAccountsDeletedEvent extends TskDataModelObjectsDeletedEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an application event published when OS accounts have been
|
||||
* deleted from the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param osAccountObjectIds TSK object IDs of the deleted accounts.
|
||||
*/
|
||||
public OsAccountsDeletedEvent(List<Long> osAccountObjectIds) {
|
||||
super(Case.Events.OS_ACCOUNTS_DELETED.toString(), osAccountObjectIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Sleuth Kit object IDs of the deleted OS accounts.
|
||||
*
|
||||
* @return The object IDs.
|
||||
*/
|
||||
List<Long> getOsAccountObjectIds() {
|
||||
return getOldValue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* A base class for application events published when OS accounts in the Sleuth
|
||||
* Kit data model for a case have been added or updated.
|
||||
*/
|
||||
class OsAccountsEvent extends TskDataModelChangedEvent<OsAccount, OsAccount> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs the base class part of an application event published when
|
||||
* OS accounts in the Sleuth Kit data model for a case have been added or
|
||||
* updated.
|
||||
*
|
||||
* @param eventName The name of the Case.Events enum value for the event
|
||||
* type.
|
||||
* @param account The OS accounts.
|
||||
*/
|
||||
OsAccountsEvent(String eventName, List<OsAccount> osAccounts) {
|
||||
super(eventName, null, null, osAccounts, OsAccount::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the OS accounts that have been added or updated.
|
||||
*
|
||||
* @return The OS accounts.
|
||||
*/
|
||||
public List<OsAccount> getOsAccounts() {
|
||||
return getNewValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<OsAccount> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
List<OsAccount> osAccounts = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
osAccounts.add(caseDb.getOsAccountManager().getOsAccountByObjectId(id));
|
||||
}
|
||||
return osAccounts;
|
||||
}
|
||||
|
||||
}
|
||||
+14
-6
@@ -18,18 +18,26 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
|
||||
/**
|
||||
* Event published when an OsAccount is added to a case.
|
||||
* An application event published when OS accounts in the Sleuth Kit data model
|
||||
* for a case have been updated.
|
||||
*/
|
||||
public final class OsAccountAddedEvent extends OsAccountEvent {
|
||||
public final class OsAccountsUpdatedEvent extends OsAccountsEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OsAccountAddedEvent(OsAccount account) {
|
||||
super(Case.Events.OS_ACCOUNT_ADDED.toString(), account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an application event published when OS accounts in the Sleuth
|
||||
* Kit data model for a case have been updated.
|
||||
*
|
||||
* @param osAccounts The OS accounts that were updated.
|
||||
*/
|
||||
public OsAccountsUpdatedEvent(List<OsAccount> osAccounts) {
|
||||
super(Case.Events.OS_ACCOUNTS_UPDATED.toString(), osAccounts);
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.List;
|
||||
import static org.sleuthkit.autopsy.casemodule.Case.Events.OS_ACCT_INSTANCES_ADDED;
|
||||
import org.sleuthkit.datamodel.OsAccountInstance;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* An application event published when OS account instances are added to the
|
||||
* Sleuth Kit data model for a case.
|
||||
*/
|
||||
public final class OsAcctInstancesAddedEvent extends TskDataModelChangedEvent<OsAccountInstance, OsAccountInstance> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an application event published when OS account instances are
|
||||
* added to the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param osAcctInstances The OS account instances that were added.
|
||||
*/
|
||||
public OsAcctInstancesAddedEvent(List<OsAccountInstance> osAcctInstances) {
|
||||
super(OS_ACCT_INSTANCES_ADDED.toString(), null, null, osAcctInstances, OsAccountInstance::getInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the OS account instances that have been added.
|
||||
*
|
||||
* @return The OS account instances.
|
||||
*/
|
||||
public List<OsAccountInstance> getOsAccountInstances() {
|
||||
return getNewValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<OsAccountInstance> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
return caseDb.getOsAccountManager().getOsAccountInstances(ids);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,17 +23,21 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Person;
|
||||
|
||||
/**
|
||||
* Event fired when new persons are added.
|
||||
* An application event published when persons have been added to the Sleuth Kit
|
||||
* data model for a case.
|
||||
*/
|
||||
public class PersonsAddedEvent extends PersonsEvent {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* @param dataModelObjects The persons that have been added.
|
||||
* Constructs an application event published when persons have been added to
|
||||
* the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param persons The persons that have been added.
|
||||
*/
|
||||
public PersonsAddedEvent(List<Person> dataModelObjects) {
|
||||
super(Case.Events.PERSONS_ADDED.name(), dataModelObjects);
|
||||
public PersonsAddedEvent(List<Person> persons) {
|
||||
super(Case.Events.PERSONS_ADDED.name(), persons);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,20 +20,32 @@ package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Person;
|
||||
|
||||
/**
|
||||
* Event fired when persons are removed.
|
||||
* Application events published when persons have been deleted from the Sleuth
|
||||
* Kit data model for a case.
|
||||
*/
|
||||
public class PersonsDeletedEvent extends PersonsEvent {
|
||||
|
||||
public class PersonsDeletedEvent extends TskDataModelObjectsDeletedEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* @param dataModelObjects The list of persons that have been deleted.
|
||||
* Constructs an application event published when persons have been deleted
|
||||
* from the Sleuth Kit data model for a case.
|
||||
*
|
||||
* @param personIds The IDs of the persons that have been deleted.
|
||||
*/
|
||||
public PersonsDeletedEvent(List<Person> dataModelObjects) {
|
||||
super(Case.Events.PERSONS_DELETED.name(), dataModelObjects);
|
||||
public PersonsDeletedEvent(List<Long> personIds) {
|
||||
super(Case.Events.PERSONS_DELETED.name(), personIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the person IDs of the persons that have been deleted.
|
||||
*
|
||||
* @return The person IDs.
|
||||
*/
|
||||
List<Long> getPersonIds() {
|
||||
return getOldValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,69 +19,52 @@
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import org.sleuthkit.datamodel.Person;
|
||||
import org.sleuthkit.datamodel.PersonManager;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Base event class for when something pertaining to persons changes.
|
||||
* A base class for application events published when persons in the Sleuth Kit
|
||||
* data model for a case have been added or updated.
|
||||
*/
|
||||
public class PersonsEvent extends TskDataModelChangeEvent<Person> {
|
||||
public class PersonsEvent extends TskDataModelChangedEvent<Person, Person> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Retrieves a list of ids from a list of persons.
|
||||
*
|
||||
* @param persons The persons.
|
||||
* @return The list of ids.
|
||||
*/
|
||||
private static List<Long> getIds(List<Person> persons) {
|
||||
return getSafeList(persons).stream()
|
||||
.filter(h -> h != null)
|
||||
.map(h -> h.getPersonId()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the persons or an empty list.
|
||||
*
|
||||
* @param persons The person list.
|
||||
* @return The person list or an empty list if the parameter is null.
|
||||
*/
|
||||
private static List<Person> getSafeList(List<Person> persons) {
|
||||
return persons == null ? Collections.emptyList() : persons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* Constructs the base class part of an application event published when
|
||||
* persons in the Sleuth Kit data model for a case have been added or
|
||||
* updated.
|
||||
*
|
||||
* @param eventName The name of the Case.Events enum value for the event
|
||||
* type.
|
||||
* @param dataModelObjects The list of persons for the event.
|
||||
* type.
|
||||
* @param persons The persons.
|
||||
*/
|
||||
protected PersonsEvent(String eventName, List<Person> dataModelObjects) {
|
||||
super(eventName, getIds(dataModelObjects), new ArrayList<>(getSafeList(dataModelObjects)));
|
||||
PersonsEvent(String eventName, List<Person> persons) {
|
||||
super(eventName, null, null, persons, Person::getPersonId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the persons that have been added or updated.
|
||||
*
|
||||
* @return The persons.
|
||||
*/
|
||||
public List<Person> getPersons() {
|
||||
return getNewValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Person> getDataModelObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
PersonManager personManager = caseDb.getPersonManager();
|
||||
List<Person> toRet = new ArrayList<>();
|
||||
if (ids != null) {
|
||||
for (Long id : ids) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<Person> thisPersonOpt = personManager.getPerson(id);
|
||||
thisPersonOpt.ifPresent((h) -> toRet.add(h));
|
||||
protected List<Person> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
List<Person> persons = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
Optional<Person> person = caseDb.getPersonManager().getPerson(id);
|
||||
if (person.isPresent()) {
|
||||
persons.add(person.get());
|
||||
}
|
||||
}
|
||||
|
||||
return toRet;
|
||||
return persons;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Regular → Executable
+9
-7
@@ -23,19 +23,21 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.datamodel.Person;
|
||||
|
||||
/**
|
||||
* Event fired when persons are changed.
|
||||
* Application events published when persons in the Sleuth Kit data model for
|
||||
* a case have been updated.
|
||||
*/
|
||||
public class PersonsChangedEvent extends PersonsEvent {
|
||||
public class PersonsUpdatedEvent extends PersonsEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
* Constructs an application event published when persons in the Sleuth Kit
|
||||
* data model for a case have been updated.
|
||||
*
|
||||
* @param dataModelObjects The new values for the persons that have been
|
||||
* changed.
|
||||
* @param persons The updated persons.
|
||||
*/
|
||||
public PersonsChangedEvent(List<Person> dataModelObjects) {
|
||||
super(Case.Events.PERSONS_CHANGED.name(), dataModelObjects);
|
||||
public PersonsUpdatedEvent(List<Person> persons) {
|
||||
super(Case.Events.PERSONS_UPDATED.name(), persons);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,33 +28,38 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Event published when a report is added to a case.
|
||||
* An application event published when a report is added to a case.
|
||||
*/
|
||||
public final class ReportAddedEvent extends TskDataModelChangeEvent<Report> {
|
||||
public final class ReportAddedEvent extends TskDataModelChangedEvent<Report, Report> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an event published when a report is added to a case.
|
||||
* Constructs an application event published when a report is added to a
|
||||
* case.
|
||||
*
|
||||
* @param report The data source that was added.
|
||||
* @param report The report that was added.
|
||||
*/
|
||||
public ReportAddedEvent(Report report) {
|
||||
super(Case.Events.REPORT_ADDED.toString(), Stream.of(report.getId()).collect(Collectors.toList()), Stream.of(report).collect(Collectors.toList()));
|
||||
super(Case.Events.REPORT_ADDED.toString(), null, null, Stream.of(report).collect(Collectors.toList()), Report::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reoprt that was added to the case.
|
||||
*
|
||||
* @return The report.
|
||||
*/
|
||||
public Report getReport() {
|
||||
List<Report> reports = getNewValue();
|
||||
return reports.get(0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<Report> getDataModelObjects(SleuthkitCase caseD, List<Long> ids) throws TskCoreException {
|
||||
protected List<Report> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
Long id = ids.get(0);
|
||||
Report report = caseD.getReportById(id);
|
||||
List<Report> reports = new ArrayList<>();
|
||||
reports.add(report);
|
||||
reports.add(caseDb.getReportById(id));
|
||||
return reports;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* An application event generic used as a superclass for events published when
|
||||
* something changes in the Sleuth Kit Data Model for a case.
|
||||
*
|
||||
* @param <T> A Sleuth Kit Data Model object type.
|
||||
*/
|
||||
public abstract class TskDataModelChangeEvent<T> extends AutopsyEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(TskDataModelChangeEvent.class.getName());
|
||||
private final List<Long> dataModelObjectIds;
|
||||
private transient List<T> dataModelObjects;
|
||||
|
||||
/**
|
||||
* Constructs an application event generic used as a superclass for events
|
||||
* published when something changes in the Sleuth Kit Data Model for a case.
|
||||
*
|
||||
* @param eventName The event name.
|
||||
* @param dataModelObjectIds The unique numeric IDs (TSK object IDs, case
|
||||
* database row IDs, etc.) of the Sleuth Kit Data
|
||||
* Model objects associated with this application
|
||||
* event.
|
||||
* @param dataModelObjects The Sleuth Kit Data Model objects associated
|
||||
* with this application event
|
||||
*/
|
||||
protected TskDataModelChangeEvent(String eventName, List<Long> dataModelObjectIds, List<T> dataModelObjects) {
|
||||
super(eventName, null, null);
|
||||
this.dataModelObjectIds = dataModelObjectIds;
|
||||
this.dataModelObjects = dataModelObjects;
|
||||
if (eventName == null) {
|
||||
throw new IllegalArgumentException("eventName is null");
|
||||
}
|
||||
if (dataModelObjectIds == null) {
|
||||
throw new IllegalArgumentException("dataModelObjectIds is null");
|
||||
}
|
||||
if (dataModelObjects == null) {
|
||||
throw new IllegalArgumentException("dataModelObjects is null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique numeric IDs (TSK object IDs, case database row IDs, etc.)
|
||||
* of the Sleuth Kit Data Model objects associated with this application
|
||||
* event.
|
||||
*
|
||||
* @return The unique IDs.
|
||||
*/
|
||||
public final List<Long> getDataModelObjectIds() {
|
||||
return Collections.unmodifiableList(dataModelObjectIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Sleuth Kit Data Model objects associated with this application
|
||||
* event.
|
||||
*
|
||||
* @return The objects.
|
||||
*/
|
||||
@Override
|
||||
public List<T> getNewValue() {
|
||||
/*
|
||||
* If this event came from another host collaborating on a multi-user
|
||||
* case, the transient list of Sleuth Kit Data Model objects will be
|
||||
* null and will need to be reconstructed on the current host.
|
||||
*/
|
||||
if (dataModelObjects == null) {
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCaseThrows();
|
||||
SleuthkitCase caseDb = currentCase.getSleuthkitCase();
|
||||
dataModelObjects = getDataModelObjects(caseDb, dataModelObjectIds);
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error geting TSK Data Model objects for %s event (%s)", getPropertyName(), getSourceType()), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(dataModelObjects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Sleuth Kit Data Model objects associated with this application
|
||||
* event.
|
||||
*
|
||||
* @param caseDb The case database.
|
||||
* @param ids The unique, numeric IDs (TSK object IDs, case database row
|
||||
* IDs, etc.) of the Sleuth Kit Data Model objects.
|
||||
*
|
||||
* @return The objects.
|
||||
*
|
||||
* @throws org.sleuthkit.datamodel.TskCoreException If there is an error
|
||||
* getting the Sleuth Kit
|
||||
* Data Model objects.
|
||||
*/
|
||||
abstract protected List<T> getDataModelObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException;
|
||||
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* An abstract base class for application events published when one or more
|
||||
* Sleuth Kit Data Model objects for a case change in some way.
|
||||
*
|
||||
* This class extends AutopsyEvent. The AutopsyEvent class extends
|
||||
* PropertyChangeEvent to integrate with legacy use of JavaBeans
|
||||
* PropertyChangeEvents and PropertyChangeListeners as an application event
|
||||
* publisher-subcriber mechanism. Subclasses need to decide what constitutes
|
||||
* "old" and "new" objects for them and are encouraged to provide getters for
|
||||
* these values that do not require clients to cast the return values.
|
||||
*
|
||||
* The AutopsyEvent class implements Serializable to allow local event instances
|
||||
* to be published to other Autopsy nodes over a network in serialized form. TSK
|
||||
* Data Model objects are generally not serializable because they encapsulate a
|
||||
* reference to a SleuthkitCase object that represents the case database and
|
||||
* which has local JDBC Connection objects. For this reason, this class supports
|
||||
* serialization of the unique numeric IDs (TSK object IDs, case database row
|
||||
* IDs, etc.) of the subject TSK Data Model objects and the "reconstruction" of
|
||||
* those objects on other Autopsy nodes by querying the case database by unique
|
||||
* ID.
|
||||
*
|
||||
* @param <T> The Sleuth Kit Data Model object type of the "old" data model
|
||||
* objects.
|
||||
* @param <U> The Sleuth Kit Data Model object type of the "new" data model
|
||||
* objects.
|
||||
*/
|
||||
public abstract class TskDataModelChangedEvent<T, U> extends AutopsyEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(TskDataModelChangedEvent.class.getName());
|
||||
private final boolean hasOldValue;
|
||||
private final List<Long> oldValueIds;
|
||||
private transient List<T> oldValueObjects;
|
||||
private final boolean hasNewValue;
|
||||
private final List<Long> newValueIds;
|
||||
private transient List<U> newValueObjects;
|
||||
|
||||
/**
|
||||
* Constructs the base class part for application events published when one
|
||||
* or more Sleuth Kit Data Model objects for a case change in some way.
|
||||
*
|
||||
* @param eventName The event name.
|
||||
* @param oldValueObjects A list of he Data Model objects that have been
|
||||
* designated as the "old" objects in the event.
|
||||
* May be null.
|
||||
* @param oldValueGetIdMethod A method that can be applied to the "old" data
|
||||
* model objects to get their unique numeric IDs
|
||||
* (TSK object IDs, case database row IDs, etc.).
|
||||
* May be null if there are no "old" objects.
|
||||
* @param newValueObjects A list of he Data Model objects that have been
|
||||
* designated as the "new" objects in the event.
|
||||
* May be null.
|
||||
* @param newValueGetIdMethod A method that can be applied to the "new" data
|
||||
* model objects to get their unique numeric IDs
|
||||
* (TSK object IDs, case database row IDs, etc.).
|
||||
* May be null if there are no "new" objects.
|
||||
*/
|
||||
protected TskDataModelChangedEvent(String eventName, List<T> oldValueObjects, Function<T, Long> oldValueGetIdMethod, List<U> newValueObjects, Function<U, Long> newValueGetIdMethod) {
|
||||
super(eventName, null, null);
|
||||
oldValueIds = new ArrayList<>();
|
||||
this.oldValueObjects = new ArrayList<>();
|
||||
if (oldValueObjects != null) {
|
||||
hasOldValue = true;
|
||||
oldValueIds.addAll(oldValueObjects.stream()
|
||||
.map(o -> oldValueGetIdMethod.apply(o))
|
||||
.collect(Collectors.toList()));
|
||||
this.oldValueObjects.addAll(oldValueObjects);
|
||||
} else {
|
||||
hasOldValue = false;
|
||||
}
|
||||
newValueIds = new ArrayList<>();
|
||||
this.newValueObjects = new ArrayList<>();
|
||||
if (newValueObjects != null) {
|
||||
hasNewValue = true;
|
||||
newValueIds.addAll(newValueObjects.stream()
|
||||
.map(o -> newValueGetIdMethod.apply(o))
|
||||
.collect(Collectors.toList()));
|
||||
this.newValueObjects.addAll(newValueObjects);
|
||||
} else {
|
||||
hasNewValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of the Data Model objects that have been designated as the
|
||||
* "old" objects in the event.
|
||||
*
|
||||
* @return The list of the "old" data model objects. May be empty.
|
||||
*/
|
||||
@Override
|
||||
public List<T> getOldValue() {
|
||||
if (hasOldValue) {
|
||||
if (oldValueObjects == null) {
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCaseThrows();
|
||||
SleuthkitCase caseDb = currentCase.getSleuthkitCase();
|
||||
oldValueObjects = getOldValueObjects(caseDb, oldValueIds);
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error getting oldValue() TSK Data Model objects for %s event (%s)", getPropertyName(), getSourceType()), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(oldValueObjects);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of the Data Model objects that have been designated as the
|
||||
* "new" objects in the event.
|
||||
*
|
||||
* @return The list of the "new" data model objects. May be empty.
|
||||
*/
|
||||
@Override
|
||||
public List<U> getNewValue() {
|
||||
if (hasNewValue) {
|
||||
if (newValueObjects == null) {
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCaseThrows();
|
||||
SleuthkitCase caseDb = currentCase.getSleuthkitCase();
|
||||
newValueObjects = getNewValueObjects(caseDb, newValueIds);
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error getting newValue() TSK Data Model objects for %s event (%s)", getPropertyName(), getSourceType()), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(newValueObjects);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs the "old" Sleuth Kit Data Model objects associated with this
|
||||
* application event, if any, using the given unique numeric IDs (TSK object
|
||||
* IDs, case database row IDs, etc.) to query the given case database.
|
||||
*
|
||||
* @param caseDb The case database.
|
||||
* @param ids The unique, numeric IDs (TSK object IDs, case database row
|
||||
* IDs, etc.) of the Sleuth Kit Data Model objects.
|
||||
*
|
||||
* @return The objects.
|
||||
*
|
||||
* @throws org.sleuthkit.datamodel.TskCoreException If there is an error
|
||||
* getting the Sleuth Kit
|
||||
* Data Model objects.
|
||||
*/
|
||||
protected List<T> getOldValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs the "new" Sleuth Kit Data Model objects associated with this
|
||||
* application event, if any, using the given unique numeric IDs (TSK object
|
||||
* IDs, case database row IDs, etc.) to query the given case database.
|
||||
*
|
||||
* @param caseDb The case database.
|
||||
* @param ids The unique, numeric IDs (TSK object IDs, case database row
|
||||
* IDs, etc.) of the Sleuth Kit Data Model objects.
|
||||
*
|
||||
* @return The objects.
|
||||
*
|
||||
* @throws org.sleuthkit.datamodel.TskCoreException If there is an error
|
||||
* getting the Sleuth Kit
|
||||
* Data Model objects.
|
||||
*/
|
||||
protected List<U> getNewValueObjects(SleuthkitCase caseDb, List<Long> ids) throws TskCoreException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
|
||||
/**
|
||||
* An abstract base class for application events published when one or more
|
||||
* Sleuth Kit Data Model objects for a case have been deleted.
|
||||
*
|
||||
* This class extends AutopsyEvent. The AutopsyEvent class extends
|
||||
* PropertyChangeEvent to integrate with legacy use of JavaBeans
|
||||
* PropertyChangeEvents and PropertyChangeListeners as an application event
|
||||
* publisher-subcriber mechanism. Subclasses need to decide what constitutes
|
||||
* "old" and "new" objects for them.
|
||||
*
|
||||
* For this class the "old" values are the unique numeric IDs (TSK object IDs,
|
||||
* case database row IDs, etc.) of the deleted TSK Data Model objects. There are
|
||||
* no "new" values. Subclasses are encouraged to provide less generic getters
|
||||
* with descriptive names for the unique IDs than the override of the inherited
|
||||
* getOldValue() method below. These getters can be implemented by delegating to
|
||||
* getOldValue().
|
||||
*/
|
||||
public class TskDataModelObjectsDeletedEvent extends AutopsyEvent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<Long> deletedObjectIds;
|
||||
|
||||
protected TskDataModelObjectsDeletedEvent(String eventName, List<Long> deletedObjectIds) {
|
||||
super(eventName, null, null);
|
||||
this.deletedObjectIds = new ArrayList<>();
|
||||
this.deletedObjectIds.addAll(deletedObjectIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getOldValue() {
|
||||
return Collections.unmodifiableList(deletedObjectIds);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
OptionsCategory_Name_TagNamesOptions=\u30ab\u30b9\u30bf\u30e0\u30fb\u30bf\u30b0
|
||||
OptionsCategory_TagNames=TagNames
|
||||
TagNameDefinition.predefTagNames.bookmark.text=\u30d6\u30c3\u30af\u30de\u30fc\u30af
|
||||
@@ -11,14 +11,21 @@ TagNameDialog.JOptionPane.tagNameEmpty.title=\u7a7a(\u672a\u5165\u529b)\u306e\u7
|
||||
TagNameDialog.JOptionPane.tagNameIllegalCharacters.message=\u30bf\u30b0\u540d\u306b\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u3089\u308c\u307e\u305b\u3093\: \\ \: * ? " < > | , ;
|
||||
TagNameDialog.JOptionPane.tagNameIllegalCharacters.title=\u30bf\u30b0\u540d\u306b\u7121\u52b9\u306a\u6587\u5b57\u304c\u3042\u308a\u307e\u3059
|
||||
TagNameDialog.cancelButton.text=\u53d6\u308a\u6d88\u3057
|
||||
TagNameDialog.descriptionLabel.text=\u8aac\u660e\uff1a
|
||||
TagNameDialog.editTitle.text=\u30bf\u30b0\u3092\u7de8\u96c6
|
||||
TagNameDialog.newTagNameLabel.text=\u540d\u524d\:
|
||||
TagNameDialog.notableCheckbox.text=\u30bf\u30b0\u306f\u30a2\u30a4\u30c6\u30e0\u304c\u6ce8\u76ee\u306b\u5024\u3059\u308b\u3053\u3068\u3092\u793a\u3057\u307e\u3059\u3002
|
||||
TagNameDialog.okButton.text=OK
|
||||
TagNameDialog.tagNameTextField.text=
|
||||
TagNameDialog.title.text=\u65b0\u898f\u30bf\u30b0
|
||||
TagOptionsPanel.TagNameDialog.tagNameAlreadyExists.message=\u30bf\u30b0\u540d\u306f\u4e00\u610f\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002\u3053\u306e\u540d\u524d\u306e\u30bf\u30b0\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\u3002
|
||||
TagOptionsPanel.TagNameDialog.tagNameAlreadyExists.title=\u30bf\u30b0\u540d\u3092\u8907\u88fd
|
||||
TagOptionsPanel.deleteTagNameButton.text=\u30bf\u30b0\u3092\u524a\u9664
|
||||
TagOptionsPanel.descriptionLabel.text=\u30bf\u30b0\u306e\u8aac\u660e\uff1a
|
||||
TagOptionsPanel.editTagNameButton.text=\u30bf\u30b0\u306e\u7de8\u96c6
|
||||
TagOptionsPanel.ingestRunningWarningLabel.text=\u53d6\u8fbc\u307f\u306e\u5b9f\u884c\u4e2d\u306f\u3001\u65e2\u5b58\u306e\u30bf\u30b0\u3092\u5909\u66f4\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
TagOptionsPanel.isNotableLabel.text=\u30bf\u30b0\u306f\u30a2\u30a4\u30c6\u30e0\u304c\u6ce8\u76ee\u306b\u5024\u3059\u308b\u3053\u3068\u3092\u793a\u3057\u307e\u3059\uff1a
|
||||
TagOptionsPanel.newTagNameButton.text=\u65b0\u898f\u30bf\u30b0
|
||||
TagOptionsPanel.panelDescriptionTextArea.text=\u30bf\u30b0\u3092\u4f5c\u6210\u3068\u7ba1\u7406\u3002 \u30bf\u30b0\u306f\u3001\u30b1\u30fc\u30b9\u5185\u306e\u30d5\u30a1\u30a4\u30eb\u3068\u7d50\u679c\u306b\u9069\u7528\u3067\u304d\u307e\u3059\u3002 \u6ce8\u76ee\u306e\u30bf\u30b0\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3067\u30bf\u30b0\u304c\u4ed8\u3051\u3089\u308c\u305f\u30a2\u30a4\u30c6\u30e0\u306b\u6ce8\u76ee\u306e\u30d5\u30e9\u30b0\u304c\u4ed8\u3051\u3089\u308c\u307e\u3059\u3002 \u30bf\u30b0\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u5909\u66f4\u3059\u308b\u3068\u3001\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u307f\u306b\u5f71\u97ff\u3057\u307e\u3059\u3002
|
||||
TagOptionsPanel.tagTypesListLabel.text=\u30bf\u30b0\u540d\:
|
||||
TagsManager.notableTagEnding.text=\ (\u9855\u8457)
|
||||
|
||||
@@ -130,8 +130,7 @@ public class FileManager implements Closeable {
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
public List<AbstractFile> findFilesExactName(long parentId, String name) throws TskCoreException{
|
||||
String whereClause = "name = '%s'";
|
||||
return caseDb.findAllFilesInFolderWhere(parentId, String.format(whereClause, name));
|
||||
return caseDb.getFileManager().findFilesExactName(parentId, name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,12 +219,7 @@ public class FileManager implements Closeable {
|
||||
* database.
|
||||
*/
|
||||
public List<AbstractFile> findFiles(String fileName, AbstractFile parent) throws TskCoreException {
|
||||
List<AbstractFile> result = new ArrayList<>();
|
||||
List<Content> dataSources = caseDb.getRootObjects();
|
||||
for (Content dataSource : dataSources) {
|
||||
result.addAll(findFiles(dataSource, fileName, parent));
|
||||
}
|
||||
return result;
|
||||
return caseDb.findFilesInFolder(fileName, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,25 +262,6 @@ public class FileManager implements Closeable {
|
||||
return caseDb.findFiles(dataSource, fileName, parentSubString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all files and directories with a given file name and given parent
|
||||
* file or directory in a given data source (image, local/logical files set,
|
||||
* etc.). The name search is for full or partial matches and is case
|
||||
* insensitive (a case insensitive SQL LIKE clause is used to query the case
|
||||
* database).
|
||||
*
|
||||
* @param dataSource The data source.
|
||||
* @param fileName The full name or a pattern to match on part of the name
|
||||
* @param parent The parent file or directory.
|
||||
*
|
||||
* @return The matching files and directories.
|
||||
*
|
||||
* @throws TskCoreException if there is a problem querying the case
|
||||
* database.
|
||||
*/
|
||||
public List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parent) throws TskCoreException {
|
||||
return findFiles(dataSource, fileName, parent.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all files and directories with a given file name and path in a
|
||||
@@ -779,5 +754,28 @@ public class FileManager implements Closeable {
|
||||
private AbstractFile addLocalFile(CaseDbTransaction trans, SpecialDirectory parentDirectory, java.io.File localFile, FileAddProgressUpdater progressUpdater) throws TskCoreException {
|
||||
return addLocalFile(trans, parentDirectory, localFile, TskData.EncodingType.NONE, progressUpdater);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all files and directories with a given file name and given parent
|
||||
* file or directory in a given data source (image, local/logical files set,
|
||||
* etc.). The name search is for full or partial matches and is case
|
||||
* insensitive (a case insensitive SQL LIKE clause is used to query the case
|
||||
* database).
|
||||
*
|
||||
* @param dataSource The data source.
|
||||
* @param fileName The full name or a pattern to match on part of the name
|
||||
* @param parent The parent file or directory.
|
||||
*
|
||||
* @return The matching files and directories.
|
||||
*
|
||||
* @throws TskCoreException if there is a problem querying the case
|
||||
* database.
|
||||
*
|
||||
* @deprecated Use version without the unnecessary dataSource argument
|
||||
*/
|
||||
@Deprecated
|
||||
public List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parent) throws TskCoreException {
|
||||
return findFiles(fileName, parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoComment=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6
|
||||
AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentEmptyFile=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6\uff08\u7a7a\u306e\u30d5\u30a1\u30a4\u30eb\uff09
|
||||
AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentNoMD5=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6\uff08MD5\u30cf\u30c3\u30b7\u30e5\u7121\u3057\uff09
|
||||
CentralRepoCommentDialog.cancelButton.text=C&ancel
|
||||
CentralRepoCommentDialog.commentLabel.text=\u30b3\u30e1\u30f3\u30c8\uff1a
|
||||
CentralRepoCommentDialog.okButton.text=&OK
|
||||
CentralRepoCommentDialog.title.addEditCentralRepoComment=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30b3\u30e1\u30f3\u30c8\u306e\u8ffd\u52a0/\u7de8\u96c6
|
||||
OpenIDE-Module-Display-Category=\u53d6\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb
|
||||
OpenIDE-Module-Long-Description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3068\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\n\n\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3001\u9078\u629e\u3057\u305f\u76f8\u95a2\u30bf\u30a4\u30d7\u306b\u4e00\u81f4\u3059\u308b\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306e\u5c5e\u6027\u3092\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u683c\u7d0d\u3057\u307e\u3059\u3002\n\u4fdd\u5b58\u3055\u308c\u305f\u5c5e\u6027\u306f\u3001\u5c06\u6765\u306e\u30b1\u30fc\u30b9\u3067\u3001\u53d6\u308a\u8fbc\u307f\u4e2d\u306b\u30d5\u30a1\u30a4\u30eb\u3068\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u76f8\u4e92\u306b\u95a2\u9023\u4ed8\u3051\u3066\u5206\u6790\u3059\u308b\u305f\u3081\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002
|
||||
OpenIDE-Module-Name=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea
|
||||
OpenIDE-Module-Short-Description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#Thu Jul 01 11:56:41 UTC 2021
|
||||
OtherOccurrences.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8
|
||||
OtherOccurrences.csvHeader.case=\u30b1\u30fc\u30b9
|
||||
OtherOccurrences.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8
|
||||
OtherOccurrences.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
|
||||
OtherOccurrences.csvHeader.device=\u30c7\u30d0\u30a4\u30b9
|
||||
OtherOccurrences.csvHeader.known=\u65e2\u77e5
|
||||
OtherOccurrences.csvHeader.path=\u30d1\u30b9
|
||||
OtherOccurrences.csvHeader.value=\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u5024
|
||||
+64
-24
@@ -31,6 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTimeZone;
|
||||
@@ -52,6 +53,9 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentTag;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
import org.sleuthkit.datamodel.OsAccountInstance;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@@ -63,17 +67,63 @@ import org.sleuthkit.datamodel.TskData;
|
||||
public final class OtherOccurrences {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(OtherOccurrences.class.getName());
|
||||
|
||||
|
||||
private static final String UUID_PLACEHOLDER_STRING = "NoCorrelationAttributeInstance";
|
||||
|
||||
private OtherOccurrences() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what attributes can be used for correlation based on the node.
|
||||
*
|
||||
* @param node The node to correlate
|
||||
* @param osAccount the osAccount to correlate
|
||||
*
|
||||
* @return A list of attributes that can be used for correlation
|
||||
*/
|
||||
public static Collection<CorrelationAttributeInstance> getCorrelationAttributeFromOsAccount(Node node, OsAccount osAccount) {
|
||||
Collection<CorrelationAttributeInstance> ret = new ArrayList<>();
|
||||
Optional<String> osAccountAddr = osAccount.getAddr();
|
||||
|
||||
if (osAccountAddr.isPresent()) {
|
||||
try {
|
||||
for (OsAccountInstance instance : osAccount.getOsAccountInstances()) {
|
||||
DataSource osAccountDataSource = instance.getDataSource();
|
||||
try {
|
||||
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
|
||||
CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance(
|
||||
CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID),
|
||||
osAccountAddr.get(),
|
||||
correlationCase,
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, instance.getDataSource()),
|
||||
"",
|
||||
"",
|
||||
TskData.FileKnown.KNOWN,
|
||||
osAccount.getId());
|
||||
|
||||
ret.add(correlationAttributeInstance);
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", osAccountAddr.get()), ex); //NON-NLS
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.WARNING, String.format("Exception while getting open case looking up osAccount %s.", osAccountAddr.get()), ex); //NON-NLS
|
||||
} catch (CorrelationAttributeNormalizationException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Exception with Correlation Attribute Normalization for osAccount %s.", osAccountAddr.get()), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.INFO, String.format("Unable to check create CorrelationAttribtueInstance for osAccount %s.", osAccountAddr.get()), ex);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what attributes can be used for correlation based on the node.
|
||||
* If EamDB is not enabled, get the default Files correlation.
|
||||
*
|
||||
* @param node The node to correlate
|
||||
* @param node The node to correlate.
|
||||
* @param file The file to correlate.
|
||||
*
|
||||
* @return A list of attributes that can be used for correlation
|
||||
*/
|
||||
@@ -170,7 +220,6 @@ public final class OtherOccurrences {
|
||||
public static AbstractFile getAbstractFileFromNode(Node node) {
|
||||
BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class);
|
||||
ContentTag nodeContentTag = node.getLookup().lookup(ContentTag.class);
|
||||
BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class);
|
||||
AbstractFile nodeAbstractFile = node.getLookup().lookup(AbstractFile.class);
|
||||
|
||||
if (nodeBbArtifactTag != null) {
|
||||
@@ -180,18 +229,6 @@ public final class OtherOccurrences {
|
||||
}
|
||||
} else if (nodeContentTag != null) {
|
||||
Content content = nodeContentTag.getContent();
|
||||
if (content instanceof AbstractFile) {
|
||||
return (AbstractFile) content;
|
||||
}
|
||||
} else if (nodeBbArtifact != null) {
|
||||
Content content;
|
||||
try {
|
||||
content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error retrieving blackboard artifact", ex); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
if (content instanceof AbstractFile) {
|
||||
return (AbstractFile) content;
|
||||
}
|
||||
@@ -208,7 +245,10 @@ public final class OtherOccurrences {
|
||||
* artifact. If the central repo is not enabled, this will only return files
|
||||
* from the current case with matching MD5 hashes.
|
||||
*
|
||||
* @param corAttr CorrelationAttribute to query for
|
||||
* @param file The current file.
|
||||
* @param deviceId The device ID for the current data source.
|
||||
* @param dataSourceName The name of the current data source.
|
||||
* @param corAttr CorrelationAttribute to query for
|
||||
*
|
||||
* @return A collection of correlated artifact instances
|
||||
*/
|
||||
@@ -240,12 +280,12 @@ public final class OtherOccurrences {
|
||||
UniquePathKey uniquePathKey = new UniquePathKey(newNode);
|
||||
nodeDataMap.put(uniquePathKey, newNode);
|
||||
}
|
||||
if (file != null && corAttr.getCorrelationType().getDisplayName().equals("Files")) {
|
||||
List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase, file);
|
||||
}
|
||||
if (file != null && corAttr.getCorrelationType().getDisplayName().equals("Files")) {
|
||||
List<AbstractFile> caseDbFiles = getCaseDbMatches(corAttr, openCase, file);
|
||||
|
||||
for (AbstractFile caseDbFile : caseDbFiles) {
|
||||
addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
|
||||
}
|
||||
for (AbstractFile caseDbFile : caseDbFiles) {
|
||||
addOrUpdateNodeData(openCase, nodeDataMap, caseDbFile);
|
||||
}
|
||||
}
|
||||
return nodeDataMap;
|
||||
@@ -347,7 +387,7 @@ public final class OtherOccurrences {
|
||||
public static String makeDataSourceString(String caseUUID, String deviceId, String dataSourceName) {
|
||||
return caseUUID + deviceId + dataSourceName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the list of Eam Cases and determines the earliest case creation
|
||||
* date. Sets the label to display the earliest date string to the user.
|
||||
@@ -377,8 +417,8 @@ public final class OtherOccurrences {
|
||||
|
||||
return dateStringDisplay;
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
|
||||
@NbBundle.Messages({
|
||||
"OtherOccurrences.csvHeader.case=Case",
|
||||
"OtherOccurrences.csvHeader.device=Device",
|
||||
"OtherOccurrences.csvHeader.dataSource=Data Source",
|
||||
|
||||
+1
-1
@@ -43,5 +43,5 @@ OtherOccurrencesPanel.showCommonalityMenuItem.text=Show Frequency
|
||||
OtherOccurrencesPanel.showCaseDetailsMenuItem.text=Show Case Details
|
||||
OtherOccurrencesPanel.table.noArtifacts=Item has no attributes with which to search.
|
||||
OtherOccurrencesPanel.table.noResultsFound=No results found.
|
||||
OtherOccurrencesPanel_earliestCaseNotAvailable=Not Availble.
|
||||
OtherOccurrencesPanel_earliestCaseNotAvailable=Not Available.
|
||||
OtherOccurrencesPanel_table_loadingResults=Loading results
|
||||
|
||||
+28
-40
@@ -1,54 +1,42 @@
|
||||
DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=\u30a8\u30e9\u30fc
|
||||
DataContentViewerOtherCases.caseDetailsDialog.noDetails=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
DataContentViewerOtherCases.caseDetailsDialog.noDetailsReference=\u30b0\u30ed\u30fc\u30d0\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u30b1\u30fc\u30b9\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
DataContentViewerOtherCases.caseDetailsDialog.notSelected=\u884c\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
|
||||
# {0} - \u5171\u6709\u6027\u306e\u5272\u5408
|
||||
# {1} - \u76f8\u95a2\u5206\u6790\u30bf\u30a4\u30d7
|
||||
# {2} - \u76f8\u95a2\u5206\u6790\u5024
|
||||
DataContentViewerOtherCases.correlatedArtifacts.byType=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e {0}% \u306b {2} \u304c\u3042\u308a\u307e\u3059(\u30bf\u30a4\u30d7: {1})\n
|
||||
DataContentViewerOtherCases.correlatedArtifacts.failed=\u983b\u5ea6\u306e\u8a73\u7d30\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
DataContentViewerOtherCases.correlatedArtifacts.isEmpty=\u76f8\u95a2\u5206\u6790\u3059\u308b\u305f\u3081\u306e\u30d5\u30a1\u30a4\u30eb\u3084\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
DataContentViewerOtherCases.correlatedArtifacts.title=\u5c5e\u6027\u983b\u5ea6
|
||||
DataContentViewerOtherCases.dataSources.header.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d
|
||||
DataContentViewerOtherCases.earliestCaseNotAvailable=\ \u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002
|
||||
DataContentViewerOtherCases.foundIn.text=%d \u306e\u30b1\u30fc\u30b9\u3068 %d \u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u5185\u306b %d \u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002
|
||||
DataContentViewerOtherCases.noOpenCase.errMsg=\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
DataContentViewerOtherCases.table.noArtifacts=\u9805\u76ee\u306b\u691c\u7d22\u306b\u5229\u7528\u3067\u304d\u308b\u5c5e\u6027\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
DataContentViewerOtherCases.table.noResultsFound=\u8a72\u5f53\u3059\u308b\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
#Thu Jul 01 11:56:41 UTC 2021
|
||||
DataContentViewerOtherCases.table.toolTip.text=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002
|
||||
DataContentViewerOtherCases.title=\u305d\u306e\u4ed6\u306e\u767a\u751f
|
||||
DataContentViewerOtherCases.toolTip=\u305d\u306e\u4ed6\u306e\u767a\u751f\u304b\u3089\u9078\u629e\u3057\u305f\u30d5\u30a1\u30a4\u30eb/\u904e\u53bb\u306e\u691c\u7d22\u7d50\u679c\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u8868\u793a\u3057\u307e\u3059\u3002
|
||||
DataContentViewerOtherCasesModel.csvHeader.attribute=\u4e00\u81f4\u3057\u305f\u5c5e\u6027
|
||||
DataContentViewerOtherCasesModel.csvHeader.case=\u30b1\u30fc\u30b9
|
||||
DataContentViewerOtherCasesModel.csvHeader.comment=\u30b3\u30e1\u30f3\u30c8
|
||||
DataContentViewerOtherCasesModel.csvHeader.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
|
||||
DataContentViewerOtherCasesModel.csvHeader.device=\u30c7\u30d0\u30a4\u30b9
|
||||
DataContentViewerOtherCasesModel.csvHeader.known=\u65e2\u77e5
|
||||
DataContentViewerOtherCasesModel.csvHeader.path=\u30d1\u30b9
|
||||
DataContentViewerOtherCasesModel.csvHeader.value=\u5c5e\u6027\u5024
|
||||
OccurrencePanel.caseCreatedDateLabel.text=\u4f5c\u6210\u65e5:
|
||||
OccurrencePanel.caseCreatedDateLabel.text=\u4f5c\u6210\u65e5\:
|
||||
OccurrencePanel.caseDetails.text=\u30b1\u30fc\u30b9\u8a73\u7d30
|
||||
OccurrencePanel.caseNameLabel.text=\u540d\u524d:
|
||||
OccurrencePanel.caseNameLabel.text=\u540d\u524d\:
|
||||
OccurrencePanel.commonProperties.text=\u5171\u901a\u306e\u30d7\u30ed\u30d1\u30c6\u30a3
|
||||
OccurrencePanel.commonPropertyCommentLabel.text=\u30b3\u30e1\u30f3\u30c8:
|
||||
OccurrencePanel.commonPropertyKnownStatusLabel.text=\u65e2\u77e5\u306e\u30b9\u30c6\u30fc\u30bf\u30b9:
|
||||
OccurrencePanel.commonPropertyTypeLabel.text=\u30bf\u30a4\u30d7:
|
||||
OccurrencePanel.commonPropertyValueLabel.text=\u5024:
|
||||
OccurrencePanel.commonPropertyCommentLabel.text=\u30b3\u30e1\u30f3\u30c8\:
|
||||
OccurrencePanel.commonPropertyKnownStatusLabel.text=\u65e2\u77e5\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\:
|
||||
OccurrencePanel.commonPropertyTypeLabel.text=\u30bf\u30a4\u30d7\:
|
||||
OccurrencePanel.commonPropertyValueLabel.text=\u5024\:
|
||||
OccurrencePanel.dataSourceDetails.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u8a73\u7d30
|
||||
OccurrencePanel.dataSourceNameLabel.text=\u540d\u524d:
|
||||
OccurrencePanel.dataSourceNameLabel.text=\u540d\u524d\:
|
||||
OccurrencePanel.fileDetails.text=\u30d5\u30a1\u30a4\u30eb\u8a73\u7d30
|
||||
OccurrencePanel.filePathLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9:
|
||||
OccurrencePanel.filePathLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\:
|
||||
OtherOccurrencesCasesTableModel.case=\u30b1\u30fc\u30b9
|
||||
OtherOccurrencesCasesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesDataSourcesTableModel.dataSourceName=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d
|
||||
OtherOccurrencesDataSourcesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesFilesTableModel.fileName=\u30d5\u30a1\u30a4\u30eb\u540d
|
||||
OtherOccurrencesFilesTableModel.noData=\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel.filesTable.toolTipText=\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u30bd\u30fc\u30c8\u3057\u307e\u3059\u3002\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u3055\u3089\u306a\u308b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8868\u793a\u3057\u307e\u3059\u3002
|
||||
OtherOccurrencesPanel.earliestCaseLabel.toolTipText=
|
||||
OtherOccurrencesPanel.earliestCaseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u958b\u59cb\u65e5:
|
||||
OtherOccurrencesPanel.earliestCaseDate.text=\u6700\u3082\u53e4\u3044\u30b1\u30fc\u30b9\u65e5\u4ed8
|
||||
OtherOccurrencesPanel.foundInLabel.text=
|
||||
OtherOccurrencesPanel.caseDetailsDialog.noCaseNameError=\u30a8\u30e9\u30fc
|
||||
OtherOccurrencesPanel.caseDetailsDialog.noDetails=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel.caseDetailsDialog.noDetailsReference=\u30b0\u30ed\u30fc\u30d0\u30eb\u53c2\u7167\u30d7\u30ed\u30d1\u30c6\u30a3\u306e\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel.caseDetailsDialog.notSelected=\u884c\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
|
||||
OtherOccurrencesPanel.correlatedArtifacts.byType=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e{0}\uff05\u306b{2}\u304c\u3042\u308a\u307e\u3059\uff08\u30bf\u30a4\u30d7\uff1a{1}\uff09
|
||||
OtherOccurrencesPanel.correlatedArtifacts.failed=\u983b\u5ea6\u306e\u8a73\u7d30\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
OtherOccurrencesPanel.correlatedArtifacts.isEmpty=\u95a2\u9023\u4ed8\u3051\u308b\u30d5\u30a1\u30a4\u30eb\u3084\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel.correlatedArtifacts.title=\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u306e\u983b\u5ea6
|
||||
OtherOccurrencesPanel.earliestCaseDate.text=\u30b1\u30fc\u30b9\u306e\u6700\u521d\u306e\u65e5\u4ed8
|
||||
OtherOccurrencesPanel.earliestCaseLabel.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u958b\u59cb\u65e5\uff1a
|
||||
OtherOccurrencesPanel.exportToCSVMenuItem.text=\u305d\u306e\u4ed6\u306e\u3059\u3079\u3066\u306e\u767a\u751f\u3092CSV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
|
||||
OtherOccurrencesPanel.filesTable.toolTipText=\u4e26\u3079\u66ff\u3048\u306f\u5217\u540d\u3092\u30af\u30ea\u30c3\u30af\u3002 \u305d\u306e\u4ed6\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u3001\u30c6\u30fc\u30d6\u30eb\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3002
|
||||
OtherOccurrencesPanel.foundIn.text=\uff05d\u30b1\u30fc\u30b9\u3068\uff05d\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3067\uff05d\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002
|
||||
OtherOccurrencesPanel.noOpenCase.errMsg=\u30aa\u30fc\u30d7\u30f3\u30b1\u30fc\u30b9\u306f\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel.showCaseDetailsMenuItem.text=\u30b1\u30fc\u30b9\u306e\u8a73\u7d30\u3092\u8868\u793a
|
||||
OtherOccurrencesPanel.showCommonalityMenuItem.text=\u983b\u5ea6\u3092\u8868\u793a
|
||||
OtherOccurrencesPanel.showCaseDetailsMenuItem.text=\u30b1\u30fc\u30b9\u8a73\u7d30\u3092\u8868\u793a
|
||||
OtherOccurrencesPanel.exportToCSVMenuItem.text=\u305d\u306e\u4ed6\u3059\u3079\u3066\u306e\u767a\u751f\u3092CSV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8
|
||||
OtherOccurrencesPanel.table.noArtifacts=\u30a2\u30a4\u30c6\u30e0\u306b\u306f\u3001\u691c\u7d22\u3059\u308b\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel.table.noResultsFound=\u7d50\u679c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002
|
||||
OtherOccurrencesPanel_earliestCaseNotAvailable=\u5229\u7528\u4e0d\u53ef\u3002
|
||||
OtherOccurrencesPanel_table_loadingResults=\u7d50\u679c\u306e\u8aad\u8fbc\u4e2d
|
||||
|
||||
+8
-6
@@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.centralrepository.application.OtherOccurrences;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
|
||||
/**
|
||||
* View correlation results from other cases
|
||||
@@ -90,17 +91,18 @@ public final class DataContentViewerOtherCases extends JPanel implements DataCon
|
||||
public boolean isSupported(Node node) {
|
||||
|
||||
// Is supported if one of the following is true:
|
||||
// - The central repo is enabled and the node has correlatable content
|
||||
// (either through the MD5 hash of the associated file or through a BlackboardArtifact)
|
||||
// - The central repo is enabled and the node is not null
|
||||
// - The central repo is disabled and the backing file has a valid MD5 hash
|
||||
AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node);
|
||||
if (CentralRepository.isEnabled()) {
|
||||
return !OtherOccurrences.getCorrelationAttributesFromNode(node, file).isEmpty();
|
||||
} else {
|
||||
// And the node has information which could be correlated on.
|
||||
if (CentralRepository.isEnabled() && node != null) {
|
||||
return OtherOccurrences.getAbstractFileFromNode(node) != null || OtherOccurrences.getBlackboardArtifactFromNode(node) != null || node.getLookup().lookup(OsAccount.class) != null;
|
||||
} else if (node != null) {
|
||||
AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node);
|
||||
return file != null
|
||||
&& file.getSize() > 0
|
||||
&& ((file.getMd5Hash() != null) && (!file.getMd5Hash().isEmpty()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-2
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.contentviewer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -37,6 +38,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
@@ -60,7 +62,11 @@ class OtherOccurrencesNodeWorker extends SwingWorker<OtherOccurrencesData, Void>
|
||||
|
||||
@Override
|
||||
protected OtherOccurrencesData doInBackground() throws Exception {
|
||||
OsAccount osAccount = node.getLookup().lookup(OsAccount.class);
|
||||
AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node);
|
||||
if (osAccount != null) {
|
||||
file = node.getLookup().lookup(AbstractFile.class);
|
||||
}
|
||||
String deviceId = "";
|
||||
String dataSourceName = "";
|
||||
Map<String, CorrelationCase> caseNames = new HashMap<>();
|
||||
@@ -77,8 +83,12 @@ class OtherOccurrencesNodeWorker extends SwingWorker<OtherOccurrencesData, Void>
|
||||
// @@@ Review this behavior
|
||||
return null;
|
||||
}
|
||||
Collection<CorrelationAttributeInstance> correlationAttributes = OtherOccurrences.getCorrelationAttributesFromNode(node, file);
|
||||
|
||||
Collection<CorrelationAttributeInstance> correlationAttributes = new ArrayList<>();
|
||||
if (osAccount != null) {
|
||||
correlationAttributes = OtherOccurrences.getCorrelationAttributeFromOsAccount(node, osAccount);
|
||||
} else {
|
||||
correlationAttributes = OtherOccurrences.getCorrelationAttributesFromNode(node, file);
|
||||
}
|
||||
int totalCount = 0;
|
||||
Set<String> dataSources = new HashSet<>();
|
||||
for (CorrelationAttributeInstance corAttr : correlationAttributes) {
|
||||
|
||||
-2
@@ -34,8 +34,6 @@
|
||||
</MenuItem>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JFileChooser" name="CSVFileChooser">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
|
||||
+96
-68
@@ -35,6 +35,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JMenuItem;
|
||||
@@ -46,7 +49,6 @@ import javax.swing.SwingWorker;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.table.TableRowSorter;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
@@ -71,7 +73,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noArtifacts());
|
||||
private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noResultsFound());
|
||||
private static final CorrelationCaseWrapper LOADING_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_loadingResults());
|
||||
private static final Logger logger = Logger.getLogger(OtherOccurrencesPanel.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final OtherOccurrencesFilesTableModel filesTableModel;
|
||||
@@ -85,6 +86,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
private SwingWorker<?, ?> worker;
|
||||
|
||||
// Initializing the JFileChooser in a thread to prevent a block on the EDT
|
||||
// see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel
|
||||
private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(JFileChooser::new);
|
||||
private JFileChooser CSVFileChooser;
|
||||
|
||||
/**
|
||||
* Creates new form OtherOccurrencesPanel
|
||||
*/
|
||||
@@ -93,9 +99,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
this.casesTableModel = new OtherOccurrencesCasesTableModel();
|
||||
this.dataSourcesTableModel = new OtherOccurrencesDataSourcesTableModel();
|
||||
this.correlationAttributes = new ArrayList<>();
|
||||
occurrencePanel = new OccurrencePanel();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
executor.execute(futureFileChooser);
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
@@ -215,7 +223,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
String caseDisplayName = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noCaseNameError();
|
||||
String details = Bundle.OtherOccurrencesPanel_caseDetailsDialog_noDetails();
|
||||
try {
|
||||
if (-1 != selectedRowViewIdx) {
|
||||
if (-1 != selectedRowViewIdx && filesTableModel.getRowCount() > 0) {
|
||||
CentralRepository dbManager = CentralRepository.getInstance();
|
||||
int selectedRowModelIdx = filesTable.convertRowIndexToModel(selectedRowViewIdx);
|
||||
List<NodeData> rowList = filesTableModel.getListOfNodesForFile(selectedRowModelIdx);
|
||||
@@ -245,6 +253,18 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
private void saveToCSV() throws NoCurrentCaseException {
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
|
||||
if (CSVFileChooser == null) {
|
||||
try {
|
||||
CSVFileChooser = futureFileChooser.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
// If something happened with the thread try and
|
||||
// initalized the chooser now
|
||||
logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread");
|
||||
CSVFileChooser = new JFileChooser();
|
||||
}
|
||||
}
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
String fileName = String.format("%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now);
|
||||
CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCaseThrows().getExportDirectory()));
|
||||
@@ -258,13 +278,13 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
|
||||
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
|
||||
}
|
||||
CSVWorker worker = new CSVWorker(selectedFile, file, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes));
|
||||
worker.execute();
|
||||
CSVWorker csvWorker = new CSVWorker(selectedFile, file, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes));
|
||||
csvWorker.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"OtherOccurrencesPanel_earliestCaseNotAvailable=Not Availble."})
|
||||
@NbBundle.Messages({"OtherOccurrencesPanel_earliestCaseNotAvailable=Not Available."})
|
||||
/**
|
||||
* Reset the UI and clear cached data.
|
||||
*/
|
||||
@@ -309,8 +329,9 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
casesTableModel.clearTable();
|
||||
|
||||
OtherOccurrenceOneTypeWorker.OneTypeData data = get();
|
||||
|
||||
OtherOccurrenceOneTypeWorker.OneTypeData data = get();
|
||||
correlationAttributes.addAll(data.getCorrelationAttributesToAdd());
|
||||
for (CorrelationCase corCase : data.getCaseNames().values()) {
|
||||
casesTableModel.addCorrelationCase(new CorrelationCaseWrapper(corCase));
|
||||
}
|
||||
@@ -319,12 +340,13 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
|
||||
} else if (caseCount == 0) {
|
||||
casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
|
||||
}
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
} else {
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getTotalCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
@@ -369,12 +391,13 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
casesTableModel.addCorrelationCase(NO_ARTIFACTS_CASE);
|
||||
} else if (caseCount == 0) {
|
||||
casesTableModel.addCorrelationCase(NO_RESULTS_CASE);
|
||||
}
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
} else {
|
||||
String earliestDate = data.getEarliestCaseDate();
|
||||
earliestCaseDate.setText(earliestDate.isEmpty() ? Bundle.OtherOccurrencesPanel_earliestCaseNotAvailable() : earliestDate);
|
||||
foundInLabel.setText(String.format(Bundle.OtherOccurrencesPanel_foundIn_text(), data.getInstanceDataCount(), caseCount, data.getDataSourceCount()));
|
||||
if (caseCount > 0) {
|
||||
casesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +423,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
|
||||
worker = new SelectionWorker(correlationAttributes, file, deviceId, dataSourceName) {
|
||||
@@ -420,31 +443,32 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
currentCaseName = null;
|
||||
logger.log(Level.WARNING, "Unable to get current case for other occurrences content viewer", ex);
|
||||
}
|
||||
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedRow : selectedCaseIndexes) {
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
|
||||
&& casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedRow : selectedCaseIndexes) {
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)) != null
|
||||
&& casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())) {
|
||||
dataSourcesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else if (currentCaseName != null && (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(currentCaseName))) {
|
||||
dataSourcesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else if (currentCaseName != null && (casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(selectedRow)).getCaseUUID().equals(currentCaseName))) {
|
||||
dataSourcesTableModel.addNodeData(nodeData);
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dataSourcesTable.getRowCount() > 0) {
|
||||
if (dataSourcesTableModel.getRowCount() > 0) {
|
||||
dataSourcesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to update OtherOccurrencesPanel on data source selection", ex);
|
||||
logger.log(Level.SEVERE, "Failed to update OtherOccurrencesPanel on data source selection", ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -476,25 +500,29 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
try {
|
||||
Map<UniquePathKey, NodeData> correlatedNodeDataMap = get();
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedDataSourceRow : selectedDataSources) {
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (dataSourcesTableModel.getCaseUUIDForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
|
||||
&& dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else {
|
||||
if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
if (dataSourcesTableModel.getRowCount() > 0) {
|
||||
for (NodeData nodeData : correlatedNodeDataMap.values()) {
|
||||
for (int selectedDataSourceRow : selectedDataSources) {
|
||||
int rowModelIndex = dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow);
|
||||
try {
|
||||
if (nodeData.isCentralRepoNode()) {
|
||||
if (dataSourcesTableModel.getCaseUUIDForRow(rowModelIndex).equals(nodeData.getCorrelationAttributeInstance().getCorrelationCase().getCaseUUID())
|
||||
&& dataSourcesTableModel.getDeviceIdForRow(rowModelIndex).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
} else {
|
||||
if (dataSourcesTableModel.getDeviceIdForRow(dataSourcesTable.convertRowIndexToModel(selectedDataSourceRow)).equals(nodeData.getDeviceID())) {
|
||||
filesTableModel.addNodeData(nodeData);
|
||||
}
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get correlation attribute instance from OtherOccurrenceNodeInstanceData for case " + nodeData.getCaseName(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filesTable.getRowCount() > 0) {
|
||||
|
||||
if (filesTableModel.getRowCount() > 0) {
|
||||
filesTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
@@ -515,18 +543,20 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
private void updateOnFileSelection() {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
try {
|
||||
if (filesTable.getSelectedRowCount() == 1) {
|
||||
if (filesTableModel.getRowCount() > 0 && filesTable.getSelectedRowCount() == 1) {
|
||||
//if there is one file selected update the deatils to show the data for that file
|
||||
occurrencePanel = new OccurrencePanel(filesTableModel.getListOfNodesForFile(filesTable.convertRowIndexToModel(filesTable.getSelectedRow())));
|
||||
} else if (dataSourcesTable.getSelectedRowCount() == 1) {
|
||||
} else if (dataSourcesTableModel.getRowCount() > 0 && dataSourcesTable.getSelectedRowCount() == 1) {
|
||||
//if no files were selected and only one data source is selected update the information to reflect the data source
|
||||
String caseName = dataSourcesTableModel.getCaseNameForRow(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()));
|
||||
String dsName = dataSourcesTableModel.getValueAt(dataSourcesTable.convertRowIndexToModel(dataSourcesTable.getSelectedRow()), 0).toString();
|
||||
String caseCreatedDate = "";
|
||||
for (int row : casesTable.getSelectedRows()) {
|
||||
if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
|
||||
caseCreatedDate = getCaseCreatedDate(row);
|
||||
break;
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
for (int row : casesTable.getSelectedRows()) {
|
||||
if (casesTableModel.getValueAt(casesTable.convertRowIndexToModel(row), 0).toString().equals(caseName)) {
|
||||
caseCreatedDate = getCaseCreatedDate(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
occurrencePanel = new OccurrencePanel(caseName, caseCreatedDate, dsName);
|
||||
@@ -535,7 +565,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
//update the information to reflect the case
|
||||
String createdDate;
|
||||
String caseName = "";
|
||||
if (casesTable.getRowCount() > 0) {
|
||||
if (casesTableModel.getRowCount() > 0) {
|
||||
caseName = casesTableModel.getValueAt(casesTable.convertRowIndexToModel(casesTable.getSelectedRow()), 0).toString();
|
||||
}
|
||||
if (caseName.isEmpty()) {
|
||||
@@ -566,7 +596,7 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
private String getCaseCreatedDate(int caseTableRowIdx) {
|
||||
try {
|
||||
if (CentralRepository.isEnabled()) {
|
||||
if (CentralRepository.isEnabled() && casesTableModel.getRowCount() > 0) {
|
||||
CorrelationCase partialCase;
|
||||
partialCase = casesTableModel.getCorrelationCase(casesTable.convertRowIndexToModel(caseTableRowIdx));
|
||||
if (partialCase == null) {
|
||||
@@ -594,11 +624,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Construct a new SelectionWorker.
|
||||
*
|
||||
*
|
||||
* @param coAtInstances
|
||||
* @param abstractFile
|
||||
* @param deviceIdStr
|
||||
* @param dataSourceNameStr
|
||||
* @param dataSourceNameStr
|
||||
*/
|
||||
SelectionWorker(Collection<CorrelationAttributeInstance> coAtInstances, AbstractFile abstractFile, String deviceIdStr, String dataSourceNameStr) {
|
||||
this.coAtInstances = coAtInstances;
|
||||
@@ -612,12 +642,12 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
Map<UniquePathKey, NodeData> correlatedNodeDataMap = new HashMap<>();
|
||||
for (CorrelationAttributeInstance corAttr : coAtInstances) {
|
||||
correlatedNodeDataMap.putAll(OtherOccurrences.getCorrelatedInstances(abstractFile, deviceIdStr, dataSourceNameStr, corAttr));
|
||||
|
||||
if(isCancelled()) {
|
||||
|
||||
if (isCancelled()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return correlatedNodeDataMap;
|
||||
}
|
||||
}
|
||||
@@ -685,7 +715,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
exportToCSVMenuItem = new javax.swing.JMenuItem();
|
||||
showCaseDetailsMenuItem = new javax.swing.JMenuItem();
|
||||
showCommonalityMenuItem = new javax.swing.JMenuItem();
|
||||
CSVFileChooser = new javax.swing.JFileChooser();
|
||||
tableContainerPanel = new javax.swing.JPanel();
|
||||
tablesViewerSplitPane = new javax.swing.JSplitPane();
|
||||
caseDatasourceFileSplitPane = new javax.swing.JSplitPane();
|
||||
@@ -704,12 +733,12 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
|
||||
|
||||
rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
||||
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
|
||||
rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
|
||||
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
||||
}
|
||||
public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
|
||||
}
|
||||
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
||||
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
|
||||
rightClickPopupMenuPopupMenuWillBecomeVisible(evt);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -857,7 +886,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel {
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JFileChooser CSVFileChooser;
|
||||
private javax.swing.JSplitPane caseDatasourceFileSplitPane;
|
||||
private javax.swing.JSplitPane caseDatasourceSplitPane;
|
||||
private javax.swing.JScrollPane caseScrollPane;
|
||||
|
||||
@@ -25,7 +25,9 @@ CorrelationType.ICCID.displayName=ICCID Number
|
||||
CorrelationType.IMEI.displayName=IMEI Number
|
||||
CorrelationType.IMSI.displayName=IMSI Number
|
||||
CorrelationType.MAC.displayName=MAC Addresses
|
||||
CorrelationType.OS_ACCOUNT.displayName=Os Account
|
||||
CorrelationType.PHONE.displayName=Phone Numbers
|
||||
CorrelationType.PROG_NAME.displayName=Installed Programs
|
||||
CorrelationType.SSID.displayName=Wireless Networks
|
||||
CorrelationType.USBID.displayName=USB Devices
|
||||
EamArtifactInstances.knownStatus.bad=Bad
|
||||
|
||||
@@ -1,11 +1,51 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AbstractSqlEamDb.badMajorSchema.message=\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u5024\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\uff08{0}\uff09-\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002
|
||||
AbstractSqlEamDb.badMinorSchema.message=\u30b9\u30ad\u30fc\u30de\u30de\u30a4\u30ca\u30fc\u30d0\u30fc\u30b8\u30e7\u30f3\uff08{0}\uff09\u306e\u5024\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093-\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u7834\u640d\u3057\u3066\u3044\u307e\u3059\u3002
|
||||
AbstractSqlEamDb.cannotUpgrage.message=\u73fe\u5728\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0 "{0}"\u306f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
AbstractSqlEamDb.failedToReadMajorVersion.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b9\u30ad\u30fc\u30de\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u8aad\u53d6\u308a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||
AbstractSqlEamDb.failedToReadMinorVersion.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b9\u30ad\u30fc\u30de\u30de\u30a4\u30ca\u30fc\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u8aad\u53d6\u308a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||
AbstractSqlEamDb.upgradeSchema.incompatible=\u9078\u629e\u3057\u305f\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3068\u4e92\u63db\u6027\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u3053\u306e\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u304f\u3060\u3055\u3044\u3002
|
||||
CentralRepoDbChoice.Disabled.Text=\u7121\u52b9
|
||||
CentralRepoDbChoice.PostgreSQL.Text=\u30ab\u30b9\u30bf\u30e0PostgreSQL
|
||||
CentralRepoDbChoice.PostgreSQL_Multiuser.Text=\u30de\u30eb\u30c1\u30e6\u30fc\u30b6\u30fc\u8a2d\u5b9a\u4f7f\u7528PostgreSQL
|
||||
CentralRepoDbChoice.Sqlite.Text=SQLite
|
||||
CentralRepoDbManager.connectionErrorMsg.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||
CentralRepositoryService.progressMsg.updatingSchema=\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u3066\u3044\u307e\u3059\u2026
|
||||
CentralRepositoryService.progressMsg.updatingSchema=\u30b9\u30ad\u30fc\u30de\u306e\u66f4\u65b0\u3092\u78ba\u8a8d\u3057\u3066\u3044\u307e\u3059...
|
||||
CentralRepositoryService.progressMsg.waitingForListeners=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3078\u30c7\u30fc\u30bf\u306e\u8ffd\u52a0\u3092\u7d42\u4e86\u4e2d...\u3002
|
||||
CentralRepositoryService.serviceName=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u30fb\u30b5\u30fc\u30d3\u30b9
|
||||
CorrelationAttributeInstance.invalidName.message=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c6\u30fc\u30d6\u30eb\u540d\u304c\u7121\u52b9\u3067\u3059\u3002 \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c6\u30fc\u30d6\u30eb\u540d\u306b\u306f\u5c0f\u6587\u5b57\u30a2\u30eb\u30d5\u30a1\u30d9\u30c3\u30c8\u3001\u6570\u5b57\u3001\u304a\u3088\u3073\u300c_\u300d\u306e\u307f\u304c\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002
|
||||
CorrelationAttributeInstance.nullName.message=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\u304cnull\u3067\u3059\u3002
|
||||
CorrelationAttributeUtil.emailaddresses.text=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9
|
||||
CorrelationType.DOMAIN.displayName=\u30c9\u30e1\u30a4\u30f3
|
||||
CorrelationType.EMAIL.displayName=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9
|
||||
CorrelationType.FILES.displayName=\u30d5\u30a1\u30a4\u30eb
|
||||
CorrelationType.ICCID.displayName=ICCID\u756a\u53f7
|
||||
CorrelationType.IMEI.displayName=IMEI\u756a\u53f7
|
||||
CorrelationType.IMSI.displayName=IMSI\u756a\u53f7
|
||||
CorrelationType.MAC.displayName=MAC\u30a2\u30c9\u30ec\u30b9
|
||||
CorrelationType.PHONE.displayName=\u96fb\u8a71\u756a\u53f7
|
||||
CorrelationType.SSID.displayName=\u30ef\u30a4\u30e4\u30ec\u30b9\u30cd\u30c3\u30c8\u30ef\u30fc\u30af
|
||||
CorrelationType.USBID.displayName=USB\u30c7\u30d0\u30a4\u30b9
|
||||
EamArtifactInstances.knownStatus.bad=\u4e0d\u53ef
|
||||
EamArtifactInstances.knownStatus.known=\u65e2\u77e5
|
||||
EamArtifactInstances.knownStatus.unknown=\u4e0d\u660e
|
||||
EamCase.title.caseDisplayName=\u30b1\u30fc\u30b9\u540d\uff1a
|
||||
EamCase.title.caseNumber=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
|
||||
EamCase.title.caseUUID=\u30b1\u30fc\u30b9UUID\uff1a
|
||||
EamCase.title.creationDate=\u4f5c\u6210\u65e5\uff1a
|
||||
EamCase.title.examinerEmail=\u5be9\u67fb\u5b98\u306e\u96fb\u5b50\u30e1\u30fc\u30eb\uff1a
|
||||
EamCase.title.examinerName=\u5be9\u67fb\u5b98\u540d\uff1a
|
||||
EamCase.title.examinerPhone=\u5be9\u67fb\u5b98\u306e\u96fb\u8a71\u756a\u53f7\uff1a
|
||||
EamCase.title.notes=\u30ce\u30fc\u30c8\uff1a
|
||||
EamCase.title.org=\u7d44\u7e54\uff1a
|
||||
EamDbUtil.centralRepoConnectionFailed.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
EamDbUtil.centralRepoDisabled.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u7121\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002
|
||||
EamDbUtil.centralRepoUpgradeFailed.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||
EamDbUtil.exclusiveLockAquisitionFailure.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u6392\u4ed6\u30ed\u30c3\u30af\u304c\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
Persona.defaultName=\u7121\u540d
|
||||
PostgresEamDb.centralRepoDisabled.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002
|
||||
PostgresEamDb.connectionFailed.message=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u63a5\u7d9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
PostgresEamDb.multiUserLockError.message=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30ed\u30c3\u30af\u306e\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||
SqliteEamDb.centralRepositoryDisabled.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002
|
||||
SqliteEamDb.connectionFailedMessage.message=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u63a5\u7d9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
SqliteEamDb.databaseMissing.message=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.datamodel;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber;
|
||||
|
||||
/**
|
||||
* This class updates CR schema to 1.6
|
||||
*
|
||||
*/
|
||||
public class CentralRepoDbUpgrader15To16 implements CentralRepoDbUpgrader {
|
||||
|
||||
@Override
|
||||
public void upgradeSchema(CaseDbSchemaVersionNumber dbSchemaVersion, Connection connection) throws CentralRepoException, SQLException {
|
||||
|
||||
if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 6)) < 0) {
|
||||
|
||||
try (Statement statement = connection.createStatement();) {
|
||||
|
||||
CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform();
|
||||
|
||||
for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) {
|
||||
String instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
|
||||
|
||||
if ((type.getId() == CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID) ||
|
||||
(type.getId() == CorrelationAttributeInstance.OSACCOUNT_TYPE_ID)){
|
||||
|
||||
// these are new Correlation types - new tables need to be created
|
||||
statement.execute(String.format(RdbmsCentralRepoFactory.getCreateAccountInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname));
|
||||
statement.execute(String.format(RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(), instance_type_dbname, instance_type_dbname));
|
||||
statement.execute(String.format(RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(), instance_type_dbname, instance_type_dbname));
|
||||
statement.execute(String.format(RdbmsCentralRepoFactory.getAddValueIndexTemplate(), instance_type_dbname, instance_type_dbname));
|
||||
statement.execute(String.format(RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate(), instance_type_dbname, instance_type_dbname));
|
||||
statement.execute(String.format(RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate(), instance_type_dbname, instance_type_dbname));
|
||||
|
||||
// add new correlation type
|
||||
CentralRepoDbUtil.insertCorrelationType(connection, type);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -257,6 +257,8 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
public static final int IMEI_TYPE_ID = 7;
|
||||
public static final int IMSI_TYPE_ID = 8;
|
||||
public static final int ICCID_TYPE_ID = 9;
|
||||
public static final int INSTALLED_PROGS_TYPE_ID = 10;
|
||||
public static final int OSACCOUNT_TYPE_ID = 11;
|
||||
|
||||
// An offset to assign Ids for additional correlation types.
|
||||
public static final int ADDITIONAL_TYPES_BASE_ID = 1000;
|
||||
@@ -276,7 +278,9 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
"CorrelationType.MAC.displayName=MAC Addresses",
|
||||
"CorrelationType.IMEI.displayName=IMEI Number",
|
||||
"CorrelationType.IMSI.displayName=IMSI Number",
|
||||
"CorrelationType.ICCID.displayName=ICCID Number"})
|
||||
"CorrelationType.PROG_NAME.displayName=Installed Programs",
|
||||
"CorrelationType.ICCID.displayName=ICCID Number",
|
||||
"CorrelationType.OS_ACCOUNT.displayName=Os Account"})
|
||||
public static List<CorrelationAttributeInstance.Type> getDefaultCorrelationTypes() throws CentralRepoException {
|
||||
List<CorrelationAttributeInstance.Type> defaultCorrelationTypes = new ArrayList<>();
|
||||
|
||||
@@ -290,6 +294,8 @@ public class CorrelationAttributeInstance implements Serializable {
|
||||
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(IMEI_TYPE_ID, Bundle.CorrelationType_IMEI_displayName(), "imei_number", true, true)); //NON-NLS
|
||||
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(IMSI_TYPE_ID, Bundle.CorrelationType_IMSI_displayName(), "imsi_number", true, true)); //NON-NLS
|
||||
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(ICCID_TYPE_ID, Bundle.CorrelationType_ICCID_displayName(), "iccid_number", true, true)); //NON-NLS
|
||||
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(INSTALLED_PROGS_TYPE_ID, Bundle.CorrelationType_PROG_NAME_displayName(), "installed_programs", true, true)); //NON-NLS
|
||||
defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(OSACCOUNT_TYPE_ID, Bundle.CorrelationType_OS_ACCOUNT_displayName(), "os_accounts", true, true)); //NON-NLS
|
||||
|
||||
// Create Correlation Types for Accounts.
|
||||
int correlationTypeId = ADDITIONAL_TYPES_BASE_ID;
|
||||
|
||||
+47
-7
@@ -36,6 +36,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.HashUtility;
|
||||
import org.sleuthkit.datamodel.InvalidAccountIDException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
@@ -93,6 +95,7 @@ public class CorrelationAttributeUtil {
|
||||
add(ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_WEB_FORM_ADDRESS.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID());
|
||||
add(ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -189,6 +192,17 @@ public class CorrelationAttributeUtil {
|
||||
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) {
|
||||
makeCorrAttrFromAcctArtifact(correlationAttrs, sourceArtifact);
|
||||
|
||||
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
|
||||
BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH));
|
||||
String pathAttrString = null;
|
||||
if (setNameAttr != null) {
|
||||
pathAttrString = setNameAttr.getValueString();
|
||||
}
|
||||
if (pathAttrString != null && !pathAttrString.isEmpty()) {
|
||||
makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID);
|
||||
} else {
|
||||
makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, CorrelationAttributeInstance.INSTALLED_PROGS_TYPE_ID);
|
||||
}
|
||||
} else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()
|
||||
|| artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
|
||||
@@ -213,7 +227,7 @@ public class CorrelationAttributeUtil {
|
||||
}
|
||||
return correlationAttrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes a correlation attribute instance from a phone number attribute of
|
||||
* an artifact.
|
||||
@@ -381,23 +395,49 @@ public class CorrelationAttributeUtil {
|
||||
private static CorrelationAttributeInstance makeCorrAttr(BlackboardArtifact artifact, CorrelationAttributeInstance.Type correlationType, String value) {
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCaseThrows();
|
||||
AbstractFile bbSourceFile = currentCase.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
|
||||
if (null == bbSourceFile) {
|
||||
logger.log(Level.SEVERE, "Error creating artifact instance. Abstract File was null."); // NON-NLS
|
||||
Content sourceContent = currentCase.getSleuthkitCase().getContentById(artifact.getObjectID());
|
||||
if (null == sourceContent) {
|
||||
logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Failed to load content with ID: {1} associated with artifact with ID: {2}",
|
||||
new Object[]{correlationType.getDisplayName(), artifact.getObjectID(), artifact.getId()}); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
Content ds = sourceContent.getDataSource();
|
||||
if (ds == null) {
|
||||
logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Failed to load data source for content with ID: {1}",
|
||||
new Object[]{correlationType.getDisplayName(), artifact.getObjectID()}); // NON-NLS
|
||||
return null;
|
||||
}
|
||||
|
||||
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
|
||||
return new CorrelationAttributeInstance(
|
||||
if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
|
||||
return new CorrelationAttributeInstance(
|
||||
correlationType,
|
||||
value,
|
||||
correlationCase,
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, ds),
|
||||
"",
|
||||
"",
|
||||
TskData.FileKnown.UNKNOWN,
|
||||
sourceContent.getId());
|
||||
} else {
|
||||
if (! (sourceContent instanceof AbstractFile)) {
|
||||
logger.log(Level.SEVERE, "Error creating artifact instance of type {0}. Source content of artifact with ID: {1} is not an AbstractFile",
|
||||
new Object[]{correlationType.getDisplayName(), artifact.getId()});
|
||||
return null;
|
||||
}
|
||||
AbstractFile bbSourceFile = (AbstractFile) sourceContent;
|
||||
|
||||
return new CorrelationAttributeInstance(
|
||||
correlationType,
|
||||
value,
|
||||
correlationCase,
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, bbSourceFile.getDataSource()),
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, ds),
|
||||
bbSourceFile.getParentPath() + bbSourceFile.getName(),
|
||||
"",
|
||||
TskData.FileKnown.UNKNOWN,
|
||||
bbSourceFile.getId());
|
||||
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error getting querying case database (%s)", artifact), ex); // NON-NLS
|
||||
return null;
|
||||
|
||||
@@ -69,7 +69,7 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
static final String SCHEMA_MINOR_VERSION_KEY = "SCHEMA_MINOR_VERSION";
|
||||
static final String CREATION_SCHEMA_MAJOR_VERSION_KEY = "CREATION_SCHEMA_MAJOR_VERSION";
|
||||
static final String CREATION_SCHEMA_MINOR_VERSION_KEY = "CREATION_SCHEMA_MINOR_VERSION";
|
||||
static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION = new CaseDbSchemaVersionNumber(1, 5);
|
||||
static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION = new CaseDbSchemaVersionNumber(1, 6);
|
||||
|
||||
protected final List<CorrelationAttributeInstance.Type> defaultCorrelationTypes;
|
||||
|
||||
@@ -3976,6 +3976,9 @@ abstract class RdbmsCentralRepo implements CentralRepository {
|
||||
// Upgrade to 1.5
|
||||
(new CentralRepoDbUpgrader14To15()).upgradeSchema(dbSchemaVersion, conn);
|
||||
|
||||
// Upgrade to 1.6
|
||||
(new CentralRepoDbUpgrader15To16()).upgradeSchema(dbSchemaVersion, conn);
|
||||
|
||||
updateSchemaVersion(conn);
|
||||
conn.commit();
|
||||
logger.log(Level.INFO, String.format("Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
|
||||
|
||||
+3
@@ -1,4 +1,7 @@
|
||||
caseeventlistener.evidencetag=Evidence
|
||||
CaseEventsListener.module.name=Central Repository
|
||||
CaseEventsListener.prevCaseComment.text=Users seen in previous cases
|
||||
CaseEventsListener.prevExists.text=Previously Seen Users (Central Repository)
|
||||
CentralRepositoryNotificationDialog.bulletHeader=This data is used to:
|
||||
CentralRepositoryNotificationDialog.bulletOne=Ignore common items (files, domains, and accounts)
|
||||
CentralRepositoryNotificationDialog.bulletThree=Create personas that group accounts
|
||||
|
||||
+7
-1
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
CentralRepositoryNotificationDialog.bulletHeader=\u3053\u306e\u30c7\u30fc\u30bf\u306e\u4f7f\u7528\u76ee\u7684\u306f\uff1a
|
||||
CentralRepositoryNotificationDialog.bulletOne=\u4e00\u822c\u7684\u306a\u30a2\u30a4\u30c6\u30e0\uff08\u30d5\u30a1\u30a4\u30eb\u3001\u30c9\u30e1\u30a4\u30f3\u3001\u30a2\u30ab\u30a6\u30f3\u30c8\uff09\u3092\u7121\u8996\u3059\u308b
|
||||
CentralRepositoryNotificationDialog.bulletThree=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u30da\u30eb\u30bd\u30ca\u3092\u4f5c\u6210\u3059\u308b
|
||||
@@ -6,3 +6,9 @@ CentralRepositoryNotificationDialog.bulletTwo=\u30a2\u30a4\u30c6\u30e0\u304c\u4e
|
||||
CentralRepositoryNotificationDialog.finalRemarks=\u4fdd\u5b58\u3059\u308b\u5185\u5bb9\u3092\u5236\u9650\u3059\u308b\u306b\u306f\u3001\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fb\u30aa\u30d7\u30b7\u30e7\u30f3\u30d1\u30cd\u30eb\u3092\u4f7f\u7528\u3057\u3066\u4e0b\u3055\u3044\u3002
|
||||
CentralRepositoryNotificationDialog.header=Autopsy\u306f\u3001\u5404\u30b1\u30fc\u30b9\u306b\u95a2\u3059\u308b\u30c7\u30fc\u30bf\u3092\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u4fdd\u5b58\u3057\u307e\u3059\u3002
|
||||
IngestEventsListener.ingestmodule.name=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea
|
||||
IngestEventsListener.prevCaseComment.text=\u524d\u306e\u30b1\u30fc\u30b9\uff1a
|
||||
IngestEventsListener.prevCount.text=\u524d\u306e{0}\u306e\u6570\uff1a{1}
|
||||
IngestEventsListener.prevExists.text=\u4ee5\u524d\u898b\u305f\u30c7\u30d0\u30a4\u30b9\uff08\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\uff09
|
||||
IngestEventsListener.prevTaggedSet.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u3068\u3057\u3066\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\uff08\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\uff09
|
||||
Installer.centralRepoUpgradeFailed.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u7121\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002
|
||||
caseeventlistener.evidencetag=\u8a3c\u62e0
|
||||
|
||||
+127
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2017-2020 Basis Technology Corp.
|
||||
* Copyright 2017-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,13 +21,17 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
@@ -37,6 +41,7 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceNameChangedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.OsAcctInstancesAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
@@ -54,8 +59,18 @@ import org.sleuthkit.datamodel.TagName;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||
import org.sleuthkit.datamodel.Tag;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME;
|
||||
import org.sleuthkit.datamodel.OsAccount;
|
||||
import org.sleuthkit.datamodel.OsAccountInstance;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
|
||||
/**
|
||||
* Listen for case events and update entries in the Central Repository database
|
||||
@@ -75,7 +90,8 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
Case.Events.DATA_SOURCE_ADDED,
|
||||
Case.Events.TAG_DEFINITION_CHANGED,
|
||||
Case.Events.CURRENT_CASE,
|
||||
Case.Events.DATA_SOURCE_NAME_CHANGED);
|
||||
Case.Events.DATA_SOURCE_NAME_CHANGED,
|
||||
Case.Events.OS_ACCT_INSTANCES_ADDED);
|
||||
|
||||
public CaseEventListener() {
|
||||
jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build());
|
||||
@@ -130,6 +146,12 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
jobProcessingExecutor.submit(new DataSourceNameChangedTask(dbManager, evt));
|
||||
}
|
||||
break;
|
||||
case OS_ACCT_INSTANCES_ADDED: {
|
||||
if (((AutopsyEvent) evt).getSourceType() == AutopsyEvent.SourceType.LOCAL) {
|
||||
jobProcessingExecutor.submit(new OsAccountInstancesAddedTask(dbManager, evt));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,10 +311,10 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
* Sets the known status for the correlation attribute instance for the
|
||||
* given abstract file.
|
||||
*
|
||||
* @param af The abstract file for which to set the correlation
|
||||
* attribute instance.
|
||||
* @param af The abstract file for which to set the correlation
|
||||
* attribute instance.
|
||||
* @param knownStatus The new known status for the correlation attribute
|
||||
* instance.
|
||||
* instance.
|
||||
*/
|
||||
private void setContentKnownStatus(AbstractFile af, TskData.FileKnown knownStatus) {
|
||||
final CorrelationAttributeInstance eamArtifact = CorrelationAttributeUtil.makeCorrAttrFromFile(af);
|
||||
@@ -385,7 +407,7 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
* for the item. If there are, set known status as notable. If not set
|
||||
* status as unknown.
|
||||
*
|
||||
* @param content The content for the tag that was added or deleted.
|
||||
* @param content The content for the tag that was added or deleted.
|
||||
* @param bbArtifact The artifact for the tag that was added or deleted.
|
||||
*/
|
||||
private void handleTagChange(Content content, BlackboardArtifact bbArtifact) {
|
||||
@@ -430,7 +452,7 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
* Sets the known status of a blackboard artifact in the central
|
||||
* repository.
|
||||
*
|
||||
* @param bbArtifact The blackboard artifact to set known status.
|
||||
* @param bbArtifact The blackboard artifact to set known status.
|
||||
* @param knownStatus The new known status.
|
||||
*/
|
||||
private void setArtifactKnownStatus(BlackboardArtifact bbArtifact, TskData.FileKnown knownStatus) {
|
||||
@@ -635,6 +657,104 @@ public final class CaseEventListener implements PropertyChangeListener {
|
||||
} // CURRENT_CASE
|
||||
}
|
||||
|
||||
@NbBundle.Messages({"CaseEventsListener.module.name=Central Repository",
|
||||
"CaseEventsListener.prevCaseComment.text=Users seen in previous cases",
|
||||
"CaseEventsListener.prevExists.text=Previously Seen Users (Central Repository)"})
|
||||
/**
|
||||
* Add OsAccount Instance to CR and find interesting items based on the OsAccount
|
||||
*/
|
||||
private final class OsAccountInstancesAddedTask implements Runnable {
|
||||
|
||||
private final CentralRepository dbManager;
|
||||
private final PropertyChangeEvent event;
|
||||
private final String MODULE_NAME = Bundle.CaseEventsListener_module_name();
|
||||
|
||||
private OsAccountInstancesAddedTask(CentralRepository db, PropertyChangeEvent evt) {
|
||||
dbManager = db;
|
||||
event = evt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//Nothing to do here if the central repo is not enabled or if ingest is running but is set to not save data/make artifacts
|
||||
if (!CentralRepository.isEnabled()
|
||||
|| (IngestManager.getInstance().isIngestRunning() && !(IngestEventsListener.isFlagSeenDevices() || IngestEventsListener.shouldCreateCrProperties()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
final OsAcctInstancesAddedEvent osAcctInstancesAddedEvent = (OsAcctInstancesAddedEvent) event;
|
||||
List<OsAccountInstance> addedOsAccountNew = osAcctInstancesAddedEvent.getOsAccountInstances();
|
||||
for (OsAccountInstance osAccountInstance : addedOsAccountNew) {
|
||||
try {
|
||||
OsAccount osAccount = osAccountInstance.getOsAccount();
|
||||
Optional<String> accountAddr = osAccount.getAddr();
|
||||
// Check address if it is null or one of the ones below we want to ignore it since they will always be one a windows system
|
||||
// and they are not unique
|
||||
if (!accountAddr.isPresent() || accountAddr.get().equals("S-1-5-18") || accountAddr.get().equals("S-1-5-19") || accountAddr.get().equals("S-1-5-20")) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
||||
CorrelationCase correlationCase = CentralRepository.getInstance().getCase(Case.getCurrentCaseThrows());
|
||||
CorrelationAttributeInstance correlationAttributeInstance = new CorrelationAttributeInstance(
|
||||
CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID),
|
||||
accountAddr.get(),
|
||||
correlationCase,
|
||||
CorrelationDataSource.fromTSKDataSource(correlationCase, osAccountInstance.getDataSource()),
|
||||
"",
|
||||
"",
|
||||
TskData.FileKnown.KNOWN,
|
||||
osAccount.getId());
|
||||
|
||||
// Save to the database if requested
|
||||
if(IngestEventsListener.shouldCreateCrProperties()) {
|
||||
dbManager.addArtifactInstance(correlationAttributeInstance);
|
||||
}
|
||||
|
||||
// Look up and create artifacts for previously seen accounts if requested
|
||||
if (IngestEventsListener.isFlagSeenDevices()) {
|
||||
List<CorrelationAttributeInstance> previousOccurences = dbManager.getArtifactInstancesByTypeValue(CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.OSACCOUNT_TYPE_ID), correlationAttributeInstance.getCorrelationValue());
|
||||
for (CorrelationAttributeInstance instance : previousOccurences) {
|
||||
if (!instance.getCorrelationCase().getCaseUUID().equals(correlationAttributeInstance.getCorrelationCase().getCaseUUID())) {
|
||||
SleuthkitCase tskCase = osAccount.getSleuthkitCase();
|
||||
Blackboard blackboard = tskCase.getBlackboard();
|
||||
|
||||
Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
|
||||
new BlackboardAttribute(
|
||||
TSK_SET_NAME, MODULE_NAME,
|
||||
Bundle.CaseEventsListener_prevExists_text()),
|
||||
new BlackboardAttribute(
|
||||
TSK_COMMENT, MODULE_NAME,
|
||||
Bundle.CaseEventsListener_prevCaseComment_text()));
|
||||
BlackboardArtifact newAnalysisResult = osAccount.newAnalysisResult(
|
||||
BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE,
|
||||
null, Bundle.CaseEventsListener_prevExists_text(), null, attributesForNewArtifact, osAccountInstance.getDataSource().getId()).getAnalysisResult();
|
||||
try {
|
||||
// index the artifact for keyword search
|
||||
blackboard.postArtifact(newAnalysisResult, MODULE_NAME);
|
||||
break;
|
||||
} catch (Blackboard.BlackboardException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + newAnalysisResult.getArtifactID(), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (CentralRepoException ex) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Cannot get central repository for OsAccount: %s.", accountAddr.get()), ex); //NON-NLS
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
|
||||
} catch (CorrelationAttributeNormalizationException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Exception with Correlation Attribute Normalization.", ex); //NON-NLS
|
||||
}
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Cannot get central repository for OsAccount: " + "OsAccount", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class DataSourceNameChangedTask implements Runnable {
|
||||
|
||||
private final CentralRepository dbManager;
|
||||
|
||||
+13
-18
@@ -37,7 +37,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
||||
@@ -63,11 +62,6 @@ import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT;
|
||||
import org.sleuthkit.datamodel.CommunicationsUtils;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
|
||||
/**
|
||||
@@ -76,7 +70,6 @@ import org.sleuthkit.datamodel.Score;
|
||||
*/
|
||||
@NbBundle.Messages({"IngestEventsListener.ingestmodule.name=Central Repository"})
|
||||
public class IngestEventsListener {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CorrelationAttributeInstance.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED);
|
||||
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(DATA_ADDED);
|
||||
@@ -216,17 +209,17 @@ public class IngestEventsListener {
|
||||
@NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
|
||||
"IngestEventsListener.prevCaseComment.text=Previous Case: "})
|
||||
static private void makeAndPostPreviousNotableArtifact(BlackboardArtifact originalArtifact, List<String> caseDisplayNames) {
|
||||
|
||||
Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(new BlackboardAttribute(
|
||||
TSK_SET_NAME, MODULE_NAME,
|
||||
Bundle.IngestEventsListener_prevTaggedSet_text()),
|
||||
Collection<BlackboardAttribute> attributesForNewArtifact = Arrays.asList(
|
||||
new BlackboardAttribute(
|
||||
TSK_SET_NAME, MODULE_NAME,
|
||||
Bundle.IngestEventsListener_prevTaggedSet_text()),
|
||||
new BlackboardAttribute(
|
||||
TSK_COMMENT, MODULE_NAME,
|
||||
Bundle.IngestEventsListener_prevCaseComment_text() + caseDisplayNames.stream().distinct().collect(Collectors.joining(","))),
|
||||
new BlackboardAttribute(
|
||||
TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
|
||||
originalArtifact.getArtifactID()));
|
||||
makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact);
|
||||
makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevTaggedSet_text());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,26 +244,28 @@ public class IngestEventsListener {
|
||||
new BlackboardAttribute(
|
||||
TSK_ASSOCIATED_ARTIFACT, MODULE_NAME,
|
||||
originalArtifact.getArtifactID()));
|
||||
makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact);
|
||||
makeAndPostInterestingArtifact(originalArtifact, attributesForNewArtifact, Bundle.IngestEventsListener_prevExists_text());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Make an interesting item artifact to flag the passed in artifact.
|
||||
*
|
||||
* @param originalArtifact Artifact in current case we want to flag
|
||||
* @param attributesForNewArtifact Attributes to assign to the new
|
||||
* Interesting items artifact
|
||||
* @param configuration The configuration to be specified for the new interesting artifact hit
|
||||
*/
|
||||
private static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection<BlackboardAttribute> attributesForNewArtifact) {
|
||||
private static void makeAndPostInterestingArtifact(BlackboardArtifact originalArtifact, Collection<BlackboardAttribute> attributesForNewArtifact, String configuration) {
|
||||
try {
|
||||
SleuthkitCase tskCase = originalArtifact.getSleuthkitCase();
|
||||
AbstractFile abstractFile = tskCase.getAbstractFileById(originalArtifact.getObjectID());
|
||||
Blackboard blackboard = tskCase.getBlackboard();
|
||||
// Create artifact if it doesn't already exist.
|
||||
if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_ARTIFACT_HIT, attributesForNewArtifact)) {
|
||||
BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult(
|
||||
new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT),
|
||||
Score.SCORE_UNKNOWN, null, null, null, attributesForNewArtifact)
|
||||
BlackboardArtifact newInterestingArtifact = abstractFile.newAnalysisResult(
|
||||
BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT, Score.SCORE_LIKELY_NOTABLE,
|
||||
null, configuration, null, attributesForNewArtifact)
|
||||
.getAnalysisResult();
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
|
||||
IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable
|
||||
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices previously seen in other cases
|
||||
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases
|
||||
IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository
|
||||
|
||||
+1
-1
@@ -11,5 +11,5 @@ CentralRepoIngestModuleFactory.ingestmodule.desc=Saves properties to the central
|
||||
CentralRepoIngestModuleFactory.ingestmodule.name=Central Repository
|
||||
IngestSettingsPanel.ingestSettingsLabel.text=Ingest Settings
|
||||
IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=Flag items previously tagged as notable
|
||||
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices previously seen in other cases
|
||||
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=Flag devices and users previously seen in other cases
|
||||
IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=Save items to the Central Repository
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
CentralRepoIngestModel_name_header=\u540d\u524d\uff1a<br>
|
||||
CentralRepoIngestModel_previous_case_header=<br>\u4ee5\u524d\u306e\u30b1\u30fc\u30b9\uff1a<br>
|
||||
CentralRepoIngestModule.errorMessage.isNotEnabled=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u8a2d\u5b9a\u304c\u521d\u671f\u5316\u3055\u308c\u3066\u304a\u3089\u305a\u3001\u53d6\u308a\u8fbc\u307f\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
CentralRepoIngestModule.notfyBubble.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u521d\u671f\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093
|
||||
CentralRepoIngestModule.prevCaseComment.text=\u524d\u306e\u30b1\u30fc\u30b9\uff1a
|
||||
CentralRepoIngestModule.prevTaggedSet.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u3068\u3057\u3066\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u305f\uff08\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\uff09
|
||||
CentralRepoIngestModuleFactory.ingestmodule.desc=\u8ffd\u3063\u3066\u76f8\u95a2\u7528\u306b\u3001\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u4fdd\u5b58\u3057\u307e\u3059
|
||||
CentralRepoIngestModuleFactory.ingestmodule.name=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea
|
||||
CentralRepoIngestModule_notable_message_header=<html>\u3053\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u5185\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u4ee5\u524d\u300c\u6ce8\u76ee\u300d\u3068\u3057\u3066\u30bf\u30b0\u4ed8\u3051\u3055\u308c\u3066\u3044\u307e\u3059\u3002<br>
|
||||
CentralRepoIngestModule_postToBB_knownBadMsg=\u6ce8\u76ee\uff1a {0}
|
||||
IngestSettingsPanel.createCorrelationPropertiesCheckbox.text=\u30a2\u30a4\u30c6\u30e0\u3092\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u4fdd\u5b58\u3059\u308b
|
||||
IngestSettingsPanel.flagPreviouslySeenDevicesCheckbox.text=\u4ee5\u524d\u306e\u30b1\u30fc\u30b9\u3067\u898b\u3089\u308c\u305f\u30c7\u30d0\u30a4\u30b9\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b
|
||||
IngestSettingsPanel.flagTaggedNotableItemsCheckbox.text=\u4ee5\u524d\u306b\u6ce8\u76ee\u3059\u3079\u304d\u30bf\u30b0\u4ed8\u3051\u305f\u30a2\u30a4\u30c6\u30e0\u306b\u30d5\u30e9\u30b0\u3092\u4ed8\u3051\u308b
|
||||
IngestSettingsPanel.ingestSettingsLabel.text=\u53d6\u8fbc\u307f\u8a2d\u5b9a
|
||||
|
||||
+2
-4
@@ -67,7 +67,6 @@ import org.sleuthkit.datamodel.Score;
|
||||
final class CentralRepoIngestModule implements FileIngestModule {
|
||||
|
||||
private static final String MODULE_NAME = CentralRepoIngestModuleFactory.getModuleName();
|
||||
|
||||
static final boolean DEFAULT_FLAG_TAGGED_NOTABLE_ITEMS = false;
|
||||
static final boolean DEFAULT_FLAG_PREVIOUS_DEVICES = false;
|
||||
static final boolean DEFAULT_CREATE_CR_PROPERTIES = true;
|
||||
@@ -334,7 +333,6 @@ final class CentralRepoIngestModule implements FileIngestModule {
|
||||
* @param caseDisplayNames Case names to be added to a TSK_COMMON attribute.
|
||||
*/
|
||||
private void postCorrelatedBadFileToBlackboard(AbstractFile abstractFile, List<String> caseDisplayNames) {
|
||||
|
||||
Collection<BlackboardAttribute> attributes = Arrays.asList(
|
||||
new BlackboardAttribute(
|
||||
TSK_SET_NAME, MODULE_NAME,
|
||||
@@ -347,8 +345,8 @@ final class CentralRepoIngestModule implements FileIngestModule {
|
||||
// Create artifact if it doesn't already exist.
|
||||
if (!blackboard.artifactExists(abstractFile, TSK_INTERESTING_FILE_HIT, attributes)) {
|
||||
BlackboardArtifact tifArtifact = abstractFile.newAnalysisResult(
|
||||
new BlackboardArtifact.Type(TSK_INTERESTING_FILE_HIT),
|
||||
Score.SCORE_UNKNOWN, null, null, null, attributes)
|
||||
BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT, Score.SCORE_LIKELY_NOTABLE,
|
||||
null, Bundle.CentralRepoIngestModule_prevTaggedSet_text(), null, attributes)
|
||||
.getAnalysisResult();
|
||||
try {
|
||||
// index the artifact for keyword search
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace pref="47" max="32767" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ final class IngestSettingsPanel extends IngestModuleIngestJobSettingsPanel {
|
||||
.addComponent(flagTaggedNotableItemsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(flagPreviouslySeenDevicesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(createCorrelationPropertiesCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
.addContainerGap(47, Short.MAX_VALUE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
|
||||
+2
-1
@@ -39,7 +39,8 @@ GlobalSettingsPanel.askForCentralRepoDbChoice.sqliteChoice.text=Use SQLite
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database.
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL server?
|
||||
# {0} - server name
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use the PostgreSQL server on {0}?
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description2=Any data in an existing SQLite Central Repository will not be transferred to the new database.
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.title=Central Repository
|
||||
GlobalSettingsPanel.testCurrentConfiguration.dbDoesNotExist.message=Database does not exist.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Tue Aug 18 18:09:20 UTC 2020
|
||||
#Mon Jun 14 12:23:19 UTC 2021
|
||||
AddNewOrganizationDialog.addNewOrg.msg=\u65b0\u898f\u7d44\u7e54\u3092\u8ffd\u52a0
|
||||
AddNewOrganizationDialog.bnCancel.text=\u53d6\u308a\u6d88\u3057
|
||||
AddNewOrganizationDialog.bnOK.text=OK
|
||||
@@ -93,9 +93,9 @@ GlobalSettingsPanel.manageOrganizationButton.text=\u7d44\u7e54\u3092\u7ba1\u7406
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.description=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306f\u30ed\u30fc\u30ab\u30ebSQLite\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u3057\u3066\u518d\u69cb\u6210\u3055\u308c\u307e\u3059
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=[PostgreSQL\u306e\u69cb\u6210]\u3092\u62bc\u3057\u3066\u3001PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u5909\u66f4\u3057\u307e\u3059\u3002
|
||||
GlobalSettingsPanel.onMultiUserChange.disabledMu.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306e\u5909\u66f4\u304c\u5fc5\u8981\u3067\u3059
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description=\u3053\u306ePostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f7f\u7528\u3059\u308b\u3088\u3046\u306b\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description2=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u306b\u306f\u904e\u53bb\u306e\u30b1\u30fc\u30b9\u304b\u3089\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3068\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u4fdd\u5b58\u3055\u308c\u307e\u3059\u3002
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u30fc\u3067\u4f7f\u7528\u3057\u307e\u3059\u304b\uff1f
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description=\u3053\u306ePostgreSQL\u30b5\u30fc\u30d0\u30fc\u3092\u4f7f\u7528\u3059\u308b\u3088\u3046\u306b\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.description2=\u65e2\u5b58\u306eSQLite\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30c7\u30fc\u30bf\u306f\u65b0\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u8ee2\u9001\u3055\u308c\u307e\u305b\u3093\u3002
|
||||
GlobalSettingsPanel.onMultiUserChange.enable.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea
|
||||
GlobalSettingsPanel.organizationPanel.border.title=\u7d44\u7e54
|
||||
GlobalSettingsPanel.organizationTextArea.text=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u5185\u3067\u7d44\u7e54\u60c5\u5831\u3092\u8ffd\u8de1\u3067\u304d\u307e\u3059\u3002
|
||||
GlobalSettingsPanel.pnCorrelationProperties.border.title=\u76f8\u95a2\u5206\u6790\u30d7\u30ed\u30d1\u30c6\u30a3
|
||||
|
||||
+6
-2
@@ -47,6 +47,7 @@ import java.util.logging.Level;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.openide.util.ImageUtilities;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresSettingsLoader;
|
||||
|
||||
|
||||
|
||||
@@ -152,7 +153,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"GlobalSettingsPanel.onMultiUserChange.enable.title=Central Repository",
|
||||
"GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL server?",
|
||||
"# {0} - server name",
|
||||
"GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use the PostgreSQL server on {0}?",
|
||||
"GlobalSettingsPanel.onMultiUserChange.enable.description2=Any data in an existing SQLite Central Repository will not be transferred to the new database."
|
||||
})
|
||||
public static void onMultiUserChange(Component parent, boolean muPreviouslySelected, boolean muCurrentlySelected) {
|
||||
@@ -161,10 +163,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
|
||||
|
||||
if (!muPreviouslySelected && muCurrentlySelected) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
PostgresCentralRepoSettings multiUserSettings
|
||||
= new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER);
|
||||
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent,
|
||||
"<html><body>"
|
||||
+ "<div style='width: 400px;'>"
|
||||
+ "<p>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description() + "</p>"
|
||||
+ "<p>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description(multiUserSettings.getHost()) + "</p>"
|
||||
+ "<p style='margin-top: 10px'>" + Bundle.GlobalSettingsPanel_onMultiUserChange_enable_description2() + "</p>"
|
||||
+ "</div>"
|
||||
+ "</body></html>",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AddAliasDialog.accountsLbl.text=\u30a2\u30ab\u30a6\u30f3\u30c8\uff1a
|
||||
AddAliasDialog.cancelBtn.text=\u30ad\u30e3\u30f3\u30bb\u30eb
|
||||
AddAliasDialog.okBtn.text=OK
|
||||
@@ -17,6 +17,7 @@ CreatePersonaAccountDialog.title.text=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f5c
|
||||
CreatePersonaAccountDialog.typeLbl.text=\u30bf\u30a4\u30d7\uff1a
|
||||
CreatePersonaAccountDialog_error_msg=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
|
||||
CreatePersonaAccountDialog_error_title=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30a8\u30e9\u30fc
|
||||
CreatePersonaAccountDialog_invalid_account_Title=\u30a2\u30ab\u30a6\u30f3\u30c8\u8b58\u5225\u5b50\u304c\u7121\u52b9\u3067\u3059
|
||||
CreatePersonaAccountDialog_invalid_account_msg=\u30a2\u30ab\u30a6\u30f3\u30c8\u8b58\u5225\u5b50\u304c\u7121\u52b9\u3067\u3059\u3002
|
||||
CreatePersonaAccountDialog_success_msg=\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
|
||||
CreatePersonaAccountDialog_success_title=\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.invalidPath.text=\u30d1\u30b9\u306f\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093
|
||||
CommandLineIngestSettingPanel_empty_report_name_mgs=\u30ec\u30dd\u30fc\u30c8\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u540d\u306f\u7a7a\u767d\u306a\u306e\u3067\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306f\u4f5c\u6210\u3057\u307e\u305b\u3093\u3002
|
||||
CommandLineIngestSettingPanel_existing_report_name_mgs=\u30ec\u30dd\u30fc\u30c8\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u540d\u306f\u3059\u3067\u306b\u5b58\u5728\u3059\u308b\u306e\u3067\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306f\u4f5c\u6210\u3057\u307e\u305b\u3093\u3002
|
||||
@@ -8,7 +8,9 @@ CommandLineIngestSettingsPanel.ResultsDirectoryUnspecified=\u51fa\u529b\u30d5\u3
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.text=\u8a2d\u5b9a
|
||||
CommandLineIngestSettingsPanel.bnEditIngestSettings.toolTipText=\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u51e6\u7406\u30e2\u30fc\u30c9\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u3067\u3059\u3002
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.AccessibleContext.accessibleName=\u8a2d\u5b9a
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.actionCommand=\u30ec\u30dd\u30fc\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u8a2d\u5b9a
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.text=\u8a2d\u5b9a
|
||||
CommandLineIngestSettingsPanel.bnEditReportSettings.toolTipText=\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u51e6\u7406\u30e2\u30fc\u30c9\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u8a2d\u5b9a\u3002
|
||||
CommandLineIngestSettingsPanel.browseOutputFolderButton.text=\u53c2\u7167
|
||||
CommandLineIngestSettingsPanel.ingestDescriptionTextPane.text=\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u304b\u3089\u4f7f\u7528\u3059\u308b\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002
|
||||
CommandLineIngestSettingsPanel.ingestProfileLabel.text=\u53d6\u8fbc\u307f\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\uff1a
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018-2019 Basis Technology Corp.
|
||||
* Copyright 2018-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -60,7 +60,7 @@ public final class InstanceCountNode extends DisplayableItemNode {
|
||||
"InstanceCountNode.displayName=Exists in %s data sources (%s)"
|
||||
})
|
||||
public InstanceCountNode(int instanceCount, CommonAttributeValueList attributeValues, CorrelationAttributeInstance.Type type) {
|
||||
super(Children.create(new CommonAttributeValueNodeFactory(attributeValues.getMetadataList(), type), false));
|
||||
super(Children.create(new CommonAttributeValueNodeFactory(attributeValues.getMetadataList(), type), true));
|
||||
this.type = type;
|
||||
this.instanceCount = instanceCount;
|
||||
this.attributeValues = attributeValues;
|
||||
|
||||
@@ -128,8 +128,10 @@ public final class InterCasePanel extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
for (CorrelationAttributeInstance.Type type : types) {
|
||||
correlationTypeFilters.put(type.getDisplayName(), type);
|
||||
this.correlationTypeComboBox.addItem(type.getDisplayName());
|
||||
if (! type.getDbTableName().contains("os_account") && ! type.getDbTableName().contains("installed_program")) {
|
||||
correlationTypeFilters.put(type.getDisplayName(), type);
|
||||
this.correlationTypeComboBox.addItem(type.getDisplayName());
|
||||
}
|
||||
}
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.WARNING, "Error getting correlation types", ex);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AccountInstanceNode_Tooltip_Template=\u9023\u7d61\u5148\uff1a{0}-\u30da\u30eb\u30bd\u30ca\uff1a{1}
|
||||
AccountInstanceNode_Tooltip_suffix=(1 of {0})
|
||||
AccountNode.accountName=\u30a2\u30ab\u30a6\u30f3\u30c8
|
||||
@@ -10,6 +10,8 @@ CVTTopComponent.TabConstraints.tabTitle=\u53ef\u8996\u5316
|
||||
CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=\u53c2\u7167
|
||||
CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=\u53c2\u7167
|
||||
CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=\u53ef\u8996\u5316
|
||||
CVTTopComponent.filterTabPanel.TabConstraints.tabTitle=\u30d5\u30a3\u30eb\u30bf\u30fc
|
||||
CVTTopComponent.filtersPane.TabConstraints.tabTitle=\u30d5\u30a3\u30eb\u30bf\u30fc
|
||||
CVTTopComponent.name=\ \u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u53ef\u8996\u5316
|
||||
CVTTopComponent.vizPanel.TabConstraints.tabTitle=\u53ef\u8996\u5316
|
||||
CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=\u53ef\u8996\u5316
|
||||
@@ -68,6 +70,8 @@ VisualizationPanel.fitZoomButton.text=
|
||||
VisualizationPanel.fitZoomButton.toolTipText=\u53ef\u8996\u5316\u3092\u9069\u5408
|
||||
VisualizationPanel.forwardButton.text=
|
||||
VisualizationPanel.forwardButton.toolTipText=\u30af\u30ea\u30c3\u30af\u3057\u3066\u9032\u3080
|
||||
VisualizationPanel.hierarchyLayoutButton.text=\u968e\u5c64\u7684
|
||||
VisualizationPanel.jButton1.text=Fast Organic
|
||||
VisualizationPanel.jTextPane1.text=[\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u53c2\u7167]\u30c6\u30fc\u30d6\u30eb\u3067\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3001[\u8868\u793a]\u3092\u9078\u629e\u3057\u3066\u958b\u59cb\u3002
|
||||
VisualizationPanel.layoutFail.text={0} \u30ec\u30a4\u30a2\u30a6\u30c8\u304c\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u5225\u306e\u30ec\u30a4\u30a2\u30a6\u30c8\u3092\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002
|
||||
VisualizationPanel.layoutFailWithLockedVertices.text=\u9802\u70b9\u304c\u30ed\u30c3\u30af\u3055\u308c\u305f {0} \u30ec\u30a4\u30a2\u30a6\u30c8\u304c\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u4e00\u90e8\u306e\u9802\u70b9\u306e\u30ed\u30c3\u30af\u3092\u89e3\u9664\u3059\u308b\u304b\u3001\u5225\u306e\u30ec\u30a4\u30a2\u30a6\u30c8\u3092\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002
|
||||
@@ -75,6 +79,7 @@ VisualizationPanel.lockAction.pluralText=\u9078\u629e\u3057\u305f\u30a2\u30ab\u3
|
||||
VisualizationPanel.lockAction.singularText=\u9078\u629e\u3057\u305f\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30ed\u30c3\u30af
|
||||
VisualizationPanel.organicLayoutButton.text=\u6709\u6a5f\u7684
|
||||
VisualizationPanel.snapshotButton.text_1=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30fb\u30ec\u30dd\u30fc\u30c8
|
||||
VisualizationPanel.snapshotButton.toolTipText=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30ec\u30dd\u30fc\u30c8
|
||||
VisualizationPanel.unlockAction.pluralText=\u9078\u629e\u3057\u305f\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30ed\u30c3\u30af\u3092\u89e3\u9664
|
||||
VisualizationPanel.unlockAction.singularText=\u9078\u629e\u3057\u305f\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30ed\u30c3\u30af
|
||||
VisualizationPanel.zoomActualButton.text=
|
||||
@@ -84,6 +89,7 @@ VisualizationPanel.zoomInButton.toolTipText=\u30ba\u30fc\u30e0\u30a4\u30f3
|
||||
VisualizationPanel.zoomLabel.text=100%
|
||||
VisualizationPanel.zoomOutButton.text=
|
||||
VisualizationPanel.zoomOutButton.toolTipText=\u30ba\u30fc\u30e0\u30a2\u30a6\u30c8
|
||||
VisualizationPanel.zoomPercentLabel.text=100%
|
||||
VisualizationPanel_action_dialogs_title=\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3
|
||||
VisualizationPanel_action_name_text=\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30fb\u30ec\u30dd\u30fc\u30c8
|
||||
VisualizationPanel_module_name=\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017-2018 Basis Technology Corp.
|
||||
* Copyright 2017-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -70,7 +70,6 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.logging.Level;
|
||||
@@ -583,30 +582,14 @@ final public class VisualizationPanel extends JPanel {
|
||||
|
||||
ModalDialogProgressIndicator progressIndicator = new ModalDialogProgressIndicator(windowAncestor, Bundle.VisualizationPanel_computingLayout());
|
||||
progressIndicator.start(Bundle.VisualizationPanel_computingLayout());
|
||||
|
||||
new SwingWorker<Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground() {
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
layout.execute(graph.getDefaultParent());
|
||||
fitGraph();
|
||||
} finally {
|
||||
graph.getModel().endUpdate();
|
||||
progressIndicator.finish();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.WARNING, "CVT graph layout failed.", ex);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
layout.execute(graph.getDefaultParent());
|
||||
fitGraph();
|
||||
} finally {
|
||||
graph.getModel().endUpdate();
|
||||
progressIndicator.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
CallLogViewer_device_label=\u30c7\u30d0\u30a4\u30b9
|
||||
CallLogViewer_duration_label=\u671f\u9593\uff08\u79d2\uff09
|
||||
CallLogViewer_noCallLogs=<\u9078\u629e\u3057\u305f\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u901a\u8a71\u30ed\u30b0\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093>
|
||||
CallLogViewer_recipient_label=\u5b9b\u5148/\u53d7\u4fe1
|
||||
CallLogViewer_title=\u30b3\u30fc\u30eb\u30ed\u30b0
|
||||
ContactDetailsPane.nameLabel.text=\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u30fc
|
||||
ContactNode_Email=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9
|
||||
ContactNode_Home_Number=\u81ea\u5b85\u96fb\u8a71\u756a\u53f7
|
||||
@@ -46,6 +51,10 @@ SummaryPersonaPane.createButton.text=\u4f5c\u6210
|
||||
SummaryPersonaPane.messageLabel.text=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u4f5c\u6210\u304a\u3088\u3073\u8868\u793a\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b>
|
||||
SummaryPersonaPane.noPersonaLabel.text=\u30da\u30eb\u30bd\u30ca\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
|
||||
SummaryPersonaPane_not_account_in_cr=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u3067\u8b58\u5225\u5b50{0}\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002
|
||||
SummaryViewer.accountCountry.text=<\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u56fd>
|
||||
SummaryViewer.accountLabel.text=<\u30a2\u30ab\u30a6\u30f3\u30c8\u540d>
|
||||
SummaryViewer.accoutDescriptionLabel.text=<\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8aac\u660e>
|
||||
SummaryViewer.attachmentDataLabel.text=\u30ab\u30a6\u30f3\u30c8
|
||||
SummaryViewer.attachmentsDataLabel.text=\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb
|
||||
SummaryViewer.attachmentsLabel.text=\u30e1\u30c7\u30a3\u30a2\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\:
|
||||
SummaryViewer.callLogsDataLabel.text=callLogs
|
||||
@@ -53,18 +62,28 @@ SummaryViewer.callLogsLabel.text=\u901a\u8a71\u30ed\u30b0\:
|
||||
SummaryViewer.caseReferencesPanel.border.title=\u305d\u306e\u4ed6\u306e\u767a\u751f
|
||||
SummaryViewer.contactsDataLabel.text=\u9023\u7d61\u5148
|
||||
SummaryViewer.contactsLabel.text=\u9023\u7d61\u5148\:
|
||||
SummaryViewer.contanctsPanel.border.title=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u9023\u7d61\u5148
|
||||
SummaryViewer.countsPanel.border.title=\u30ab\u30a6\u30f3\u30c8
|
||||
SummaryViewer.fileRefPane.border.title=\u73fe\u30b1\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u53c2\u7167
|
||||
SummaryViewer.messagesDataLabel.text=\u30e1\u30c3\u30bb\u30fc\u30b8
|
||||
SummaryViewer.messagesLabel.text=\u30e1\u30c3\u30bb\u30fc\u30b8\:
|
||||
SummaryViewer.personaPanel.border.title=\u30da\u30eb\u30bd\u30ca
|
||||
SummaryViewer.referencesDataLabel.text=<\u53c2\u7167\u30ab\u30a6\u30f3\u30c8>
|
||||
SummaryViewer.referencesLabel.text=\u901a\u4fe1\u30ea\u30d5\u30a1\u30ec\u30f3\u30b9\uff1a
|
||||
SummaryViewer.selectAccountFileRefLabel.text=<\u30d5\u30a1\u30a4\u30eb\u53c2\u7167\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u5358\u4e00\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044>
|
||||
SummaryViewer.thumbnailCntLabel.text=\u30e1\u30c7\u30a3\u30a2\u306e\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\uff1a
|
||||
SummaryViewer.thumbnailsDataLabel.text=\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb
|
||||
SummaryViewer_Account_Description=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306f\u3001\u30b1\u30fc\u30b9\u5185\u306e\u30c7\u30d0\u30a4\u30b9\u3092\u8868\u3057\u307e\u3059\u3002
|
||||
SummaryViewer_Account_Description_MuliSelect=\u8907\u6570\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u3001\u6982\u8981\u60c5\u5831\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
SummaryViewer_CaseRefNameColumn_Title=\u30b1\u30fc\u30b9\u540d
|
||||
SummaryViewer_CentralRepository_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ec\u30dd\u30b8\u30c8\u30ea\u30fc\u3092\u6709\u52b9\u5316\u3057\u3066\u305d\u306e\u4ed6\u306e\u767a\u751f\u3092\u8868\u793a>
|
||||
SummaryViewer_Country_Code=\u56fd\uff1a
|
||||
SummaryViewer_Creation_Date_Title=\u4f5c\u6210\u65e5
|
||||
SummaryViewer_Device_Account_Description=\u3053\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u306f\u3001\u30b1\u30fc\u30b9\u5185\u306e\u30c7\u30d0\u30a4\u30b9\u306b\u3088\u3063\u3066\u53c2\u7167\u3055\u308c\u307e\u3057\u305f\u3002
|
||||
SummaryViewer_Fetching_References=<\u30d5\u30a1\u30a4\u30eb\u53c2\u7167\u306e\u53d6\u5f97>
|
||||
SummaryViewer_FileRefNameColumn_Title=\u30d1\u30b9
|
||||
SummaryViewer_Persona_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u53ef\u80fd\u306b\u3059\u308b>
|
||||
SummaryViewer_FileRef_Message=<\u30d5\u30a1\u30a4\u30eb\u53c2\u7167\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u5358\u4e00\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044>
|
||||
SummaryViewer_Persona_CR_Message=<\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b>
|
||||
SummaryViewer_Select_account_for_persona=<\u30da\u30eb\u30bd\u30ca\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044>
|
||||
SummaryViewer_TabTitle=\u30b5\u30de\u30ea\u30fc
|
||||
SummeryViewer_FileRef_Message=<\u30a2\u30ab\u30a6\u30f3\u30c8\u30921\u3064\u9078\u629e\u3057\u3066\u30d5\u30a1\u30a4\u30eb\u30ec\u30d5\u30a1\u30ec\u30f3\u30b9\u3092\u8868\u793a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -119,9 +119,9 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
|
||||
updateOutlineViewPanel();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
TableColumn column = outline.getColumnModel().getColumn(2);
|
||||
column.setCellRenderer(new NodeTableCellRenderer() );
|
||||
column.setCellRenderer(new NodeTableCellRenderer());
|
||||
|
||||
}
|
||||
|
||||
@@ -164,7 +164,9 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
|
||||
|
||||
@Override
|
||||
public void setSelectionInfo(SelectionInfo info) {
|
||||
callLogDataViewer.setNode(null);
|
||||
nodeFactory.refresh(info);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,7 +231,7 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane bottomScrollPane;
|
||||
private org.sleuthkit.autopsy.communications.relationships.OutlineViewPanel outlineViewPanel;
|
||||
|
||||
+12
-8
@@ -35,7 +35,8 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
/**
|
||||
* ChildFactory for ContactNodes.
|
||||
*/
|
||||
final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
||||
final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact> {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ContactsChildNodeFactory.class.getName());
|
||||
|
||||
private SelectionInfo selectionInfo;
|
||||
@@ -47,12 +48,13 @@ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
||||
* accounts
|
||||
*/
|
||||
ContactsChildNodeFactory(SelectionInfo selectionInfo) {
|
||||
this.selectionInfo = selectionInfo;
|
||||
this.selectionInfo = selectionInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the current instance of selectionInfo and calls the refresh method.
|
||||
*
|
||||
* Updates the current instance of selectionInfo and calls the refresh
|
||||
* method.
|
||||
*
|
||||
* @param selectionInfo New instance of the currently selected accounts
|
||||
*/
|
||||
public void refresh(SelectionInfo selectionInfo) {
|
||||
@@ -63,13 +65,15 @@ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
||||
/**
|
||||
* Creates a list of Keys (BlackboardArtifact) for only contacts of the
|
||||
* currently selected accounts
|
||||
*
|
||||
* @param list List of BlackboardArtifact to populate
|
||||
*
|
||||
* @return True on success
|
||||
*/
|
||||
@Override
|
||||
protected boolean createKeys(List<BlackboardArtifact> list) {
|
||||
|
||||
if(selectionInfo == null) {
|
||||
|
||||
if (selectionInfo == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,7 +84,7 @@ final class ContactsChildNodeFactory extends ChildFactory<BlackboardArtifact>{
|
||||
logger.log(Level.SEVERE, "Failed to load relationship sources.", ex); //NON-NLS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
|
||||
|
||||
BlackboardArtifact bba = (BlackboardArtifact) content;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -35,7 +35,6 @@ import org.openide.nodes.NodeAdapter;
|
||||
import org.openide.nodes.NodeMemberEvent;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||
@@ -126,6 +125,7 @@ final class ContactsViewer extends JPanel implements RelationshipsViewer {
|
||||
|
||||
@Override
|
||||
public void setSelectionInfo(SelectionInfo info) {
|
||||
contactPane.setNode(null);
|
||||
nodeFactory.refresh(info);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -99,18 +99,19 @@ final class MediaViewer extends JPanel implements RelationshipsViewer, ExplorerM
|
||||
public void setSelectionInfo(SelectionInfo info) {
|
||||
Set<Content> relationshipSources;
|
||||
Set<BlackboardArtifact> artifactList = new HashSet<>();
|
||||
contentViewer.setNode(null);
|
||||
if (info != null) {
|
||||
try {
|
||||
relationshipSources = info.getRelationshipSources();
|
||||
|
||||
try {
|
||||
relationshipSources = info.getRelationshipSources();
|
||||
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
|
||||
artifactList.add((BlackboardArtifact) content);
|
||||
});
|
||||
|
||||
relationshipSources.stream().filter((content) -> (content instanceof BlackboardArtifact)).forEachOrdered((content) -> {
|
||||
artifactList.add((BlackboardArtifact) content);
|
||||
});
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to update selection.", ex);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to update selection.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
thumbnailViewer.resetComponent();
|
||||
|
||||
thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new AttachmentThumbnailsChildren(artifactList)), tableEM), true, this.getClass().getName()));
|
||||
|
||||
+9
-12
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications.relationships;
|
||||
|
||||
import java.awt.Component;
|
||||
import javax.swing.JPanel;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.communications.ModifiableProxyLookup;
|
||||
@@ -37,15 +36,15 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider
|
||||
*/
|
||||
public RelationshipBrowser() {
|
||||
initComponents();
|
||||
|
||||
|
||||
MessageViewer messagesViewer = new MessageViewer();
|
||||
ContactsViewer contactsViewer = new ContactsViewer();
|
||||
SummaryViewer summaryViewer = new SummaryViewer();
|
||||
MediaViewer mediaViewer = new MediaViewer();
|
||||
CallLogViewer callLogViewer = new CallLogViewer();
|
||||
|
||||
|
||||
proxyLookup = new ModifiableProxyLookup(messagesViewer.getLookup());
|
||||
|
||||
|
||||
tabPane.add(summaryViewer.getDisplayName(), summaryViewer);
|
||||
tabPane.add(messagesViewer.getDisplayName(), messagesViewer);
|
||||
tabPane.add(callLogViewer.getDisplayName(), callLogViewer);
|
||||
@@ -95,13 +94,11 @@ public final class RelationshipBrowser extends JPanel implements Lookup.Provider
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void tabPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabPaneStateChanged
|
||||
if(currentSelection != null) {
|
||||
((RelationshipsViewer) tabPane.getSelectedComponent()).setSelectionInfo(currentSelection);
|
||||
}
|
||||
|
||||
Component selectedComponent = tabPane.getSelectedComponent();
|
||||
if(selectedComponent instanceof Lookup.Provider) {
|
||||
Lookup lookup = ((Lookup.Provider)selectedComponent).getLookup();
|
||||
RelationshipsViewer viewer = ((RelationshipsViewer) tabPane.getSelectedComponent());
|
||||
//clear old values
|
||||
viewer.setSelectionInfo(currentSelection);
|
||||
if (viewer instanceof Lookup.Provider) {
|
||||
Lookup lookup = viewer.getLookup();
|
||||
proxyLookup.setNewLookups(lookup);
|
||||
}
|
||||
}//GEN-LAST:event_tabPaneStateChanged
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018-2020 Basis Technology Corp.
|
||||
* Copyright 2018-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,10 +21,7 @@ package org.sleuthkit.autopsy.contentviewers;
|
||||
import java.awt.Component;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.text.EditorKit;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
|
||||
import static org.openide.util.NbBundle.Messages;
|
||||
import org.openide.nodes.Node;
|
||||
@@ -36,6 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.contentviewers.application.Annotations;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||
|
||||
/**
|
||||
* Annotations view of file contents.
|
||||
@@ -48,33 +46,6 @@ import org.jsoup.nodes.Document;
|
||||
"AnnotationsContentViewer.onEmpty=No annotations were found for this particular item."
|
||||
})
|
||||
public class AnnotationsContentViewer extends javax.swing.JPanel implements DataContentViewer {
|
||||
|
||||
private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize();
|
||||
|
||||
// how big the subheader should be
|
||||
private static final int SUBHEADER_FONT_SIZE = DEFAULT_FONT_SIZE * 12 / 11;
|
||||
|
||||
// how big the header should be
|
||||
private static final int HEADER_FONT_SIZE = DEFAULT_FONT_SIZE * 14 / 11;
|
||||
|
||||
// the subsection indent
|
||||
private static final int DEFAULT_SUBSECTION_LEFT_PAD = DEFAULT_FONT_SIZE;
|
||||
|
||||
// spacing occurring after an item
|
||||
private static final int DEFAULT_SECTION_SPACING = DEFAULT_FONT_SIZE * 2;
|
||||
private static final int DEFAULT_SUBSECTION_SPACING = DEFAULT_FONT_SIZE / 2;
|
||||
private static final int CELL_SPACING = DEFAULT_FONT_SIZE / 2;
|
||||
|
||||
// additional styling for components
|
||||
private static final String STYLE_SHEET_RULE
|
||||
= String.format(" .%s { font-size: %dpx;font-style:italic; margin: 0px; padding: 0px; } ", Annotations.MESSAGE_CLASSNAME, DEFAULT_FONT_SIZE)
|
||||
+ String.format(" .%s {font-size:%dpx;font-weight:bold; margin: 0px; margin-top: %dpx; padding: 0px; } ",
|
||||
Annotations.SUBHEADER_CLASSNAME, SUBHEADER_FONT_SIZE, DEFAULT_SUBSECTION_SPACING)
|
||||
+ String.format(" .%s { font-size:%dpx;font-weight:bold; margin: 0px; padding: 0px; } ", Annotations.HEADER_CLASSNAME, HEADER_FONT_SIZE)
|
||||
+ String.format(" td { vertical-align: top; font-size:%dpx; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px;} ", DEFAULT_FONT_SIZE, CELL_SPACING)
|
||||
+ String.format(" th { vertical-align: top; text-align: left; margin: 0px; padding: 0px %dpx 0px 0px} ", DEFAULT_FONT_SIZE, CELL_SPACING)
|
||||
+ String.format(" .%s { margin: %dpx 0px; padding-left: %dpx; } ", Annotations.SUBSECTION_CLASSNAME, DEFAULT_SUBSECTION_SPACING, DEFAULT_SUBSECTION_LEFT_PAD)
|
||||
+ String.format(" .%s { margin-bottom: %dpx; } ", Annotations.SECTION_CLASSNAME, DEFAULT_SECTION_SPACING);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(AnnotationsContentViewer.class.getName());
|
||||
@@ -86,13 +57,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
*/
|
||||
public AnnotationsContentViewer() {
|
||||
initComponents();
|
||||
Utilities.configureTextPaneAsHtml(textPanel);
|
||||
// get html editor kit and apply additional style rules
|
||||
EditorKit editorKit = textPanel.getEditorKit();
|
||||
if (editorKit instanceof HTMLEditorKit) {
|
||||
HTMLEditorKit htmlKit = (HTMLEditorKit) editorKit;
|
||||
htmlKit.getStyleSheet().addRule(STYLE_SHEET_RULE);
|
||||
}
|
||||
ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,25 +130,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Node node) {
|
||||
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
|
||||
|
||||
try {
|
||||
if (artifact != null) {
|
||||
if (artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()) != null) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (node.getLookup().lookup(AbstractFile.class) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format(
|
||||
"Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).",
|
||||
artifact.getDisplayName(), artifact.getArtifactID()), ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
return node != null && node.getLookup().lookup(AbstractFile.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -223,7 +170,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
if(doc != null) {
|
||||
return doc.html();
|
||||
} else {
|
||||
return Bundle.AnnotationsContentViewer_onEmpty();
|
||||
return "<span class='" + ContentViewerHtmlStyles.getMessageClassName() + "'>" + Bundle.AnnotationsContentViewer_onEmpty() + "</span>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,6 +182,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data
|
||||
|
||||
try {
|
||||
String text = get();
|
||||
ContentViewerHtmlStyles.setStyles(textPanel);
|
||||
textPanel.setText(text);
|
||||
textPanel.setCaretPosition(0);
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
|
||||
@@ -70,6 +70,7 @@ MediaViewVideoPanel.progressLabel.text=00:00
|
||||
MediaViewVideoPanel.infoLabel.text=info
|
||||
MediaViewImagePanel.imgFileTooLarge.msg=Could not load image file (too large): {0}
|
||||
|
||||
Metadata.headerTitle=Metadata
|
||||
Metadata.nodeText.loading=Metadata loading...
|
||||
Metadata.nodeText.none=None
|
||||
Metadata.nodeText.truncated=(results truncated)
|
||||
@@ -105,6 +106,8 @@ Metadata.nodeText.exceptionNotice.text=Error getting file metadata:
|
||||
MessageArtifactViewer.textbodyScrollPane.TabConstraints.tabTitle=Text
|
||||
JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file:
|
||||
JPEGViewerDummy.jTextField1.text=jTextField1
|
||||
Metadata_dataArtifactTitle=Source File Metadata
|
||||
MetadataWorker.doInBackground.noDataMsg=No Data
|
||||
PDFViewer.encryptedDialog=This document is password protected.
|
||||
PDFViewer.errorDialog=An error occurred while opening this PDF document. Check the logs for more information. You may continue to use this feature on other PDF documents.
|
||||
PListNode.KeyCol=Key
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
#Fri Feb 12 16:56:28 UTC 2021
|
||||
AnnotationsContentViewer.centralRepositoryEntry.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b3\u30e1\u30f3\u30c8
|
||||
AnnotationsContentViewer.centralRepositoryEntryDataLabel.case=\u30b1\u30fc\u30b9\:
|
||||
AnnotationsContentViewer.centralRepositoryEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\:
|
||||
AnnotationsContentViewer.centralRepositoryEntryDataLabel.path=\u30d1\u30b9\:
|
||||
AnnotationsContentViewer.centralRepositoryEntryDataLabel.type=\u30bf\u30a4\u30d7\:
|
||||
AnnotationsContentViewer.fileHitEntry.artifactCommentTitle=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30b3\u30e1\u30f3\u30c8
|
||||
AnnotationsContentViewer.fileHitEntry.comment=\u30b3\u30e1\u30f3\u30c8\uff1a
|
||||
AnnotationsContentViewer.fileHitEntry.hashSetHitTitle=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30fb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8
|
||||
AnnotationsContentViewer.fileHitEntry.interestingFileHitTitle=\u8208\u5473\u6df1\u3044\u30d5\u30a1\u30a4\u30eb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8
|
||||
AnnotationsContentViewer.fileHitEntry.setName=\u30bb\u30c3\u30c8\u540d\uff1a
|
||||
#Mon Jul 12 13:21:59 UTC 2021
|
||||
AnnotationsContentViewer.onEmpty=\u3053\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u6ce8\u91c8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
AnnotationsContentViewer.sourceFile.title=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
|
||||
AnnotationsContentViewer.tagEntry.title=\u30bf\u30b0
|
||||
AnnotationsContentViewer.tagEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\:
|
||||
AnnotationsContentViewer.tagEntryDataLabel.tag=\u30bf\u30b0\:
|
||||
AnnotationsContentViewer.tagEntryDataLabel.tagUser=\u5be9\u67fb\u5b98\uff1a
|
||||
AnnotationsContentViewer.title=\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3
|
||||
AnnotationsContentViewer.toolTip=\u9078\u629e\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8\u3092\u8868\u793a\u3057\u307e\u3059\u3002
|
||||
ApplicationContentViewer.title=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3
|
||||
@@ -43,6 +28,7 @@ GstVideoPanel.setupVideo.infoLabel.text=\u524a\u9664\u3057\u305f\u52d5\u753b\u30
|
||||
HtmlPanel.showImagesToggleButton.text=\u30a4\u30e1\u30fc\u30b8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9
|
||||
HtmlPanel_showImagesToggleButton_hide=\u30a4\u30e1\u30fc\u30b8\u3092\u975e\u8868\u793a\u306b\u3059\u308b
|
||||
HtmlPanel_showImagesToggleButton_show=\u30a4\u30e1\u30fc\u30b8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9
|
||||
HtmlViewer_encoding_error=\u3059\u3079\u3066\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u8868\u793a
|
||||
HtmlViewer_file_error=\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u898b\u3064\u304b\u3089\u306a\u3044\u304b\u3001\u89e3\u8aad\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
Html_text_display_error=HTML\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a\u3067\u304d\u307e\u305b\u3093\u3002 \u6b63\u3057\u304f\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3055\u308c\u305fHTML\u3067\u306a\u3044\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002
|
||||
JPEGViewerDummy.jLabel1.text=JPEG\u30d5\u30a1\u30a4\u30eb\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u307e\u3059\:
|
||||
@@ -55,6 +41,7 @@ MediaPlayerPanel.VolumeIcon.text=\ \u30dc\u30ea\u30e5\u30fc\u30e0
|
||||
MediaPlayerPanel.audioSlider.toolTipText=
|
||||
MediaPlayerPanel.infoLabel.text=\u30a8\u30e9\u30fc\u306a\u3057
|
||||
MediaPlayerPanel.noSupport=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30d5\u30a1\u30a4\u30eb\u3067\u3059\u3002
|
||||
MediaPlayerPanel.playBackSpeedLabel.text=\u901f\u5ea6\uff1a
|
||||
MediaPlayerPanel.playButton.text=\u25ba
|
||||
MediaPlayerPanel.playbackDisabled=\u30d3\u30c7\u30aa\u3068\u30aa\u30fc\u30c7\u30a3\u30aa\u306e\u518d\u751f\u3067\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6b8b\u308a\u306e\u671f\u9593\u3001\u30d3\u30c7\u30aa\u3068\u30aa\u30fc\u30c7\u30a3\u30aa\u306e\u518d\u751f\u306f\u7121\u52b9\u306b\u306a\u308a\u307e\u3059\u3002
|
||||
MediaPlayerPanel.progressLabel.text=00\:00\:00/00\:00\:00
|
||||
@@ -86,6 +73,7 @@ MediaViewVideoPanel.pauseButton.text=\u25ba
|
||||
MediaViewVideoPanel.progressLabel.text=00\:00
|
||||
MessageArtifactViewer.textbodyScrollPane.TabConstraints.tabTitle=\u30c6\u30ad\u30b9\u30c8
|
||||
Metadata.nodeText.exceptionNotice.text=\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\:
|
||||
Metadata.nodeText.loading=\u30e1\u30bf\u30c7\u30fc\u30bf\u306e\u8aad\u8fbc\u4e2d...
|
||||
Metadata.nodeText.nonFilePassedIn=\u30d5\u30a1\u30a4\u30eb\u4ee5\u5916\u306e\u3082\u306e\u304c\u901a\u904e\u3057\u307e\u3057\u305f
|
||||
Metadata.nodeText.none=\u306a\u3057
|
||||
Metadata.nodeText.text=\u9001\u4fe1\u5143\u306eSleuth Kit\u306eistat\u30c4\u30fc\u30eb\:
|
||||
@@ -116,6 +104,7 @@ Metadata.tableRowTitle.timezone=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3
|
||||
Metadata.tableRowTitle.type=\u30bf\u30a4\u30d7
|
||||
Metadata.title=\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf
|
||||
Metadata.toolTip=\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u8868\u793a\u3057\u307e\u3059\u3002
|
||||
Metadata_dataArtifactTitle=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306e\u30e1\u30bf\u30c7\u30fc\u30bf
|
||||
PDFViewer.encryptedDialog=\u3053\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u3067\u4fdd\u8b77\u3055\u308c\u3066\u3044\u307e\u3059\u3002
|
||||
PDFViewer.errorDialog=PDF\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u958b\u304f\u3068\u304d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 \u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u3053\u306e\u6a5f\u80fd\u306f\u3001\u4ed6\u306ePDF\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3067\u5f15\u304d\u7d9a\u304d\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002
|
||||
PListNode.KeyCol=\u30ad\u30fc
|
||||
@@ -227,6 +216,7 @@ viewer.annotation.signature.validation.common.doc.unmodified.label=- \u7f72\u540
|
||||
viewer.annotation.signature.validation.common.identity.unchecked.label=-\u7f72\u540d\u306f\u6709\u52b9\u3067\u3059\u304c\u3001ID\u306e\u5931\u52b9\u3092\u78ba\u8a8d\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
|
||||
viewer.annotation.signature.validation.common.identity.unknown.label=- \u7f72\u540d\u8005\u306eID\u306f\u4e0d\u660e\u3067\u3059\u3001\u30ad\u30fc\u30b9\u30c8\u30a2\u306b\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
|
||||
viewer.annotation.signature.validation.common.identity.valid.label=-\u7f72\u540d\u8005\u306eID\u306f\u6709\u52b9\u3067\u3059
|
||||
viewer.annotation.signature.validation.common.invalid.label=\u7f72\u540d\u304c\u7121\u52b9\u3067\u3059\uff1a
|
||||
viewer.annotation.signature.validation.common.notAvailable.label=\u8a72\u5f53\u306a\u3057
|
||||
viewer.annotation.signature.validation.common.signedBy.label=-{0} {1}\u306b\u3088\u308b\u7f72\u540d
|
||||
viewer.annotation.signature.validation.common.time.embedded.label=-\u7f72\u540d\u306b\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3057\u305f\u304c\u3001\u691c\u8a3c\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f
|
||||
|
||||
@@ -34,6 +34,9 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import static java.util.Objects.nonNull;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javafx.application.Platform;
|
||||
@@ -150,7 +153,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private final JMenuItem exportTagsMenuItem;
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private final JFileChooser exportChooser;
|
||||
private JFileChooser exportChooser;
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private final JFXPanel fxPanel;
|
||||
|
||||
@@ -189,10 +192,10 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||
private Task<Image> readImageFileTask;
|
||||
private volatile ImageTransforms imageTransforms;
|
||||
|
||||
static {
|
||||
ImageIO.scanForPlugins();
|
||||
}
|
||||
|
||||
// Initializing the JFileChooser in a thread to prevent a block on the EDT
|
||||
// see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel
|
||||
private final FutureTask<JFileChooser> futureFileChooser = new FutureTask<>(JFileChooser::new);
|
||||
|
||||
/**
|
||||
* Constructs a media image file viewer implemented as a Swing panel that
|
||||
@@ -210,9 +213,9 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
||||
initComponents();
|
||||
|
||||
imageTransforms = new ImageTransforms(0, 0, true);
|
||||
|
||||
exportChooser = new JFileChooser();
|
||||
exportChooser.setDialogTitle(Bundle.MediaViewImagePanel_fileChooserTitle());
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
executor.execute(futureFileChooser);
|
||||
|
||||
//Build popupMenu when Tags Menu button is pressed.
|
||||
imageTaggingOptions = new JPopupMenu();
|
||||
@@ -1043,6 +1046,18 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
||||
final AbstractFile file = imageFile;
|
||||
tagsGroup.clearFocus();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
|
||||
if(exportChooser == null) {
|
||||
try {
|
||||
exportChooser = futureFileChooser.get();
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
// If something happened with the thread try and
|
||||
// initalized the chooser now
|
||||
logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread");
|
||||
exportChooser = new JFileChooser();
|
||||
}
|
||||
}
|
||||
|
||||
exportChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
//Always base chooser location to export folder
|
||||
exportChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||
<Properties>
|
||||
<Property name="horizontalScrollBarPolicy" type="int" value="32"/>
|
||||
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[610, 52]"/>
|
||||
</Property>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013-2018 Basis Technology Corp.
|
||||
* Copyright 2013-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -20,24 +20,30 @@ package org.sleuthkit.autopsy.contentviewers;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.DataArtifact;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
@@ -49,7 +55,7 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
|
||||
* shows the same data that can also be found in the ResultViewer table, just a
|
||||
* different order and allows the full path to be visible in the bottom area.
|
||||
*/
|
||||
@ServiceProvider(service = DataContentViewer.class, position = 6)
|
||||
@ServiceProvider(service = DataContentViewer.class, position = 4)
|
||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||
public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
|
||||
@@ -63,6 +69,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
public Metadata() {
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,8 +87,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(100, 52));
|
||||
|
||||
jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
|
||||
jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
jScrollPane2.setPreferredSize(new java.awt.Dimension(610, 52));
|
||||
|
||||
jTextPane1.setEditable(false);
|
||||
@@ -116,30 +121,59 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
* selectAllMenuItem.addActionListener(actList);
|
||||
*/
|
||||
|
||||
Utilities.configureTextPaneAsHtml(jTextPane1);
|
||||
}
|
||||
|
||||
private void setText(String str) {
|
||||
jTextPane1.setText("<html><body>" + str + "</body></html>"); //NON-NLS
|
||||
ContentViewerHtmlStyles.setupHtmlJTextPane(jTextPane1);
|
||||
jTextPane1.setText("<html><head></head><body>" + str + "</body></html>"); //NON-NLS
|
||||
}
|
||||
|
||||
private void addHeader(StringBuilder sb, String header, boolean spaced) {
|
||||
sb.append(MessageFormat.format("<div class=\"{0}\"><h1 class=\"{1}\">{2}</h1></div>",
|
||||
(spaced) ? ContentViewerHtmlStyles.getSpacedSectionClassName() : "",
|
||||
ContentViewerHtmlStyles.getHeaderClassName(),
|
||||
header));
|
||||
}
|
||||
|
||||
private void startTable(StringBuilder sb) {
|
||||
sb.append("<table>"); //NON-NLS
|
||||
sb.append(MessageFormat.format("<table class=\"{0}\" valign=\"top\" align=\"left\"><tbody>",
|
||||
ContentViewerHtmlStyles.getIndentedClassName())); //NON-NLS
|
||||
}
|
||||
|
||||
private void endTable(StringBuilder sb) {
|
||||
sb.append("</table>"); //NON-NLS
|
||||
sb.append("</tbody></table>"); //NON-NLS
|
||||
}
|
||||
|
||||
private void addRow(StringBuilder sb, String key, String value) {
|
||||
sb.append("<tr><td valign=\"top\">"); //NON-NLS
|
||||
sb.append(key);
|
||||
sb.append("</td><td>"); //NON-NLS
|
||||
sb.append(value);
|
||||
sb.append("</td></tr>"); //NON-NLS
|
||||
sb.append(MessageFormat.format("<tr><td class=\"{0}\"><span class=\"{1}\">{2}:</span></td><td class=\"{3}\">{4}</td></tr>",
|
||||
ContentViewerHtmlStyles.getKeyColumnClassName(),
|
||||
ContentViewerHtmlStyles.getTextClassName(),
|
||||
EscapeUtil.escapeHtml(key),
|
||||
ContentViewerHtmlStyles.getTextClassName(),
|
||||
EscapeUtil.escapeHtml(value)
|
||||
));
|
||||
}
|
||||
|
||||
private void addMonospacedRow(StringBuilder sb, String key) {
|
||||
sb.append(MessageFormat.format("<tr><td class=\"{0}\"><span class=\"{1}\">{2}</span></td></tr>",
|
||||
ContentViewerHtmlStyles.getKeyColumnClassName(),
|
||||
ContentViewerHtmlStyles.getMonospacedClassName(),
|
||||
EscapeUtil.escapeHtml(key)
|
||||
));
|
||||
}
|
||||
|
||||
private void addRowWithMultipleValues(StringBuilder sb, String key, String[] values) {
|
||||
String[] safeValues = values == null || values.length < 1 ? new String[]{""} : values;
|
||||
|
||||
addRow(sb, key, safeValues[0]);
|
||||
Stream.of(safeValues)
|
||||
.skip(1)
|
||||
.filter(line -> line != null)
|
||||
.forEach(line -> addRow(sb, "", EscapeUtil.escapeHtml(line)));
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"Metadata.headerTitle=Metadata",
|
||||
"Metadata.tableRowTitle.mimeType=MIME Type",
|
||||
"Metadata.nodeText.truncated=(results truncated)",
|
||||
"Metadata.tableRowTitle.sha1=SHA1",
|
||||
@@ -219,8 +253,11 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
if (StringUtils.isEmpty(details)) {
|
||||
details = Bundle.Metadata_nodeText_unknown();
|
||||
}
|
||||
details = details.replaceAll("\n", "<br>");
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.acquisitionDetails"), details);
|
||||
String[] lines = (details != null) ? details.split("\n") : new String[]{""};
|
||||
addRowWithMultipleValues(sb,
|
||||
NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.acquisitionDetails"),
|
||||
lines);
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error reading acquisition details from case database", ex); //NON-NLS
|
||||
}
|
||||
@@ -229,7 +266,19 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return NbBundle.getMessage(this.getClass(), "Metadata.title");
|
||||
return getTitle(null);
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"Metadata_dataArtifactTitle=Source File Metadata"
|
||||
})
|
||||
@Override
|
||||
public String getTitle(Node node) {
|
||||
if (node != null && !node.getLookup().lookupAll(DataArtifact.class).isEmpty()) {
|
||||
return Bundle.Metadata_dataArtifactTitle();
|
||||
} else {
|
||||
return NbBundle.getMessage(this.getClass(), "Metadata.title");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -275,6 +324,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Messages("MetadataWorker.doInBackground.noDataMsg=No Data")
|
||||
@Override
|
||||
protected String doInBackground() throws Exception {
|
||||
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
|
||||
@@ -285,6 +335,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
addHeader(sb, Bundle.Metadata_headerTitle(), false);
|
||||
startTable(sb);
|
||||
|
||||
if (file != null) {
|
||||
@@ -299,10 +350,10 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), Long.toString(file.getSize()));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.fileNameAlloc"), file.getDirFlagAsString());
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.metadataAlloc"), file.getMetaFlagsAsString());
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.modified"), ContentUtils.getStringTime(file.getMtime(), file));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.accessed"), ContentUtils.getStringTime(file.getAtime(), file));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.modified"), TimeZoneUtils.getFormattedTime(file.getMtime()));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.accessed"), TimeZoneUtils.getFormattedTime(file.getAtime()));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), TimeZoneUtils.getFormattedTime(file.getCrtime()));
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), TimeZoneUtils.getFormattedTime(file.getCtime()));
|
||||
|
||||
String md5 = file.getMd5Hash();
|
||||
if (md5 == null) {
|
||||
@@ -343,30 +394,43 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
* If we have a file system file, grab the more detailed
|
||||
* metadata text too
|
||||
*/
|
||||
try {
|
||||
if (file instanceof FsContent) {
|
||||
FsContent fsFile = (FsContent) file;
|
||||
if (file instanceof FsContent) {
|
||||
FsContent fsFile = (FsContent) file;
|
||||
|
||||
sb.append("<hr /><pre>\n"); //NON-NLS
|
||||
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.text"));
|
||||
sb.append(" <br /><br />"); // NON-NLS
|
||||
for (String str : fsFile.getMetaDataText()) {
|
||||
sb.append(str).append("<br />"); //NON-NLS
|
||||
addHeader(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.text"), true);
|
||||
|
||||
List<String> istatStrings = Collections.emptyList();
|
||||
try {
|
||||
istatStrings = fsFile.getMetaDataText();
|
||||
} catch (TskCoreException ex) {
|
||||
istatStrings = Arrays.asList(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text") + ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
if (istatStrings.isEmpty() || (istatStrings.size() == 1 && StringUtils.isEmpty(istatStrings.get(0)))) {
|
||||
sb.append(MessageFormat.format("<div class=\"{0}\"><p class=\"{1}\">{2}</p><div>",
|
||||
ContentViewerHtmlStyles.getIndentedClassName(),
|
||||
ContentViewerHtmlStyles.getTextClassName(),
|
||||
Bundle.MetadataWorker_doInBackground_noDataMsg()));
|
||||
} else {
|
||||
startTable(sb);
|
||||
|
||||
for (String str : istatStrings) {
|
||||
addMonospacedRow(sb, str);
|
||||
|
||||
/*
|
||||
* Very long results can cause the UI to hang before
|
||||
* displaying, so truncate the results if necessary.
|
||||
*/
|
||||
if (sb.length() > 50000) {
|
||||
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated"));
|
||||
addMonospacedRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
sb.append("</pre>\n"); //NON-NLS
|
||||
|
||||
endTable(sb);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getUniquePath());
|
||||
@@ -405,20 +469,17 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
||||
|
||||
// Add all the data source paths to the "Local Path" value cell.
|
||||
String[] imagePaths = image.getPaths();
|
||||
|
||||
if (imagePaths.length > 0) {
|
||||
StringBuilder pathValues = new StringBuilder("<div>");
|
||||
pathValues.append(imagePaths[0]);
|
||||
pathValues.append("</div>");
|
||||
for (int i = 1; i < imagePaths.length; i++) {
|
||||
pathValues.append("<div>");
|
||||
pathValues.append(imagePaths[i]);
|
||||
pathValues.append("</div>");
|
||||
}
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
|
||||
addRowWithMultipleValues(sb,
|
||||
NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
|
||||
imagePaths);
|
||||
} else {
|
||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
|
||||
NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none"));
|
||||
}
|
||||
|
||||
endTable(sb);
|
||||
}
|
||||
|
||||
if (isCancelled()) {
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[100, 58]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="scrollPane" alignment="0" pref="907" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="scrollPane" alignment="1" pref="435" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="scrollPane">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextPane" name="textPanel">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[600, 52]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.contentviewers.analysisresults;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.NodeResults;
|
||||
import org.sleuthkit.autopsy.contentviewers.analysisresults.AnalysisResultsViewModel.ResultDisplayAttributes;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.datamodel.AnalysisResult;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
|
||||
/**
|
||||
* Displays a list of analysis results in a panel.
|
||||
*/
|
||||
public class AnalysisResultsContentPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String EMPTY_HTML = "<html><head></head><body></body></html>";
|
||||
|
||||
// Anchors are inserted into the navigation so that the viewer can navigate to a selection.
|
||||
// This is the prefix of those anchors.
|
||||
private static final String RESULT_ANCHOR_PREFIX = "AnalysisResult_";
|
||||
|
||||
/**
|
||||
* Creates new form AnalysisResultsContentViewer
|
||||
*/
|
||||
public AnalysisResultsContentPanel() {
|
||||
initComponents();
|
||||
ContentViewerHtmlStyles.setupHtmlJTextPane(textPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears current text and shows text provided in the message.
|
||||
*
|
||||
* @param message The message to be displayed.
|
||||
*/
|
||||
void showMessage(String message) {
|
||||
ContentViewerHtmlStyles.setStyles(textPanel);
|
||||
textPanel.setText("<html><head></head><body>"
|
||||
+ MessageFormat.format("<p class=\"{0}\">{1}</p>",
|
||||
ContentViewerHtmlStyles.getMessageClassName(),
|
||||
message == null ? "" : EscapeUtil.escapeHtml(message))
|
||||
+ "</body></html>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the current view and displays nothing.
|
||||
*/
|
||||
void reset() {
|
||||
textPanel.setText(EMPTY_HTML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays analysis results for the node in the text pane.
|
||||
*
|
||||
* @param nodeResults The analysis results data to display.
|
||||
*/
|
||||
void displayResults(NodeResults nodeResults) {
|
||||
Document document = Jsoup.parse(EMPTY_HTML);
|
||||
Element body = document.getElementsByTag("body").first();
|
||||
|
||||
Optional<Element> panelHeader = appendPanelHeader(body, nodeResults.getContent(), nodeResults.getAggregateScore());
|
||||
|
||||
// for each analysis result item, display the data.
|
||||
List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults();
|
||||
for (int idx = 0; idx < displayAttributes.size(); idx++) {
|
||||
AnalysisResultsViewModel.ResultDisplayAttributes resultAttrs = displayAttributes.get(idx);
|
||||
Element sectionDiv = appendResult(body, idx, resultAttrs);
|
||||
if (idx > 0 || panelHeader.isPresent()) {
|
||||
sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName());
|
||||
}
|
||||
}
|
||||
|
||||
// set the body html
|
||||
ContentViewerHtmlStyles.setStyles(textPanel);
|
||||
textPanel.setText(document.html());
|
||||
|
||||
// if there is a selected result scroll to it
|
||||
Optional<AnalysisResult> selectedResult = nodeResults.getSelectedResult();
|
||||
if (selectedResult.isPresent()) {
|
||||
textPanel.scrollToReference(getAnchor(selectedResult.get()));
|
||||
} else {
|
||||
// otherwise, scroll to the beginning.
|
||||
textPanel.setCaretPosition(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the header to the panel.
|
||||
*
|
||||
* @param parent The parent html element.
|
||||
* @param content The content whose name will be added if present.
|
||||
* @param score The aggregate score whose significance will be added if
|
||||
* present.
|
||||
*
|
||||
* @return The html element.
|
||||
*/
|
||||
@Messages({
|
||||
"AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score",
|
||||
"AnalysisResultsContentPanel_content_displayKey=Item"
|
||||
})
|
||||
private Optional<Element> appendPanelHeader(Element parent, Optional<Content> content, Optional<Score> score) {
|
||||
if (!content.isPresent() || !score.isPresent()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Element container = parent.appendElement("div");
|
||||
|
||||
// if there is content append the name
|
||||
content.ifPresent((c) -> {
|
||||
container.appendElement("p")
|
||||
.attr("class", ContentViewerHtmlStyles.getTextClassName())
|
||||
.text(MessageFormat.format("{0}: {1}",
|
||||
Bundle.AnalysisResultsContentPanel_content_displayKey(),
|
||||
c.getName()));
|
||||
});
|
||||
|
||||
// if there is an aggregate score, append the value
|
||||
score.ifPresent((s) -> {
|
||||
container.appendElement("p")
|
||||
.attr("class", ContentViewerHtmlStyles.getTextClassName())
|
||||
.text(MessageFormat.format("{0}: {1}",
|
||||
Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(),
|
||||
s.getSignificance().getDisplayName()));
|
||||
});
|
||||
|
||||
return Optional.ofNullable(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the anchor id to use with the analysis result (based on the id).
|
||||
*
|
||||
* @param analysisResult The analysis result.
|
||||
*
|
||||
* @return The anchor id.
|
||||
*/
|
||||
private String getAnchor(AnalysisResult analysisResult) {
|
||||
return RESULT_ANCHOR_PREFIX + analysisResult.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a result item to the parent element of an html document.
|
||||
*
|
||||
* @param parent The parent element.
|
||||
* @param index The index of the item in the list of all items.
|
||||
* @param attrs The attributes of this item.
|
||||
*
|
||||
* @return The result div.
|
||||
*/
|
||||
@NbBundle.Messages({"# {0} - analysisResultsNumber",
|
||||
"AnalysisResultsContentPanel_result_headerKey=Analysis Result {0}"
|
||||
})
|
||||
private Element appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs) {
|
||||
// create a new section with appropriate header
|
||||
Element sectionDiv = appendSection(parent,
|
||||
Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1),
|
||||
Optional.ofNullable(getAnchor(attrs.getAnalysisResult())));
|
||||
|
||||
// create a table
|
||||
Element table = sectionDiv.appendElement("table")
|
||||
.attr("valign", "top")
|
||||
.attr("align", "left");
|
||||
|
||||
table.attr("class", ContentViewerHtmlStyles.getIndentedClassName());
|
||||
|
||||
Element tableBody = table.appendElement("tbody");
|
||||
|
||||
// append a row for each item
|
||||
for (Pair<String, String> keyVal : attrs.getAttributesToDisplay()) {
|
||||
Element row = tableBody.appendElement("tr");
|
||||
String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":";
|
||||
Element keyTd = row.appendElement("td")
|
||||
.attr("class", ContentViewerHtmlStyles.getKeyColumnClassName());
|
||||
|
||||
keyTd.appendElement("span")
|
||||
.text(keyString)
|
||||
.attr("class", ContentViewerHtmlStyles.getTextClassName());
|
||||
|
||||
String valueString = keyVal.getValue() == null ? "" : keyVal.getValue();
|
||||
row.appendElement("td")
|
||||
.text(valueString)
|
||||
.attr("class", ContentViewerHtmlStyles.getTextClassName());
|
||||
}
|
||||
|
||||
return sectionDiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a new section with a section header to the parent element.
|
||||
*
|
||||
* @param parent The element to append this section to.
|
||||
* @param headerText The text for the section.
|
||||
* @param anchorId The anchor id for this section.
|
||||
*
|
||||
* @return The div for the new section.
|
||||
*/
|
||||
private Element appendSection(Element parent, String headerText, Optional<String> anchorId) {
|
||||
Element sectionDiv = parent.appendElement("div");
|
||||
|
||||
// append an anchor tag if there is one
|
||||
Element anchorEl = null;
|
||||
if (anchorId.isPresent()) {
|
||||
anchorEl = sectionDiv.appendElement("a");
|
||||
anchorEl.attr("name", anchorId.get());
|
||||
anchorEl.attr("style", "padding: 0px; margin: 0px; display: inline-block;");
|
||||
}
|
||||
|
||||
// append the header
|
||||
Element header = null;
|
||||
header = (anchorEl == null)
|
||||
? sectionDiv.appendElement("h1")
|
||||
: anchorEl.appendElement("h1");
|
||||
|
||||
header.text(headerText);
|
||||
header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
|
||||
header.attr("style", "display: inline-block");
|
||||
|
||||
// return the section element
|
||||
return sectionDiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
javax.swing.JScrollPane scrollPane = new javax.swing.JScrollPane();
|
||||
textPanel = new javax.swing.JTextPane();
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(100, 58));
|
||||
|
||||
textPanel.setEditable(false);
|
||||
textPanel.setName(""); // NOI18N
|
||||
textPanel.setPreferredSize(new java.awt.Dimension(600, 52));
|
||||
scrollPane.setViewportView(textPanel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(scrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTextPane textPanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.contentviewers.analysisresults;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
|
||||
import org.sleuthkit.datamodel.AnalysisResult;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Displays a list of analysis results as a content viewer.
|
||||
*/
|
||||
@ServiceProvider(service = DataContentViewer.class, position = 7)
|
||||
public class AnalysisResultsContentViewer implements DataContentViewer {
|
||||
private static final Logger logger = Logger.getLogger(AnalysisResultsContentPanel.class.getName());
|
||||
|
||||
// isPreferred value
|
||||
private static final int PREFERRED_VALUE = 6;
|
||||
|
||||
private final AnalysisResultsViewModel viewModel = new AnalysisResultsViewModel();
|
||||
private final AnalysisResultsContentPanel panel = new AnalysisResultsContentPanel();
|
||||
|
||||
private SwingWorker<?, ?> worker = null;
|
||||
|
||||
|
||||
|
||||
@NbBundle.Messages({
|
||||
"AnalysisResultsContentViewer_title=Analysis Results"
|
||||
})
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return Bundle.AnalysisResultsContentViewer_title();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"AnalysisResultsContentViewer_tooltip=Viewer for Analysis Results related to the selected node."
|
||||
})
|
||||
@Override
|
||||
public String getToolTip() {
|
||||
return Bundle.AnalysisResultsContentViewer_tooltip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataContentViewer createInstance() {
|
||||
return new AnalysisResultsContentViewer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetComponent() {
|
||||
panel.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages({
|
||||
"AnalysisResultsContentViewer_setNode_loadingMessage=Loading...",
|
||||
"AnalysisResultsContentViewer_setNode_errorMessage=There was an error loading results.",})
|
||||
public synchronized void setNode(Node node) {
|
||||
// reset the panel
|
||||
panel.reset();
|
||||
|
||||
// if there is a worker running, cancel it
|
||||
if (worker != null) {
|
||||
worker.cancel(true);
|
||||
worker = null;
|
||||
}
|
||||
|
||||
// if no node, nothing to do
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// show a loading message
|
||||
panel.showMessage(Bundle.AnalysisResultsContentViewer_setNode_loadingMessage());
|
||||
|
||||
// create the worker
|
||||
worker = new DataFetchWorker<>(
|
||||
// load a view model from the node
|
||||
(selectedNode) -> viewModel.getAnalysisResults(selectedNode),
|
||||
(nodeAnalysisResults) -> {
|
||||
if (nodeAnalysisResults.getResultType() == DataFetchResult.ResultType.SUCCESS) {
|
||||
// if successful, display the results
|
||||
panel.displayResults(nodeAnalysisResults.getData());
|
||||
} else {
|
||||
// if there was an error, display an error message
|
||||
panel.showMessage(Bundle.AnalysisResultsContentViewer_setNode_errorMessage());
|
||||
}
|
||||
},
|
||||
node);
|
||||
|
||||
// kick off the swing worker
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Node node) {
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// There needs to either be a file with an AnalysisResult or an AnalysisResult in the lookup.
|
||||
for (Content content : node.getLookup().lookupAll(Content.class)) {
|
||||
if (content instanceof AnalysisResult) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (content == null || content instanceof BlackboardArtifact) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().hasAnalysisResults(content.getId())) {
|
||||
return true;
|
||||
}
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to get analysis results for file with obj id " + content.getId(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isPreferred(Node node) {
|
||||
return PREFERRED_VALUE;
|
||||
}
|
||||
}
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.contentviewers.analysisresults;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.datamodel.AnalysisResult;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a representation of a list of analysis results gathered from a node.
|
||||
*/
|
||||
public class AnalysisResultsViewModel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AnalysisResultsViewModel.class.getName());
|
||||
|
||||
/**
|
||||
* The attributes to display for a particular Analysis Result.
|
||||
*/
|
||||
static class ResultDisplayAttributes {
|
||||
|
||||
private final AnalysisResult analysisResult;
|
||||
private final List<Pair<String, String>> attributesToDisplay;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param analysisResult The analysis result which these attributes
|
||||
* describe.
|
||||
* @param attributesToDisplay The attributes to display in the order
|
||||
* they should be displayed.
|
||||
*/
|
||||
ResultDisplayAttributes(AnalysisResult analysisResult, List<Pair<String, String>> attributesToDisplay) {
|
||||
this.analysisResult = analysisResult;
|
||||
this.attributesToDisplay = attributesToDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attributes to display.
|
||||
*
|
||||
* @return The attributes to display.
|
||||
*/
|
||||
List<Pair<String, String>> getAttributesToDisplay() {
|
||||
return attributesToDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the analysis result which these attributes describe.
|
||||
*
|
||||
* @return The analysis result.
|
||||
*/
|
||||
AnalysisResult getAnalysisResult() {
|
||||
return analysisResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The analysis results relating to a node (i.e. belonging to source content
|
||||
* or directly in the lookup) to be displayed.
|
||||
*/
|
||||
static class NodeResults {
|
||||
|
||||
private final List<ResultDisplayAttributes> analysisResults;
|
||||
private final Optional<AnalysisResult> selectedResult;
|
||||
private final Optional<Score> aggregateScore;
|
||||
private final Optional<Content> content;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param analysisResults The analysis results to be displayed.
|
||||
* @param selectedResult The selected analysis result or empty if none
|
||||
* selected.
|
||||
* @param aggregateScore The aggregate score or empty if no score.
|
||||
* @param content The content associated with these results.
|
||||
*/
|
||||
NodeResults(List<ResultDisplayAttributes> analysisResults, Optional<AnalysisResult> selectedResult, Optional<Score> aggregateScore, Optional<Content> content) {
|
||||
this.analysisResults = analysisResults;
|
||||
this.selectedResult = selectedResult;
|
||||
this.aggregateScore = aggregateScore;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the analysis results to be displayed.
|
||||
*
|
||||
* @return The analysis results to be displayed.
|
||||
*/
|
||||
List<ResultDisplayAttributes> getAnalysisResults() {
|
||||
return analysisResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected analysis result or empty if none selected.
|
||||
*
|
||||
* @return The selected analysis result or empty if none selected.
|
||||
*/
|
||||
Optional<AnalysisResult> getSelectedResult() {
|
||||
return selectedResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the aggregate score or empty if no score.
|
||||
*
|
||||
* @return The aggregate score or empty if no score.
|
||||
*/
|
||||
Optional<Score> getAggregateScore() {
|
||||
return aggregateScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content associated with these results or empty if not
|
||||
* present.
|
||||
*
|
||||
* @return The content associated with these results or empty if not
|
||||
* present.
|
||||
*/
|
||||
Optional<Content> getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the value of an attribute of an analysis result for display
|
||||
* purposes.
|
||||
*
|
||||
* @param originalAttrStr The original attribute value.
|
||||
*
|
||||
* @return The normalized value for display.
|
||||
*/
|
||||
private String normalizeAttr(String originalAttrStr) {
|
||||
return (originalAttrStr == null) ? "" : originalAttrStr.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attributes to be displayed for an analysis result.
|
||||
*
|
||||
* @param analysisResult The analysis result.
|
||||
*
|
||||
* @return The attributes to be displayed.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"AnalysisResultsViewModel_displayAttributes_score=Score",
|
||||
"AnalysisResultsViewModel_displayAttributes_type=Type",
|
||||
"AnalysisResultsViewModel_displayAttributes_configuration=Configuration",
|
||||
"AnalysisResultsViewModel_displayAttributes_conclusion=Conclusion"
|
||||
})
|
||||
private ResultDisplayAttributes getDisplayAttributes(AnalysisResult analysisResult) {
|
||||
// The type of BlackboardArtifact.Type of the analysis result.
|
||||
String type = "";
|
||||
try {
|
||||
type = normalizeAttr(analysisResult.getType().getDisplayName());
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to get type for analysis result with id: " + analysisResult.getArtifactID(), ex);
|
||||
}
|
||||
|
||||
// The standard attributes to display (score, type, configuration, conclusion)
|
||||
Stream<Pair<String, String>> baseAnalysisAttrs = Stream.of(
|
||||
Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_score(),
|
||||
normalizeAttr(analysisResult.getScore().getSignificance().getDisplayName())),
|
||||
Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_type(),
|
||||
normalizeAttr(type)),
|
||||
Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_configuration(),
|
||||
normalizeAttr(analysisResult.getConfiguration())),
|
||||
Pair.of(Bundle.AnalysisResultsViewModel_displayAttributes_conclusion(),
|
||||
normalizeAttr(analysisResult.getConclusion()))
|
||||
);
|
||||
|
||||
// The BlackboardAttributes sorted by type display name.
|
||||
Stream<Pair<String, String>> blackboardAttributes = Stream.empty();
|
||||
try {
|
||||
|
||||
blackboardAttributes = analysisResult.getAttributes().stream()
|
||||
.filter(attr -> attr != null && attr.getAttributeType() != null && attr.getAttributeType().getDisplayName() != null)
|
||||
.map(attr -> Pair.of(attr.getAttributeType().getDisplayName(), normalizeAttr(attr.getDisplayString())))
|
||||
.sorted((a, b) -> a.getKey().compareToIgnoreCase(b.getKey()));
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to get attributes for analysis result with id: " + analysisResult.getArtifactID(), ex);
|
||||
}
|
||||
|
||||
// return the standard attributes along with the key value pairs of the BlackboardAttribute values.
|
||||
List<Pair<String, String>> allDisplayAttributes = Stream.concat(baseAnalysisAttrs, blackboardAttributes)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new ResultDisplayAttributes(analysisResult, allDisplayAttributes);
|
||||
}
|
||||
|
||||
private List<ResultDisplayAttributes> getOrderedDisplayAttributes(Collection<AnalysisResult> analysisResults) {
|
||||
return analysisResults.stream()
|
||||
.filter(ar -> ar != null && ar.getScore() != null)
|
||||
// reverse order to push more important scores to the top
|
||||
.sorted((a, b) -> -a.getScore().compareTo(b.getScore()))
|
||||
.map((ar) -> getDisplayAttributes(ar))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view model data representing the analysis results to be
|
||||
* displayed for the node.
|
||||
*
|
||||
* @param node The node.
|
||||
*
|
||||
* @return The analysis results view model data to display.
|
||||
*/
|
||||
NodeResults getAnalysisResults(Node node) {
|
||||
if (node == null) {
|
||||
return new NodeResults(Collections.emptyList(), Optional.empty(), Optional.empty(), Optional.empty());
|
||||
}
|
||||
|
||||
Optional<Score> aggregateScore = Optional.empty();
|
||||
Optional<Content> nodeContent = Optional.empty();
|
||||
// maps id of analysis result to analysis result to prevent duplication
|
||||
Map<Long, AnalysisResult> allAnalysisResults = new HashMap<>();
|
||||
Optional<AnalysisResult> selectedResult = Optional.empty();
|
||||
|
||||
// Find first content that is not an artifact within node
|
||||
for (Content content : node.getLookup().lookupAll(Content.class)) {
|
||||
if (content == null || content instanceof BlackboardArtifact) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
nodeContent = Optional.of(content);
|
||||
|
||||
// get the aggregate score of that content
|
||||
aggregateScore = Optional.ofNullable(content.getAggregateScore());
|
||||
|
||||
// and add all analysis results to mapping
|
||||
content.getAllAnalysisResults().stream()
|
||||
.forEach((ar) -> allAnalysisResults.put(ar.getArtifactID(), ar));
|
||||
|
||||
break;
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Unable to get analysis results for content with obj id " + content.getId(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Find any analysis results in the node
|
||||
Collection<? extends AnalysisResult> analysisResults = node.getLookup().lookupAll(AnalysisResult.class);
|
||||
if (analysisResults.size() > 0) {
|
||||
|
||||
// get any items with a score
|
||||
List<AnalysisResult> filteredResults = analysisResults.stream()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// add them to the map to display
|
||||
filteredResults.forEach((ar) -> allAnalysisResults.put(ar.getArtifactID(), ar));
|
||||
|
||||
// the selected result will be the highest scored analysis result in the node.
|
||||
selectedResult = filteredResults.stream()
|
||||
.max((a, b) -> a.getScore().compareTo(b.getScore()));
|
||||
|
||||
// if no aggregate score determined at this point, use the selected result score.
|
||||
if (!aggregateScore.isPresent()) {
|
||||
aggregateScore = selectedResult.flatMap(selectedRes -> Optional.ofNullable(selectedRes.getScore()));
|
||||
}
|
||||
}
|
||||
|
||||
// get view model representation
|
||||
List<ResultDisplayAttributes> displayAttributes = getOrderedDisplayAttributes(allAnalysisResults.values());
|
||||
|
||||
return new NodeResults(displayAttributes, selectedResult, aggregateScore, nodeContent);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score
|
||||
# {0} - analysisResultsNumber
|
||||
AnalysisResultsContentPanel_result_headerKey=Analysis Result {0}
|
||||
AnalysisResultsContentViewer_setNode_errorMessage=There was an error loading results.
|
||||
AnalysisResultsContentViewer_setNode_loadingMessage=Loading...
|
||||
AnalysisResultsContentViewer_title=Analysis Results
|
||||
AnalysisResultsContentViewer_tooltip=Viewer for Analysis Results related to the selected node.
|
||||
AnalysisResultsViewModel_displayAttributes_conclusion=Conclusion
|
||||
AnalysisResultsViewModel_displayAttributes_configuration=Configuration
|
||||
AnalysisResultsViewModel_displayAttributes_score=Score
|
||||
AnalysisResultsViewModel_displayAttributes_type=Type
|
||||
@@ -0,0 +1,11 @@
|
||||
#Thu Jul 01 11:56:41 UTC 2021
|
||||
AnalysisResultsContentPanel_aggregateScore_displayKey=\u96c6\u8a08\u30b9\u30b3\u30a2
|
||||
AnalysisResultsContentPanel_result_headerKey=\u5206\u6790\u7d50\u679c{0}
|
||||
AnalysisResultsContentViewer_setNode_errorMessage=\u7d50\u679c\u306e\u8aad\u8fbc\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||
AnalysisResultsContentViewer_setNode_loadingMessage=\u8aad\u307f\u8fbc\u307f\u4e2d...
|
||||
AnalysisResultsContentViewer_title=\u5206\u6790\u7d50\u679c
|
||||
AnalysisResultsContentViewer_tooltip=\u9078\u629e\u3057\u305f\u30ce\u30fc\u30c9\u306b\u95a2\u9023\u3059\u308b\u5206\u6790\u7d50\u679c\u306e\u30d3\u30e5\u30fc\u30a2\u3002
|
||||
AnalysisResultsViewModel_displayAttributes_conclusion=\u7d50\u8ad6
|
||||
AnalysisResultsViewModel_displayAttributes_configuration=\u69cb\u6210
|
||||
AnalysisResultsViewModel_displayAttributes_score=\u30b9\u30b3\u30a2
|
||||
AnalysisResultsViewModel_displayAttributes_type=\u30bf\u30a4\u30d7
|
||||
@@ -24,7 +24,6 @@ import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JLabel;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jsoup.Jsoup;
|
||||
@@ -39,6 +38,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerHtmlStyles;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@@ -80,18 +80,6 @@ public class Annotations {
|
||||
|
||||
private static final String EMPTY_HTML = "<html><head></head><body></body></html>";
|
||||
|
||||
private static final int DEFAULT_FONT_SIZE = new JLabel().getFont().getSize();
|
||||
// spacing occurring after an item
|
||||
private static final int DEFAULT_TABLE_SPACING = DEFAULT_FONT_SIZE;
|
||||
|
||||
// html stylesheet classnames for components
|
||||
public static final String MESSAGE_CLASSNAME = "message";
|
||||
public static final String SUBSECTION_CLASSNAME = "subsection";
|
||||
public static final String SUBHEADER_CLASSNAME = "subheader";
|
||||
public static final String SECTION_CLASSNAME = "section";
|
||||
public static final String HEADER_CLASSNAME = "header";
|
||||
public static final String VERTICAL_TABLE_CLASSNAME = "vertical-table";
|
||||
|
||||
// describing table values for a tag
|
||||
private static final List<ItemEntry<Tag>> TAG_ENTRIES = Arrays.asList(
|
||||
new ItemEntry<>(Bundle.Annotations_tagEntryDataLabel_tag(),
|
||||
@@ -200,11 +188,11 @@ public class Annotations {
|
||||
* @return If any content was actually rendered.
|
||||
*/
|
||||
private static boolean renderArtifact(Element parent, BlackboardArtifact bba, Content sourceContent) {
|
||||
boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(bba), false);
|
||||
boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(bba), false, true);
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
List<CorrelationAttributeInstance> centralRepoComments = getCentralRepositoryData(bba);
|
||||
boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, false);
|
||||
boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, false, !contentRendered);
|
||||
contentRendered = contentRendered || crRendered;
|
||||
}
|
||||
|
||||
@@ -213,12 +201,17 @@ public class Annotations {
|
||||
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() == bba.getArtifactTypeID())
|
||||
&& (hasTskComment(bba))) {
|
||||
|
||||
boolean filesetRendered = appendEntries(parent, ARTIFACT_COMMENT_CONFIG, Arrays.asList(bba), false);
|
||||
boolean filesetRendered = appendEntries(parent, ARTIFACT_COMMENT_CONFIG, Arrays.asList(bba), false, !contentRendered);
|
||||
contentRendered = contentRendered || filesetRendered;
|
||||
}
|
||||
|
||||
Element sourceFileSection = appendSection(parent, Bundle.Annotations_sourceFile_title());
|
||||
boolean sourceFileRendered = renderContent(sourceFileSection, sourceContent, true);
|
||||
sourceFileSection.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName());
|
||||
|
||||
Element sourceFileContainer = sourceFileSection.appendElement("div");
|
||||
sourceFileContainer.attr("class", ContentViewerHtmlStyles.getIndentedClassName());
|
||||
|
||||
boolean sourceFileRendered = renderContent(sourceFileContainer, sourceContent, true);
|
||||
|
||||
if (!sourceFileRendered) {
|
||||
sourceFileSection.remove();
|
||||
@@ -238,24 +231,27 @@ public class Annotations {
|
||||
* @return If any content was actually rendered.
|
||||
*/
|
||||
private static boolean renderContent(Element parent, Content sourceContent, boolean isSubheader) {
|
||||
boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(sourceContent), isSubheader);
|
||||
boolean contentRendered = appendEntries(parent, TAG_CONFIG, getTags(sourceContent), isSubheader, true);
|
||||
|
||||
if (sourceContent instanceof AbstractFile) {
|
||||
AbstractFile sourceFile = (AbstractFile) sourceContent;
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
List<CorrelationAttributeInstance> centralRepoComments = getCentralRepositoryData(sourceFile);
|
||||
boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, isSubheader);
|
||||
boolean crRendered = appendEntries(parent, CR_COMMENTS_CONFIG, centralRepoComments, isSubheader,
|
||||
!contentRendered);
|
||||
contentRendered = contentRendered || crRendered;
|
||||
}
|
||||
|
||||
boolean hashsetRendered = appendEntries(parent, HASHSET_CONFIG,
|
||||
getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT),
|
||||
isSubheader);
|
||||
isSubheader,
|
||||
!contentRendered);
|
||||
|
||||
boolean interestingFileRendered = appendEntries(parent, INTERESTING_FILE_CONFIG,
|
||||
getFileSetHits(sourceFile, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT),
|
||||
isSubheader);
|
||||
isSubheader,
|
||||
!contentRendered);
|
||||
|
||||
contentRendered = contentRendered || hashsetRendered || interestingFileRendered;
|
||||
}
|
||||
@@ -456,24 +452,36 @@ public class Annotations {
|
||||
* will be formatted as a table in the format specified in the
|
||||
* SectionConfig.
|
||||
*
|
||||
* @param parent The parent element for which the entries will be
|
||||
* attached.
|
||||
* @param config The display configuration for this entry type (i.e.
|
||||
* table type, name, if data is not present).
|
||||
* @param items The items to display.
|
||||
* @param isSubsection Whether or not this should be displayed as a
|
||||
* subsection. If not displayed as a top-level section.
|
||||
* @param parent The parent element for which the entries will be
|
||||
* attached.
|
||||
* @param config The display configuration for this entry type (i.e.
|
||||
* table type, name, if data is not present).
|
||||
* @param items The items to display.
|
||||
* @param isSubsection Whether or not this should be displayed as a
|
||||
* subsection. If not displayed as a top-level
|
||||
* section.
|
||||
* @param isFirstSection Whether or not this is the first section appended.
|
||||
*
|
||||
* @return If there was actual content rendered for this set of entries.
|
||||
*/
|
||||
private static <T> boolean appendEntries(Element parent, Annotations.SectionConfig<T> config, List<? extends T> items,
|
||||
boolean isSubsection) {
|
||||
boolean isSubsection, boolean isFirstSection) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Element sectionDiv = (isSubsection) ? appendSubsection(parent, config.getTitle()) : appendSection(parent, config.getTitle());
|
||||
appendVerticalEntryTables(sectionDiv, items, config.getAttributes());
|
||||
if (!isFirstSection) {
|
||||
sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName());
|
||||
}
|
||||
|
||||
Element sectionContainer = sectionDiv.appendElement("div");
|
||||
|
||||
if (!isSubsection) {
|
||||
sectionContainer.attr("class", ContentViewerHtmlStyles.getIndentedClassName());
|
||||
}
|
||||
|
||||
appendVerticalEntryTables(sectionContainer, items, config.getAttributes());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -499,12 +507,11 @@ public class Annotations {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Element childTable = appendTable(parent, 2, tableData, null);
|
||||
childTable.attr("class", VERTICAL_TABLE_CLASSNAME);
|
||||
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
childTable.attr("style", String.format("margin-top: %dpx;", DEFAULT_TABLE_SPACING));
|
||||
childTable.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +531,10 @@ public class Annotations {
|
||||
* @return The created table.
|
||||
*/
|
||||
private static Element appendTable(Element parent, int columnNumber, List<List<String>> content, List<String> columnHeaders) {
|
||||
Element table = parent.appendElement("table");
|
||||
Element table = parent.appendElement("table")
|
||||
.attr("valign", "top")
|
||||
.attr("align", "left");
|
||||
|
||||
if (columnHeaders != null && !columnHeaders.isEmpty()) {
|
||||
Element header = table.appendElement("thead");
|
||||
appendRow(header, columnHeaders, columnNumber, true);
|
||||
@@ -551,8 +561,15 @@ public class Annotations {
|
||||
Element row = rowParent.appendElement("tr");
|
||||
for (int i = 0; i < columnNumber; i++) {
|
||||
Element cell = row.appendElement(cellType);
|
||||
|
||||
if (i == 0) {
|
||||
cell.attr("class", ContentViewerHtmlStyles.getKeyColumnClassName());
|
||||
}
|
||||
|
||||
if (data != null && i < data.size()) {
|
||||
cell.text(StringUtils.isEmpty(data.get(i)) ? "" : data.get(i));
|
||||
cell.appendElement("span")
|
||||
.attr("class", ContentViewerHtmlStyles.getTextClassName())
|
||||
.text(StringUtils.isEmpty(data.get(i)) ? "" : data.get(i));
|
||||
}
|
||||
}
|
||||
return row;
|
||||
@@ -568,10 +585,9 @@ public class Annotations {
|
||||
*/
|
||||
private static Element appendSection(Element parent, String headerText) {
|
||||
Element sectionDiv = parent.appendElement("div");
|
||||
sectionDiv.attr("class", SECTION_CLASSNAME);
|
||||
Element header = sectionDiv.appendElement("h1");
|
||||
header.text(headerText);
|
||||
header.attr("class", HEADER_CLASSNAME);
|
||||
header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
|
||||
return sectionDiv;
|
||||
}
|
||||
|
||||
@@ -585,10 +601,9 @@ public class Annotations {
|
||||
*/
|
||||
private static Element appendSubsection(Element parent, String headerText) {
|
||||
Element subsectionDiv = parent.appendElement("div");
|
||||
subsectionDiv.attr("class", SUBSECTION_CLASSNAME);
|
||||
Element header = subsectionDiv.appendElement("h2");
|
||||
header.text(headerText);
|
||||
header.attr("class", SUBHEADER_CLASSNAME);
|
||||
header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
|
||||
return subsectionDiv;
|
||||
}
|
||||
|
||||
@@ -605,7 +620,7 @@ public class Annotations {
|
||||
private static Element appendMessage(Element parent, String message) {
|
||||
Element messageEl = parent.appendElement("p");
|
||||
messageEl.text(message);
|
||||
messageEl.attr("class", MESSAGE_CLASSNAME);
|
||||
messageEl.attr("class", ContentViewerHtmlStyles.getMessageClassName());
|
||||
return messageEl;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#Thu Jul 01 11:56:41 UTC 2021
|
||||
Annotations.centralRepositoryEntry.title=\u30bb\u30f3\u30c8\u30e9\u30eb\u30fb\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b3\u30e1\u30f3\u30c8
|
||||
Annotations.centralRepositoryEntryDataLabel.case=\u30b1\u30fc\u30b9\:
|
||||
Annotations.centralRepositoryEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\:
|
||||
Annotations.centralRepositoryEntryDataLabel.path=\u30d1\u30b9\:
|
||||
Annotations.centralRepositoryEntryDataLabel.type=\u30bf\u30a4\u30d7\:
|
||||
Annotations.fileHitEntry.artifactCommentTitle=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u30b3\u30e1\u30f3\u30c8
|
||||
Annotations.fileHitEntry.comment=\u30b3\u30e1\u30f3\u30c8\:
|
||||
Annotations.fileHitEntry.hashSetHitTitle=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u30fb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8
|
||||
Annotations.fileHitEntry.interestingFileHitTitle=\u8208\u5473\u6df1\u3044\u30d5\u30a1\u30a4\u30eb\u30d2\u30c3\u30c8\u30b3\u30e1\u30f3\u30c8
|
||||
Annotations.fileHitEntry.setName=\u30bb\u30c3\u30c8\u540d\:
|
||||
Annotations.onEmpty=\u3053\u306e\u30a2\u30a4\u30c6\u30e0\u306e\u6ce8\u91c8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
|
||||
Annotations.sourceFile.title=\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
|
||||
Annotations.tagEntry.title=\u30bf\u30b0
|
||||
Annotations.tagEntryDataLabel.comment=\u30b3\u30e1\u30f3\u30c8\:
|
||||
Annotations.tagEntryDataLabel.tag=\u30bf\u30b0\:
|
||||
Annotations.tagEntryDataLabel.tagUser=\u5be9\u67fb\u5b98\uff1a
|
||||
Annotations.title=\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3
|
||||
Annotations.toolTip=\u9078\u629e\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u95a2\u9023\u4ed8\u3051\u3089\u308c\u3066\u3044\u308b\u30bf\u30b0\u3068\u30b3\u30e1\u30f3\u30c8\u3092\u8868\u793a\u3057\u307e\u3059\u3002
|
||||
+24
-24
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||
import java.awt.Component;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -30,11 +31,13 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@@ -75,6 +78,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
*/
|
||||
public CallLogArtifactViewer() {
|
||||
initComponents();
|
||||
this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,29 +97,28 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
public void setArtifact(BlackboardArtifact artifact) {
|
||||
resetComponent();
|
||||
|
||||
if (artifact == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallLogViewData callLogViewData = null;
|
||||
try {
|
||||
callLogViewData = getCallLogViewData(artifact);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error getting attributes for Calllog artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
|
||||
}
|
||||
|
||||
List<AccountPersonaSearcherData> personaSearchDataList = new ArrayList<>();
|
||||
// update the view with the call log data
|
||||
if (callLogViewData != null) {
|
||||
List<AccountPersonaSearcherData> personaSearchDataList = updateView(callLogViewData);
|
||||
if (!personaSearchDataList.isEmpty()) {
|
||||
currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this);
|
||||
currentAccountFetcher.execute();
|
||||
} else {
|
||||
currentAccountFetcher = null;
|
||||
}
|
||||
personaSearchDataList.addAll(updateView(callLogViewData));
|
||||
|
||||
}
|
||||
if (!personaSearchDataList.isEmpty()) {
|
||||
currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this);
|
||||
currentAccountFetcher.execute();
|
||||
} else {
|
||||
currentAccountFetcher = null;
|
||||
}
|
||||
|
||||
// repaint
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,13 +312,13 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
})
|
||||
private List<AccountPersonaSearcherData> updateView(CallLogViewData callLogViewData) {
|
||||
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_parties());
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, 0, Bundle.CallLogArtifactViewer_heading_parties());
|
||||
|
||||
List<AccountPersonaSearcherData> dataList = new ArrayList<>();
|
||||
// Display "From" if we have non-local device accounts
|
||||
if (callLogViewData.getFromAccount() != null) {
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_from());
|
||||
|
||||
|
||||
// check if this is local account
|
||||
String accountDisplayString = getAccountDisplayString(callLogViewData.getFromAccount(), callLogViewData);
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, accountDisplayString);
|
||||
@@ -366,8 +369,6 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
this.setLayout(m_gridBagLayout);
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
@@ -384,7 +385,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
})
|
||||
private void updateMetadataView(CallLogViewData callLogViewData) {
|
||||
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_metadata());
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_metadata());
|
||||
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_direction());
|
||||
if (callLogViewData.getDirection() != null) {
|
||||
@@ -414,7 +415,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
"CallLogArtifactViewer_heading_Source=Source",
|
||||
"CallLogArtifactViewer_label_datasource=Data Source",})
|
||||
private void updateSourceView(CallLogViewData callLogViewData) {
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_Source());
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_Source());
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_datasource());
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
|
||||
}
|
||||
@@ -432,7 +433,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
if (callLogViewData.getOtherAttributes().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_others());
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.CallLogArtifactViewer_heading_others());
|
||||
|
||||
for (Map.Entry<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, entry.getKey());
|
||||
@@ -444,9 +445,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
"CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
|
||||
})
|
||||
private void showCRDisabledMessage() {
|
||||
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
|
||||
m_constraints.gridy++;
|
||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||
Insets messageInsets = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, messageInsets, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||
m_constraints.gridy++;
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
m_constraints.gridx = 0;
|
||||
m_constraints.weighty = 0.0;
|
||||
m_constraints.weightx = 0.0; // keep components fixed horizontally.
|
||||
m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
|
||||
m_constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getSectionIndent(), 0, 0);
|
||||
m_constraints.fill = GridBagConstraints.NONE;
|
||||
|
||||
}
|
||||
|
||||
+43
-49
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,7 +19,6 @@
|
||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
@@ -38,6 +37,7 @@ import javax.swing.JTextPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -49,8 +49,6 @@ final class CommunicationArtifactViewerHelper {
|
||||
// Number of columns in the gridbag layout.
|
||||
private final static int MAX_COLS = 4;
|
||||
|
||||
final static int LEFT_INSET = 12;
|
||||
|
||||
/**
|
||||
* Empty private constructor
|
||||
*/
|
||||
@@ -64,34 +62,34 @@ final class CommunicationArtifactViewerHelper {
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constraints to use.
|
||||
* @param spacing Spacing to add to top insets (in pixels).
|
||||
* @param headerString Heading string to display.
|
||||
*
|
||||
* @return JLabel Heading label added.
|
||||
*/
|
||||
static JLabel addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) {
|
||||
static JLabel addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, int topSpacing, String headerString) {
|
||||
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// create label for heading
|
||||
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
|
||||
|
||||
// add a blank line before the start of new section, unless it's
|
||||
// the first section
|
||||
if (constraints.gridy != 0) {
|
||||
addBlankLine(panel, gridbagLayout, constraints);
|
||||
}
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
|
||||
// let the header span all of the row
|
||||
constraints.gridwidth = MAX_COLS;
|
||||
constraints.insets = new Insets(0, 0, 0, 0); // No inset for header
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
constraints.fill = GridBagConstraints.NONE;
|
||||
|
||||
constraints.insets = new Insets(topSpacing, 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||
|
||||
// set text
|
||||
headingLabel.setText(headerString);
|
||||
headingLabel.setText(headerString.trim());
|
||||
|
||||
// make it large and bold
|
||||
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
|
||||
headingLabel.setFont(ContentViewerDefaults.getHeaderFont());
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(headingLabel, constraints);
|
||||
@@ -159,7 +157,7 @@ final class CommunicationArtifactViewerHelper {
|
||||
int savedFill = constraints.fill;
|
||||
|
||||
constraints.weightx = 1.0; // take up all the horizontal space
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
javax.swing.Box.Filler horizontalFiller = new javax.swing.Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 0));
|
||||
gridbagLayout.setConstraints(horizontalFiller, constraints);
|
||||
@@ -181,6 +179,7 @@ final class CommunicationArtifactViewerHelper {
|
||||
static void addPageEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy++;
|
||||
|
||||
double savedWeighty = constraints.weighty;
|
||||
int savedFill = constraints.fill;
|
||||
@@ -197,24 +196,6 @@ final class CommunicationArtifactViewerHelper {
|
||||
constraints.fill = savedFill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a blank line to the panel.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constraints to use.
|
||||
*/
|
||||
static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
|
||||
javax.swing.JLabel filler = new javax.swing.JLabel(" ");
|
||||
gridbagLayout.setConstraints(filler, constraints);
|
||||
panel.add(filler);
|
||||
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a label/key to the panel at col 0.
|
||||
*
|
||||
@@ -247,9 +228,12 @@ final class CommunicationArtifactViewerHelper {
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
constraints.insets = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
|
||||
// set text
|
||||
keyLabel.setText(keyString + ": ");
|
||||
String preppedKeyString = keyString == null ? null : keyString.trim() + ":";
|
||||
keyLabel.setText(preppedKeyString);
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(keyLabel, constraints);
|
||||
@@ -288,6 +272,7 @@ final class CommunicationArtifactViewerHelper {
|
||||
JTextPane valueField = new JTextPane();
|
||||
valueField.setEditable(false);
|
||||
valueField.setOpaque(false);
|
||||
valueField.setMargin(new Insets(0,0,0,0));
|
||||
|
||||
constraints.gridx = gridx < MAX_COLS ? gridx : MAX_COLS - 1;
|
||||
|
||||
@@ -295,7 +280,8 @@ final class CommunicationArtifactViewerHelper {
|
||||
|
||||
// let the value span 2 cols
|
||||
cloneConstraints.gridwidth = 2;
|
||||
cloneConstraints.fill = GridBagConstraints.BOTH;
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
cloneConstraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
|
||||
// set text
|
||||
valueField.setText(valueString);
|
||||
@@ -325,13 +311,13 @@ final class CommunicationArtifactViewerHelper {
|
||||
* @param panel Panel to show.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constraints to use.
|
||||
*
|
||||
* @param insets The insets to be used for the grid bag layout constraints. If null, default insets are assumed.
|
||||
* @param messageString Message to display.
|
||||
*
|
||||
* @return Label for message added.
|
||||
*/
|
||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString) {
|
||||
return addMessageRow(panel, gridbagLayout, constraints, messageString, 0);
|
||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, Insets insets, GridBagConstraints constraints, String messageString) {
|
||||
return addMessageRow(panel, gridbagLayout, constraints, insets, messageString, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,26 +326,33 @@ final class CommunicationArtifactViewerHelper {
|
||||
*
|
||||
* @param panel Panel to show.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param insets The insets to be used for the grid bag layout constraints.
|
||||
* @param constraints Constraints to use.
|
||||
*
|
||||
* @param insets The insets to be used for the grid bag layout constraints. If null, default insets are assumed.
|
||||
* @param messageString Message to display.
|
||||
* @param gridx The grid x location to use.
|
||||
*
|
||||
* @return Label for message added.
|
||||
*/
|
||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString, int gridx) {
|
||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, Insets insets, String messageString, int gridx) {
|
||||
|
||||
// create label
|
||||
javax.swing.JLabel messageLabel = new javax.swing.JLabel();
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
||||
|
||||
constraints.insets = insets == null
|
||||
? new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0) :
|
||||
insets;
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
|
||||
int savedGridwidth = constraints.gridwidth;
|
||||
|
||||
constraints.gridwidth = 3;
|
||||
|
||||
// set text
|
||||
messageLabel.setText(messageString);
|
||||
messageLabel.setText(messageString == null ? null : messageString.trim());
|
||||
messageLabel.setFont(ContentViewerDefaults.getMessageFont());
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(messageLabel, constraints);
|
||||
@@ -406,8 +399,9 @@ final class CommunicationArtifactViewerHelper {
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// extra Indent in
|
||||
constraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0);
|
||||
|
||||
constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
|
||||
// create label
|
||||
javax.swing.JLabel personaLabel = new javax.swing.JLabel();
|
||||
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
||||
@@ -415,15 +409,12 @@ final class CommunicationArtifactViewerHelper {
|
||||
? Bundle.CommunicationArtifactViewerHelper_persona_searching()
|
||||
: Bundle.CommunicationArtifactViewerHelper_persona_unknown());
|
||||
|
||||
personaLabel.setText(personaLabelText);
|
||||
|
||||
personaLabel.setText(personaLabelText == null ? null : personaLabelText.trim());
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(personaLabel, constraints);
|
||||
panel.add(personaLabel);
|
||||
|
||||
// restore constraint
|
||||
constraints.insets = savedInsets;
|
||||
|
||||
constraints.gridx++;
|
||||
|
||||
// Place a button as place holder. It will be enabled when persona is available.
|
||||
@@ -441,6 +432,9 @@ final class CommunicationArtifactViewerHelper {
|
||||
} else {
|
||||
personaLabel.setEnabled(false);
|
||||
}
|
||||
|
||||
// restore constraint
|
||||
constraints.insets = savedInsets;
|
||||
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
|
||||
@@ -469,7 +463,7 @@ final class CommunicationArtifactViewerHelper {
|
||||
GridBagConstraints indentedConstraints = (GridBagConstraints) constraints.clone();
|
||||
|
||||
// Add an indent to match persona labels
|
||||
indentedConstraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0);
|
||||
indentedConstraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
|
||||
String contactInfo = Bundle.CommunicationArtifactViewerHelper_contact_label(contactId != null && !contactId.isEmpty() ? contactId : Bundle.CommunicationArtifactViewerHelper_contact_label_unknown());
|
||||
|
||||
|
||||
+88
-79
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -41,9 +41,9 @@ import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
@@ -57,6 +57,7 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
@@ -64,6 +65,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.InvalidAccountIDException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
@@ -107,7 +109,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
*/
|
||||
public ContactArtifactViewer() {
|
||||
initComponents();
|
||||
|
||||
this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||
defaultImage = new ImageIcon(ContactArtifactViewer.class.getResource(DEFAULT_IMAGE_PATH));
|
||||
}
|
||||
|
||||
@@ -129,19 +131,15 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
// Reset the panel.
|
||||
resetComponent();
|
||||
|
||||
if (artifact == null) {
|
||||
return;
|
||||
if (artifact != null) {
|
||||
try {
|
||||
extractArtifactData(artifact);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
|
||||
return;
|
||||
}
|
||||
updateView();
|
||||
}
|
||||
|
||||
try {
|
||||
extractArtifactData(artifact);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error getting attributes for artifact (artifact_id=%d, obj_id=%d)", artifact.getArtifactID(), artifact.getObjectID()), ex);
|
||||
return;
|
||||
}
|
||||
|
||||
updateView();
|
||||
|
||||
this.setLayout(this.m_gridBagLayout);
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
@@ -163,6 +161,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* Extracts data from the artifact to be displayed in the panel.
|
||||
*
|
||||
* @param artifact Artifact to show.
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private void extractArtifactData(BlackboardArtifact artifact) throws TskCoreException {
|
||||
@@ -234,7 +233,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
/**
|
||||
* Updates the contact image in the view.
|
||||
*
|
||||
* @param contactPanelLayout Panel layout.
|
||||
* @param contactPanelLayout Panel layout.
|
||||
* @param contactPanelConstraints Layout constraints.
|
||||
*
|
||||
*/
|
||||
@@ -245,8 +244,11 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
Insets savedInsets = contactPanelConstraints.insets;
|
||||
contactPanelConstraints.gridy = 0;
|
||||
contactPanelConstraints.gridx = 0;
|
||||
contactPanelConstraints.insets = new Insets(0, 0, 0, 0);
|
||||
|
||||
contactPanelConstraints.insets = new Insets(0, 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||
int prevGridWidth = contactPanelConstraints.gridwidth;
|
||||
contactPanelConstraints.gridwidth = 3;
|
||||
contactPanelConstraints.anchor = GridBagConstraints.LINE_START;
|
||||
|
||||
javax.swing.JLabel contactImage = new javax.swing.JLabel();
|
||||
contactImage.setIcon(getImageFromArtifact(contactArtifact));
|
||||
contactImage.setText(Bundle.ContactArtifactViewer_contactImage_text());
|
||||
@@ -256,13 +258,14 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
CommunicationArtifactViewerHelper.addLineEndGlue(this, contactPanelLayout, contactPanelConstraints);
|
||||
contactPanelConstraints.gridy++;
|
||||
|
||||
contactPanelConstraints.gridwidth = prevGridWidth;
|
||||
contactPanelConstraints.insets = savedInsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the contact name in the view.
|
||||
*
|
||||
* @param contactPanelLayout Panel layout.
|
||||
* @param contactPanelLayout Panel layout.
|
||||
* @param contactPanelConstraints Layout constraints.
|
||||
*
|
||||
*/
|
||||
@@ -275,13 +278,13 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
if (StringUtils.isEmpty(bba.getValueString()) == false) {
|
||||
contactName = bba.getDisplayString();
|
||||
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, contactName);
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, 0, contactName);
|
||||
foundName = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundName == false) {
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, Bundle.ContactArtifactViewer_contactname_unknown());
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_contactname_unknown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,9 +292,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* Updates the view by displaying the given list of attributes in the given
|
||||
* section panel.
|
||||
*
|
||||
* @param sectionAttributesList List of attributes to display.
|
||||
* @param sectionHeader Section name label.
|
||||
* @param contactPanelLayout Panel layout.
|
||||
* @param sectionAttributesList List of attributes to display.
|
||||
* @param sectionHeader Section name label.
|
||||
* @param contactPanelLayout Panel layout.
|
||||
* @param contactPanelConstraints Layout constraints.
|
||||
*
|
||||
*/
|
||||
@@ -302,7 +305,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
return;
|
||||
}
|
||||
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, sectionHeader);
|
||||
CommunicationArtifactViewerHelper.addHeader(this, contactPanelLayout, contactPanelConstraints, ContentViewerDefaults.getSectionSpacing(), sectionHeader);
|
||||
for (BlackboardAttribute bba : sectionAttributesList) {
|
||||
CommunicationArtifactViewerHelper.addKey(this, contactPanelLayout, contactPanelConstraints, bba.getAttributeType().getDisplayName());
|
||||
CommunicationArtifactViewerHelper.addValue(this, contactPanelLayout, contactPanelConstraints, bba.getDisplayString());
|
||||
@@ -316,7 +319,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
"ContactArtifactViewer_heading_Source=Source",
|
||||
"ContactArtifactViewer_label_datasource=Data Source",})
|
||||
private void updateSource() {
|
||||
CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_heading_Source());
|
||||
CommunicationArtifactViewerHelper.addHeader(this, this.m_gridBagLayout, m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_heading_Source());
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_label_datasource());
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, m_constraints, datasourceName);
|
||||
}
|
||||
@@ -335,7 +338,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
private void initiatePersonasSearch() {
|
||||
|
||||
// add a section header
|
||||
JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_persona_header());
|
||||
JLabel personaHeader = CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, m_constraints, ContentViewerDefaults.getSectionSpacing(), Bundle.ContactArtifactViewer_persona_header());
|
||||
|
||||
m_constraints.gridy++;
|
||||
|
||||
@@ -346,8 +349,10 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
this.personaSearchStatusLabel = new javax.swing.JLabel();
|
||||
personaSearchStatusLabel.setText(personaStatusLabelText);
|
||||
|
||||
personaSearchStatusLabel.setFont(ContentViewerDefaults.getMessageFont());
|
||||
|
||||
m_constraints.gridx = 0;
|
||||
m_constraints.anchor = GridBagConstraints.LINE_START;
|
||||
|
||||
CommunicationArtifactViewerHelper.addComponent(this, m_gridBagLayout, m_constraints, personaSearchStatusLabel);
|
||||
|
||||
@@ -359,9 +364,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
personaHeader.setEnabled(false);
|
||||
personaSearchStatusLabel.setEnabled(false);
|
||||
|
||||
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
|
||||
m_constraints.gridy++;
|
||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||
Insets messageInsets = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, messageInsets, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||
m_constraints.gridy++;
|
||||
|
||||
CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
|
||||
@@ -412,12 +416,12 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
/**
|
||||
* Displays the given persona in the persona panel.
|
||||
*
|
||||
* @param persona Persona to display.
|
||||
* @param matchNumber Number of matches.
|
||||
* @param persona Persona to display.
|
||||
* @param matchNumber Number of matches.
|
||||
* @param missingAccountsList List of contact accounts this persona may be
|
||||
* missing.
|
||||
* @param gridBagLayout Layout to use.
|
||||
* @param constraints layout constraints.
|
||||
* missing.
|
||||
* @param gridBagLayout Layout to use.
|
||||
* @param constraints layout constraints.
|
||||
*
|
||||
* @throws CentralRepoException
|
||||
*/
|
||||
@@ -435,12 +439,9 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
// save the original insets
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// some label are indented 2x to appear indented w.r.t column above
|
||||
Insets extraIndentInsets = new java.awt.Insets(0, 2 * CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
|
||||
|
||||
// Add a Match X label in col 0.
|
||||
constraints.gridx = 0;
|
||||
javax.swing.JLabel matchNumberLabel = CommunicationArtifactViewerHelper.addKey(this, gridBagLayout, constraints, String.format("%s %d", Bundle.ContactArtifactViewer_persona_match_num(), matchNumber));
|
||||
javax.swing.JLabel matchNumberLabel = CommunicationArtifactViewerHelper.addKey(this, gridBagLayout, constraints, String.format("%s %d", Bundle.ContactArtifactViewer_persona_match_num(), matchNumber).trim());
|
||||
|
||||
javax.swing.JLabel personaNameLabel = new javax.swing.JLabel();
|
||||
javax.swing.JButton personaButton = new javax.swing.JButton();
|
||||
@@ -461,6 +462,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
//constraints.gridwidth = 1; // TBD: this may not be needed if we use single panel
|
||||
constraints.gridx++;
|
||||
constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
personaNameLabel.setText(personaName);
|
||||
gridBagLayout.setConstraints(personaNameLabel, constraints);
|
||||
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaNameLabel);
|
||||
@@ -474,6 +477,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
// Shirnk the button height.
|
||||
personaButton.setMargin(new Insets(0, 5, 0, 5));
|
||||
constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
gridBagLayout.setConstraints(personaButton, constraints);
|
||||
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, personaButton);
|
||||
CommunicationArtifactViewerHelper.addLineEndGlue(this, gridBagLayout, constraints);
|
||||
@@ -488,7 +493,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
//constraints.insets = labelInsets;
|
||||
|
||||
javax.swing.JLabel accountsStatus = new javax.swing.JLabel(Bundle.ContactArtifactViewer_found_all_accounts_label());
|
||||
constraints.insets = extraIndentInsets;
|
||||
constraints.insets = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
constraints.anchor = GridBagConstraints.LINE_START;
|
||||
CommunicationArtifactViewerHelper.addComponent(this, gridBagLayout, constraints, accountsStatus);
|
||||
constraints.insets = savedInsets;
|
||||
|
||||
@@ -501,7 +507,6 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
constraints.gridy++;
|
||||
|
||||
// this needs an extra indent
|
||||
constraints.insets = extraIndentInsets;
|
||||
CommunicationArtifactViewerHelper.addKeyAtCol(this, gridBagLayout, constraints, Bundle.ContactArtifactViewer_missing_account_label(), 1);
|
||||
constraints.insets = savedInsets;
|
||||
|
||||
@@ -544,12 +549,12 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
m_gridBagLayout = new GridBagLayout();
|
||||
m_constraints = new GridBagConstraints();
|
||||
|
||||
m_constraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||
m_constraints.anchor = GridBagConstraints.LINE_START;
|
||||
m_constraints.gridy = 0;
|
||||
m_constraints.gridx = 0;
|
||||
m_constraints.weighty = 0.0;
|
||||
m_constraints.weightx = 0.0; // keep components fixed horizontally.
|
||||
m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
|
||||
m_constraints.insets = new java.awt.Insets(0, ContentViewerDefaults.getSectionIndent(), 0, 0);
|
||||
m_constraints.fill = GridBagConstraints.NONE;
|
||||
|
||||
}
|
||||
@@ -560,7 +565,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* @param artifact
|
||||
*
|
||||
* @return Image from a TSK_CONTACT artifact or default image if none was
|
||||
* found or the artifact is not a TSK_CONTACT
|
||||
* found or the artifact is not a TSK_CONTACT
|
||||
*/
|
||||
private ImageIcon getImageFromArtifact(BlackboardArtifact artifact) {
|
||||
ImageIcon imageIcon = defaultImage;
|
||||
@@ -610,7 +615,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* Creates a persona searcher task.
|
||||
*
|
||||
* @param accountAttributesList List of attributes that may map to
|
||||
* accounts.
|
||||
* accounts.
|
||||
*/
|
||||
ContactPersonaSearcherTask(BlackboardArtifact artifact) {
|
||||
this.artifact = artifact;
|
||||
@@ -620,48 +625,52 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
protected Map<Persona, ArrayList<CentralRepoAccount>> doInBackground() throws Exception {
|
||||
|
||||
Map<Persona, ArrayList<CentralRepoAccount>> uniquePersonas = new HashMap<>();
|
||||
|
||||
CommunicationsManager commManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||
List<Account> contactAccountsList = commManager.getAccountsRelatedToArtifact(artifact);
|
||||
|
||||
for (Account account : contactAccountsList) {
|
||||
if (isCancelled()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
try {
|
||||
if (isCancelled()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
// make a list of all unique accounts for this contact
|
||||
if (!account.getAccountType().equals(Account.Type.DEVICE)) {
|
||||
Optional<CentralRepoAccount.CentralRepoAccountType> optCrAccountType = CentralRepository.getInstance().getAccountTypeByName(account.getAccountType().getTypeName());
|
||||
if (optCrAccountType.isPresent()) {
|
||||
CentralRepoAccount crAccount = CentralRepository.getInstance().getAccount(optCrAccountType.get(), account.getTypeSpecificID());
|
||||
// make a list of all unique accounts for this contact
|
||||
if (!account.getAccountType().equals(Account.Type.DEVICE)) {
|
||||
Optional<CentralRepoAccount.CentralRepoAccountType> optCrAccountType = CentralRepository.getInstance().getAccountTypeByName(account.getAccountType().getTypeName());
|
||||
if (optCrAccountType.isPresent()) {
|
||||
CentralRepoAccount crAccount = CentralRepository.getInstance().getAccount(optCrAccountType.get(), account.getTypeSpecificID());
|
||||
|
||||
if (crAccount != null && uniqueAccountsList.contains(crAccount) == false) {
|
||||
uniqueAccountsList.add(crAccount);
|
||||
if (crAccount != null && uniqueAccountsList.contains(crAccount) == false) {
|
||||
uniqueAccountsList.add(crAccount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collection<PersonaAccount> personaAccounts = PersonaAccount.getPersonaAccountsForAccount(account);
|
||||
if (personaAccounts != null && !personaAccounts.isEmpty()) {
|
||||
// get personas for the account
|
||||
Collection<Persona> personas
|
||||
= personaAccounts
|
||||
.stream()
|
||||
.map(PersonaAccount::getPersona)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// make a list of unique personas, along with all their accounts
|
||||
for (Persona persona : personas) {
|
||||
if (uniquePersonas.containsKey(persona) == false) {
|
||||
Collection<CentralRepoAccount> accounts = persona.getPersonaAccounts()
|
||||
.stream()
|
||||
.map(PersonaAccount::getAccount)
|
||||
.collect(Collectors.toList());
|
||||
Collection<PersonaAccount> personaAccounts = PersonaAccount.getPersonaAccountsForAccount(account);
|
||||
if (personaAccounts != null && !personaAccounts.isEmpty()) {
|
||||
// get personas for the account
|
||||
Collection<Persona> personas
|
||||
= personaAccounts
|
||||
.stream()
|
||||
.map(PersonaAccount::getPersona)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ArrayList<CentralRepoAccount> personaAccountsList = new ArrayList<>(accounts);
|
||||
uniquePersonas.put(persona, personaAccountsList);
|
||||
// make a list of unique personas, along with all their accounts
|
||||
for (Persona persona : personas) {
|
||||
if (uniquePersonas.containsKey(persona) == false) {
|
||||
Collection<CentralRepoAccount> accounts = persona.getPersonaAccounts()
|
||||
.stream()
|
||||
.map(PersonaAccount::getAccount)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ArrayList<CentralRepoAccount> personaAccountsList = new ArrayList<>(accounts);
|
||||
uniquePersonas.put(persona, personaAccountsList);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InvalidAccountIDException ex) {
|
||||
// Do nothing, the account has an identifier that not an
|
||||
// acceptable format for the cr.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,7 +718,7 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param personaNameLabel Persona name label.
|
||||
* @param personaNameLabel Persona name label.
|
||||
* @param personaActionButton Persona action button.
|
||||
*/
|
||||
PersonaUIComponents(JLabel personaNameLabel, JButton personaActionButton) {
|
||||
@@ -777,8 +786,8 @@ public class ContactArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
for (CentralRepoAccount account : contactUniqueAccountsList) {
|
||||
personaPanel.addAccount(account, Bundle.ContactArtifactViewer_persona_account_justification(), Persona.Confidence.HIGH);
|
||||
}
|
||||
|
||||
if(contactName != null && contactUniqueAccountsList.isEmpty()) {
|
||||
|
||||
if (contactName != null && contactUniqueAccountsList.isEmpty()) {
|
||||
createPersonaDialog.setStartupPopupMessage(Bundle.ContactArtifactViewer_id_not_found_in_cr(contactName));
|
||||
}
|
||||
|
||||
|
||||
+4
-21
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2020 Basis Technology Corp.
|
||||
* Copyright 2011-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -41,7 +41,6 @@ import javax.swing.text.View;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
@@ -54,6 +53,7 @@ import com.google.gson.JsonArray;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||
import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel;
|
||||
//import org.sleuthkit.autopsy.contentviewers.Bundle;
|
||||
|
||||
@@ -343,7 +343,7 @@ public class DefaultTableArtifactContentViewer extends AbstractArtifactDetailsPa
|
||||
|
||||
// Use Autopsy date formatting settings, not TSK defaults
|
||||
case DATETIME:
|
||||
value = epochTimeToString(attr.getValueLong());
|
||||
value = TimeZoneUtils.getFormattedTime(attr.getValueLong());
|
||||
break;
|
||||
case JSON:
|
||||
// Get the attribute's JSON value and convert to indented multiline display string
|
||||
@@ -454,7 +454,7 @@ public class DefaultTableArtifactContentViewer extends AbstractArtifactDetailsPa
|
||||
String attributeName = jsonKey;
|
||||
String attributeValue;
|
||||
if (attributeName.toUpperCase().contains("DATETIME")) {
|
||||
attributeValue = epochTimeToString(Long.parseLong(jsonElement.getAsString()));
|
||||
attributeValue = TimeZoneUtils.getFormattedTime(Long.parseLong(jsonElement.getAsString()));
|
||||
} else {
|
||||
attributeValue = jsonElement.getAsString();
|
||||
}
|
||||
@@ -463,23 +463,6 @@ public class DefaultTableArtifactContentViewer extends AbstractArtifactDetailsPa
|
||||
sb.append(NEW_LINE).append(String.format("%s%s = null", startIndent, jsonKey));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts epoch time to readable string.
|
||||
*
|
||||
* @param epochTime epoch time value to be converted to string.
|
||||
*
|
||||
* @return String with human readable time.
|
||||
*/
|
||||
private String epochTimeToString(long epochTime) {
|
||||
String dateTimeString = "0000-00-00 00:00:00";
|
||||
if (null != content && 0 != epochTime) {
|
||||
dateFormatter.setTimeZone(ContentUtils.getTimeZone(content));
|
||||
dateTimeString = dateFormatter.format(new java.util.Date(epochTime * 1000));
|
||||
}
|
||||
return dateTimeString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+32
-21
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -18,9 +18,9 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
@@ -30,25 +30,30 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||
import org.sleuthkit.autopsy.discovery.ui.AbstractArtifactDetailsPanel;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.TimeUtilities;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
@@ -56,13 +61,18 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
*/
|
||||
@ServiceProvider(service = ArtifactContentViewer.class)
|
||||
public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel implements ArtifactContentViewer {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(GeneralPurposeArtifactViewer.class.getName());
|
||||
// Number of columns in the gridbag layout.
|
||||
private final static int MAX_COLS = 4;
|
||||
private final static Insets ROW_INSETS = new java.awt.Insets(0, 12, 0, 0);
|
||||
private final static Insets HEADER_INSETS = new java.awt.Insets(0, 0, 0, 0);
|
||||
private final static Insets ZERO_INSETS = new java.awt.Insets(0, 0, 0, 0);
|
||||
|
||||
private final static Insets FIRST_HEADER_INSETS = ZERO_INSETS;
|
||||
private final static Insets HEADER_INSETS = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0);
|
||||
private final static Insets VALUE_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getColumnSpacing(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
private final static Insets KEY_COLUMN_INSETS = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0);
|
||||
|
||||
private final static double GLUE_WEIGHT_X = 1.0;
|
||||
private final static double TEXT_WEIGHT_X = 0.0;
|
||||
private final static int LABEL_COLUMN = 0;
|
||||
@@ -92,6 +102,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
initComponents();
|
||||
gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||
detailsPanel.setLayout(gridBagLayout);
|
||||
detailsPanel.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +192,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
gridBagConstraints.weighty = 0.0;
|
||||
gridBagConstraints.weightx = TEXT_WEIGHT_X; // keep components fixed horizontally.
|
||||
gridBagConstraints.fill = GridBagConstraints.NONE;
|
||||
gridBagConstraints.insets = ROW_INSETS;
|
||||
gridBagConstraints.insets = ZERO_INSETS;
|
||||
}
|
||||
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
@@ -263,9 +274,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
for (BlackboardAttribute bba : attrList) {
|
||||
if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
|
||||
if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
|
||||
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)));
|
||||
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_dates_time(), TimeZoneUtils.getFormattedTime(bba.getValueLong()));
|
||||
} else {
|
||||
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)));
|
||||
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong()));
|
||||
}
|
||||
} else if (bba.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID() && artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
|
||||
addNameValueRow(Bundle.GeneralPurposeArtifactViewer_term_label(), bba.getDisplayString());
|
||||
@@ -293,7 +304,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
for (int key : attributeMap.keySet()) {
|
||||
for (BlackboardAttribute bba : attributeMap.get(key)) {
|
||||
if (bba.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
|
||||
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeUtilities.epochToTime(bba.getValueLong(), ContentUtils.getTimeZone(artifact)));
|
||||
addNameValueRow(bba.getAttributeType().getDisplayName(), TimeZoneUtils.getFormattedTime(bba.getValueLong()));
|
||||
} else {
|
||||
addNameValueRow(bba.getAttributeType().getDisplayName(), bba.getDisplayString());
|
||||
}
|
||||
@@ -387,29 +398,26 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
headingLabel.setEditable(false);
|
||||
// add a blank line before the start of new section, unless it's
|
||||
// the first section
|
||||
if (gridBagConstraints.gridy != 0) {
|
||||
gridBagConstraints.gridy++;
|
||||
// add to panel
|
||||
addToPanel(new javax.swing.JLabel(" "));
|
||||
addLineEndGlue();
|
||||
headingLabel.setFocusable(false);
|
||||
}
|
||||
gridBagConstraints.insets = (gridBagConstraints.gridy == 0)
|
||||
? FIRST_HEADER_INSETS
|
||||
: HEADER_INSETS;
|
||||
|
||||
gridBagConstraints.gridy++;
|
||||
gridBagConstraints.gridx = LABEL_COLUMN;;
|
||||
// let the header span all of the row
|
||||
gridBagConstraints.gridwidth = MAX_COLS;
|
||||
gridBagConstraints.insets = HEADER_INSETS;
|
||||
// set text
|
||||
headingLabel.setText(headerString);
|
||||
// make it large and bold
|
||||
headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD, headingLabel.getFont().getSize() + 2));
|
||||
headingLabel.setFont(ContentViewerDefaults.getHeaderFont());
|
||||
headingLabel.setMargin(ZERO_INSETS);
|
||||
// add to panel
|
||||
addToPanel(headingLabel);
|
||||
// reset constraints to normal
|
||||
gridBagConstraints.gridwidth = LABEL_WIDTH;
|
||||
// add line end glue
|
||||
addLineEndGlue();
|
||||
gridBagConstraints.insets = ROW_INSETS;
|
||||
gridBagConstraints.insets = ZERO_INSETS;
|
||||
return headingLabel;
|
||||
}
|
||||
|
||||
@@ -466,6 +474,7 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
|
||||
keyLabel.setFocusable(false);
|
||||
gridBagConstraints.gridy++;
|
||||
gridBagConstraints.insets = KEY_COLUMN_INSETS;
|
||||
gridBagConstraints.gridx = LABEL_COLUMN;
|
||||
gridBagConstraints.gridwidth = LABEL_WIDTH;
|
||||
// set text
|
||||
@@ -493,7 +502,9 @@ public class GeneralPurposeArtifactViewer extends AbstractArtifactDetailsPanel i
|
||||
valueField.setFocusable(false);
|
||||
valueField.setEditable(false);
|
||||
valueField.setOpaque(false);
|
||||
valueField.setMargin(ZERO_INSETS);
|
||||
gridBagConstraints.gridx = VALUE_COLUMN;
|
||||
gridBagConstraints.insets = VALUE_COLUMN_INSETS;
|
||||
GridBagConstraints cloneConstraints = (GridBagConstraints) gridBagConstraints.clone();
|
||||
// let the value span 2 cols
|
||||
cloneConstraints.gridwidth = VALUE_WIDTH;
|
||||
|
||||
+20
-10
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.contentviewers.artifactviewers;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -44,6 +45,7 @@ import javax.swing.JTextPane;
|
||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
@@ -56,6 +58,7 @@ import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.guiutils.ContactCache;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
@@ -77,6 +80,15 @@ final class MessageAccountPanel extends JPanel {
|
||||
|
||||
private AccountFetcher currentFetcher = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*/
|
||||
MessageAccountPanel() {
|
||||
this.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new artifact for the panel.
|
||||
*
|
||||
@@ -170,9 +182,7 @@ final class MessageAccountPanel extends JPanel {
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(getMainHorizontalGroup(layout, dataList))
|
||||
.addContainerGap(158, Short.MAX_VALUE)));
|
||||
.addGroup(getMainHorizontalGroup(layout, dataList))));
|
||||
|
||||
layout.setVerticalGroup(getMainVerticalGroup(layout, dataList));
|
||||
setLayout(layout);
|
||||
@@ -186,6 +196,7 @@ final class MessageAccountPanel extends JPanel {
|
||||
|
||||
messageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
messageLabel.setText(Bundle.MessageAccountPanel_no_matches());
|
||||
messageLabel.setFont(ContentViewerDefaults.getMessageFont());
|
||||
messageLabel.setEnabled(false);
|
||||
messagePanel.add(messageLabel, java.awt.BorderLayout.CENTER);
|
||||
|
||||
@@ -224,14 +235,12 @@ final class MessageAccountPanel extends JPanel {
|
||||
private ParallelGroup getMainVerticalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||
SequentialGroup group = layout.createSequentialGroup();
|
||||
for (AccountContainer o : data) {
|
||||
group.addGap(5)
|
||||
.addComponent(o.getAccountLabel())
|
||||
group.addComponent(o.getAccountLabel())
|
||||
.addGroup(o.getContactLineVerticalGroup(layout))
|
||||
.addGroup(o.getPersonLineVerticalGroup(layout));
|
||||
group.addGap(ContentViewerDefaults.getSectionSpacing());
|
||||
}
|
||||
|
||||
group.addContainerGap(83, Short.MAX_VALUE);
|
||||
|
||||
return layout.createParallelGroup().addGroup(group);
|
||||
|
||||
}
|
||||
@@ -259,12 +268,11 @@ final class MessageAccountPanel extends JPanel {
|
||||
private SequentialGroup getPersonaHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
|
||||
SequentialGroup group = layout.createSequentialGroup();
|
||||
ParallelGroup pgroup = layout.createParallelGroup(Alignment.LEADING);
|
||||
group.addGap(10);
|
||||
for (AccountContainer o : data) {
|
||||
pgroup.addGroup(o.getPersonaSequentialGroup(layout));
|
||||
pgroup.addGroup(o.getContactSequentialGroup(layout));
|
||||
}
|
||||
group.addGap(10)
|
||||
group.addGap(ContentViewerDefaults.getSectionIndent())
|
||||
.addGroup(pgroup)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(getButtonGroup(layout, data));
|
||||
@@ -343,7 +351,9 @@ final class MessageAccountPanel extends JPanel {
|
||||
button = new JButton();
|
||||
button.addActionListener(new PersonaButtonListener(this));
|
||||
|
||||
accountLabel.setMargin(new Insets(0, 0, 0, 0));
|
||||
accountLabel.setText(account.getTypeSpecificID());
|
||||
accountLabel.setFont(ContentViewerDefaults.getHeaderFont());
|
||||
contactDisplayName.setText(contactName);
|
||||
personaDisplayName.setText(persona != null ? persona.getName() : Bundle.MessageAccountPanel_unknown_label());
|
||||
|
||||
|
||||
+13
-10
@@ -2,11 +2,17 @@
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="ContentViewerDefaults.getPanelBackground()" type="code"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[495, 55]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[300, 55]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[495, 75]"/>
|
||||
<Dimension value="[495, 55]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@@ -24,15 +30,13 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jSourceNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
||||
<Component id="jSourceTextLabel" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="260" max="-2" attributes="0"/>
|
||||
<Component id="jSourceTextLabel" pref="360" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="90" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
||||
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
@@ -41,14 +45,13 @@
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jSourceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jSourceTextLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.contentviewers.contextviewer.ContextViewer.DateTimePanel;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
||||
@@ -75,8 +76,10 @@ public final class ContextSourcePanel extends javax.swing.JPanel implements Date
|
||||
jSourceNameLabel = new javax.swing.JLabel();
|
||||
jSourceTextLabel = new javax.swing.JLabel();
|
||||
|
||||
setBackground(new java.awt.Color(255, 255, 255));
|
||||
setPreferredSize(new java.awt.Dimension(495, 75));
|
||||
setBackground(ContentViewerDefaults.getPanelBackground());
|
||||
setMaximumSize(new java.awt.Dimension(495, 55));
|
||||
setMinimumSize(new java.awt.Dimension(300, 55));
|
||||
setPreferredSize(new java.awt.Dimension(495, 55));
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextSourcePanel.class, "ContextSourcePanel.jSourceGoToResultButton.text")); // NOI18N
|
||||
jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@@ -94,26 +97,23 @@ public final class ContextSourcePanel extends javax.swing.JPanel implements Date
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(50, 50, 50)
|
||||
.addComponent(jSourceNameLabel)
|
||||
.addGap(36, 36, 36)
|
||||
.addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(260, 260, 260))
|
||||
.addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(90, 90, 90)
|
||||
.addGap(40, 40, 40)
|
||||
.addComponent(jSourceGoToResultButton)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(2, 2, 2)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jSourceNameLabel)
|
||||
.addComponent(jSourceTextLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jSourceGoToResultButton)
|
||||
.addGap(0, 0, 0))
|
||||
.addGap(0, 11, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
+14
-10
@@ -2,11 +2,17 @@
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="ContentViewerDefaults.getPanelBackground()" type="code"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 55]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[300, 55]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[495, 75]"/>
|
||||
<Dimension value="[495, 55]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@@ -24,30 +30,28 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jUsageNameLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="jUsageTextLabel" pref="240" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
||||
<Component id="jUsageTextLabel" pref="420" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="90" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
||||
<Component id="jUsageGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace pref="275" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jUsageTextLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jUsageNameLabel" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jUsageGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
||||
+11
-10
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Copyright 2020-2021 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.contentviewers.contextviewer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
|
||||
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
||||
@@ -74,8 +75,10 @@ public final class ContextUsagePanel extends javax.swing.JPanel implements Conte
|
||||
jUsageNameLabel = new javax.swing.JLabel();
|
||||
jUsageTextLabel = new javax.swing.JLabel();
|
||||
|
||||
setBackground(new java.awt.Color(255, 255, 255));
|
||||
setPreferredSize(new java.awt.Dimension(495, 75));
|
||||
setBackground(ContentViewerDefaults.getPanelBackground());
|
||||
setMaximumSize(new java.awt.Dimension(32767, 55));
|
||||
setMinimumSize(new java.awt.Dimension(300, 55));
|
||||
setPreferredSize(new java.awt.Dimension(495, 55));
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(jUsageGoToResultButton, org.openide.util.NbBundle.getMessage(ContextUsagePanel.class, "ContextUsagePanel.jUsageGoToResultButton.text")); // NOI18N
|
||||
jUsageGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@@ -93,25 +96,23 @@ public final class ContextUsagePanel extends javax.swing.JPanel implements Conte
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(50, 50, 50)
|
||||
.addComponent(jUsageNameLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE)
|
||||
.addGap(36, 36, 36))
|
||||
.addComponent(jUsageTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(90, 90, 90)
|
||||
.addGap(40, 40, 40)
|
||||
.addComponent(jUsageGoToResultButton)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(275, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(2, 2, 2)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jUsageTextLabel)
|
||||
.addComponent(jUsageNameLabel, javax.swing.GroupLayout.Alignment.TRAILING))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jUsageGoToResultButton))
|
||||
.addComponent(jUsageGoToResultButton)
|
||||
.addGap(0, 11, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
@@ -4,38 +4,19 @@
|
||||
<NonVisualComponents>
|
||||
<Container class="javax.swing.JPanel" name="jSourcePanel">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" id="window" palette="3" red="ff" type="palette"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new EmptyBorder(FIRST_HEADER_INSETS)" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
||||
<Component id="jSourceLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="304" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
|
||||
<Component id="jSourceLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||
<Property name="axis" type="int" value="3"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jSourceLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="jSourceLabel" property="font" relativeSize="true" size="1"/>
|
||||
</FontInfo>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="ContentViewerDefaults.getHeaderFont()" type="code"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jSourceLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
@@ -50,38 +31,19 @@
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jUsagePanel">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" id="window" palette="3" red="ff" type="palette"/>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new EmptyBorder(HEADER_INSETS)" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
|
||||
<Component id="jUsageLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="298" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Component id="jUsageLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||
<Property name="axis" type="int" value="3"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jUsageLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="jUsageLabel" property="font" relativeSize="true" size="1"/>
|
||||
</FontInfo>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="ContentViewerDefaults.getHeaderFont()
" type="code"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUsageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
@@ -95,31 +57,9 @@
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jUnknownPanel">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
|
||||
<Component id="jUnknownLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
<Component id="jUnknownLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
|
||||
<Property name="axis" type="int" value="3"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jUnknownLabel">
|
||||
@@ -127,6 +67,9 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties" key="ContextViewer.jUnknownLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new EmptyBorder(DATA_ROW_INSETS)" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
@@ -137,11 +80,8 @@
|
||||
</Container>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[495, 358]"/>
|
||||
<Dimension value="[0, 0]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
@@ -171,8 +111,8 @@
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" red="ff" type="rgb"/>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[16, 16]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user