mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 01:37:43 +00:00
Merge pull request #6183 from wschaeferB/6610-ReorganizeDiscovery
6610 reorganize discovery
This commit is contained in:
commit
dd8ef7fc9e
@ -107,7 +107,7 @@ import org.sleuthkit.autopsy.coreutils.Version;
|
|||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
import org.sleuthkit.autopsy.discovery.OpenDiscoveryAction;
|
import org.sleuthkit.autopsy.discovery.ui.OpenDiscoveryAction;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
FileSearchDialog.jLabel1.text=File Type
|
|
||||||
FileSearchDialog.dsCheckBox.text=Data source
|
|
||||||
FileSearchDialog.cancelButton.text=Cancel
|
|
||||||
FileSearchDialog.freqCheckBox.text=CR Frequency
|
|
||||||
FileSearchDialog.sizeCheckBox.text=Size
|
|
||||||
FileSearchDialog.kwCheckBox.text=Keyword
|
|
||||||
FileSearchDialog.addParentButton.text=Add
|
|
||||||
FileSearchDialog.deleteParentButton.text=Delete
|
|
||||||
FileSearchDialog.parentFullRadioButton.text=Full
|
|
||||||
FileSearchDialog.parentSubstringRadioButton.text=Substring
|
|
||||||
FileSearchDialog.jLabel2.text=(All will be used)
|
|
||||||
FileSearchDialog.jLabel3.text=Group by attribute:
|
|
||||||
FileSearchDialog.jLabel4.text=Order groups by:
|
|
||||||
FileSearchDialog.orderAttrRadioButton.text=Attribute
|
|
||||||
FileSearchDialog.orderSizeRadioButton.text=Group Size
|
|
||||||
FileSearchDialog.jLabel5.text=Order files by:
|
|
||||||
FileSearchDialog.parentCheckBox.text=Parent
|
|
||||||
FileSearchPanel.sortingPanel.border.title=Grouping
|
|
||||||
FileSearchPanel.addButton.text=Add
|
|
||||||
FileSearchPanel.substringRadioButton.text=Substring
|
|
||||||
FileSearchPanel.fullRadioButton.text=Full
|
|
||||||
FileSearchPanel.parentCheckbox.text=Parent Folder:
|
|
||||||
FileSearchPanel.keywordCheckbox.text=Keyword:
|
|
||||||
FileSearchPanel.crFrequencyCheckbox.text=Past Occurrences:
|
|
||||||
FileSearchPanel.dataSourceCheckbox.text=Data Source:
|
|
||||||
FileSearchPanel.sizeCheckbox.text=File Size:
|
|
||||||
FileSearchPanel.orderGroupsByLabel.text=Order Groups By:
|
|
||||||
FileSearchPanel.filtersScrollPane.border.title=Filters
|
|
||||||
FileSearchPanel.parentLabel.text=(All will be used)
|
|
||||||
FileSearchPanel.deleteButton.text=Delete
|
|
||||||
FileSearchPanel.orderByLabel.text=Order Within Groups By:
|
|
||||||
FileSearchPanel.groupByLabel.text=Group By:
|
|
||||||
FileSearchDialog.searchButton.text=Search
|
|
||||||
FileSearchDialog.hashCheckBox.text=Hash Set
|
|
||||||
FileSearchDialog.intCheckBox.text=Interesting Items
|
|
||||||
FileSearchDialog.tagsCheckBox.text=Tags
|
|
||||||
FileSearchDialog.objCheckBox.text=Objects
|
|
||||||
FileSearchDialog.exifCheckBox.text=Must contain EXIF data
|
|
||||||
FileSearchDialog.notableCheckBox.text=Must have been tagged as notable
|
|
||||||
FileSearchDialog.scoreCheckBox.text=Has score
|
|
||||||
FileSearchPanel.hashSetCheckbox.text=Hash Set:
|
|
||||||
FileSearchPanel.tagsCheckbox.text=Tag:
|
|
||||||
FileSearchPanel.interestingItemsCheckbox.text=Interesting Item:
|
|
||||||
FileSearchPanel.scoreCheckbox.text=Has Score:
|
|
||||||
FileSearchPanel.notableCheckbox.text=Must have been tagged as notable
|
|
||||||
FileSearchPanel.objectsCheckbox.text=Object Detected:
|
|
||||||
ResultsPanel.currentPageLabel.text=Page: -
|
|
||||||
ResultsPanel.pageControlsLabel.text=Pages:
|
|
||||||
ResultsPanel.gotoPageLabel.text=Go to Page:
|
|
||||||
ResultsPanel.pageSizeLabel.text=Page Size:
|
|
||||||
DiscoveryExtractAction.title.extractFiles.text=Extract File
|
|
||||||
FileSearchPanel.includeRadioButton.text=Include
|
|
||||||
FileSearchPanel.excludeRadioButton.text=Exclude
|
|
||||||
FileSearchPanel.knownFilesCheckbox.toolTipText=
|
|
||||||
FileSearchPanel.knownFilesCheckbox.text=Hide known files
|
|
||||||
GroupListPanel.groupKeyList.border.title=Groups
|
|
||||||
FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings
|
|
||||||
DocumentPanel.fileSizeLabel.toolTipText=
|
|
||||||
DocumentPanel.isDeletedLabel.toolTipText=
|
|
||||||
ImageThumbnailPanel.isDeletedLabel.toolTipText=
|
|
||||||
FileSearchPanel.userCreatedCheckbox.text=Possibly User Created
|
|
||||||
DiscoveryDialog.documentsButton.text=Documents
|
|
||||||
DiscoveryDialog.videosButton.text=Videos
|
|
||||||
DiscoveryDialog.imagesButton.text=Images
|
|
||||||
DiscoveryDialog.searchButton.text=Search
|
|
||||||
DetailsPanel.instancesList.border.title=Instances
|
|
||||||
SizeFilterPanel.sizeCheckbox.text=File Size:
|
|
||||||
DataSourceFilterPanel.dataSourceCheckbox.text=Data Source:
|
|
||||||
UserCreatedFilterPanel.userCreatedCheckbox.text=Possibly User Created
|
|
||||||
# To change this license header, choose License Headers in Project Properties.
|
|
||||||
# To change this template file, choose Tools | Templates
|
|
||||||
# and open the template in the editor.
|
|
||||||
HashSetFilterPanel.hashSetCheckbox.text=Hash Set:
|
|
||||||
InterestingItemFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
|
||||||
ParentFolderFilterPanel.parentCheckbox.text=Parent Folder:
|
|
||||||
ParentFolderFilterPanel.deleteButton.text=Delete
|
|
||||||
ParentFolderFilterPanel.excludeRadioButton.text=Exclude
|
|
||||||
ParentFolderFilterPanel.includeRadioButton.text=Include
|
|
||||||
ParentFolderFilterPanel.substringRadioButton.text=Substring
|
|
||||||
ParentFolderFilterPanel.fullRadioButton.text=Full
|
|
||||||
ParentFolderFilterPanel.parentLabel.text=(All will be used)
|
|
||||||
ParentFolderFilterPanel.addButton.text=Add
|
|
||||||
ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder:
|
|
||||||
ParentFolderFilterPanel.addButton.text_1=Add
|
|
||||||
ParentFolderFilterPanel.deleteButton.text_1=Delete
|
|
||||||
ParentFolderFilterPanel.excludeRadioButton.text_1=Exclude
|
|
||||||
ParentFolderFilterPanel.substringRadioButton.text_1=Substring
|
|
||||||
ParentFolderFilterPanel.includeRadioButton.text_1=Include
|
|
||||||
ParentFolderFilterPanel.fullRadioButton.text_1=Full
|
|
||||||
ParentFolderFilterPanel.parentLabel.text_1=(All will be used)
|
|
||||||
InterestingItemsFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
|
||||||
UserCreatedFilterPanel.userCreatedCheckbox.text_1=Possibly User Created
|
|
||||||
PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text=Past Occurrences:
|
|
||||||
ObjectDetectedFilterPanel.text=Object Detected:
|
|
||||||
DiscoveryDialog.sortingPanel.border.title=Step 3: Choose display settings
|
|
||||||
DiscoveryDialog.groupByLabel.text=Group By:
|
|
||||||
DiscoveryDialog.orderByLabel.text=Order Within Groups By:
|
|
||||||
DiscoveryDialog.orderGroupsByLabel.text=Order Groups By:
|
|
||||||
ImageFilterPanel.imageFiltersSplitPane.toolTipText=
|
|
||||||
DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which documents to show
|
|
||||||
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
|
|
||||||
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
|
|
||||||
DiscoveryDialog.step1Label.text=Step 1: Choose result type
|
|
||||||
ResultsSplitPaneDivider.hideButton.text=
|
|
||||||
ResultsSplitPaneDivider.showButton.text=
|
|
||||||
ResultsSplitPaneDivider.detailsLabel.text=Details Area
|
|
||||||
DiscoveryDialog.domainsButton.text=Domains
|
|
||||||
DomainFilterPanel.domainFiltersSplitPane.border.title=Step 2: Filter which domains to show
|
|
||||||
DomainFilterPanel.domainFiltersSplitPane.toolTipText=
|
|
||||||
DateFilterPanel.dateFilterCheckbox.text=Date Filter:
|
|
||||||
ArtifactTypeFilterPanel.artifactTypeCheckbox.text=Artifact Type:
|
|
||||||
DomainUniquenessFilterPanel.domainUniquenessCheckbox.text=Domain Uniqueness:
|
|
||||||
DateFilterPanel.mostRecentButton.text=Only last:
|
|
||||||
DateFilterPanel.daysLabel.text=days of activity
|
|
||||||
DateFilterPanel.endCheckBox.text=End:
|
|
||||||
DateFilterPanel.startCheckBox.text=Start:
|
|
@ -1,295 +0,0 @@
|
|||||||
AttributeSearchData.AttributeType.Domain.displayName=Domain
|
|
||||||
AttributeSearchData.AttributeType.Other.displayName=Other
|
|
||||||
CTL_OpenDiscoveryAction=Discovery
|
|
||||||
# {0} - dataSourceName
|
|
||||||
DataSourceModuleWrapper.exifModule.text=Exif Parser module was not run on data source: {0}\n
|
|
||||||
# {0} - dataSourceName
|
|
||||||
DataSourceModuleWrapper.fileTypeModule.text=File Type Identification module was not run on data source: {0}\n
|
|
||||||
# {0} - dataSourceName
|
|
||||||
DataSourceModuleWrapper.hashModule.text=Hash Lookup module was not run on data source: {0}\n
|
|
||||||
# {0} - timeZone
|
|
||||||
DateFilterPanel.dateRange.text=Date Range ({0}):
|
|
||||||
DiscoveryDialog.name.text=Discovery
|
|
||||||
DiscoveryTopComponent.cancelButton.text=Cancel Search
|
|
||||||
DiscoveryTopComponent.name=\ Discovery
|
|
||||||
DiscoveryTopComponent.newSearch.text=New Search
|
|
||||||
DiscoveryTopComponent.searchCancelled.text=Search has been cancelled.
|
|
||||||
# {0} - search
|
|
||||||
DiscoveryTopComponent.searchComplete.text=Results with {0}
|
|
||||||
DiscoveryTopComponent.searchError.text=Error no type specified for search.
|
|
||||||
# {0} - searchType
|
|
||||||
DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait.
|
|
||||||
DiscoveryUiUtility.bytes.text=bytes
|
|
||||||
DiscoveryUiUtility.gigaBytes.text=GB
|
|
||||||
DiscoveryUiUtility.kiloBytes.text=KB
|
|
||||||
DiscoveryUiUtility.megaBytes.text=MB
|
|
||||||
# {0} - fileSize
|
|
||||||
# {1} - units
|
|
||||||
DiscoveryUiUtility.sizeLabel.text=Size: {0} {1}
|
|
||||||
DiscoveryUiUtility.terraBytes.text=TB
|
|
||||||
# {0} - otherInstanceCount
|
|
||||||
DocumentPanel.nameLabel.more.text=\ and {0} more
|
|
||||||
DocumentPanel.noImageExtraction.text=0 of ? images
|
|
||||||
DocumentPanel.numberOfImages.noImages=No images
|
|
||||||
# {0} - numberOfImages
|
|
||||||
DocumentPanel.numberOfImages.text=1 of {0} images
|
|
||||||
DocumentWrapper.previewInitialValue=Preview not generated yet.
|
|
||||||
FileGroup.groupSortingAlgorithm.groupName.text=Group Name
|
|
||||||
FileGroup.groupSortingAlgorithm.groupSize.text=Group Size
|
|
||||||
# {0} - Data source name
|
|
||||||
# {1} - Data source ID
|
|
||||||
FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})
|
|
||||||
# {0} - Data source ID
|
|
||||||
FileSearch.DataSourceGroupKey.idOnly=Data source (ID: {0})
|
|
||||||
FileSearch.documentSummary.noBytes=No bytes read for document, unable to display preview.
|
|
||||||
FileSearch.documentSummary.noPreview=No preview available.
|
|
||||||
FileSearch.FileTagGroupKey.noSets=None
|
|
||||||
# {0} - file name
|
|
||||||
FileSearch.genVideoThumb.progress.text=extracting temporary file {0}
|
|
||||||
FileSearch.GroupingAttributeType.datasource.displayName=Data Source
|
|
||||||
FileSearch.GroupingAttributeType.fileType.displayName=File Type
|
|
||||||
FileSearch.GroupingAttributeType.frequency.displayName=Past Occurrences
|
|
||||||
FileSearch.GroupingAttributeType.hash.displayName=Hash Set
|
|
||||||
FileSearch.GroupingAttributeType.interestingItem.displayName=Interesting Item
|
|
||||||
FileSearch.GroupingAttributeType.keywordList.displayName=Keyword
|
|
||||||
FileSearch.GroupingAttributeType.none.displayName=None
|
|
||||||
FileSearch.GroupingAttributeType.object.displayName=Object Detected
|
|
||||||
FileSearch.GroupingAttributeType.parent.displayName=Parent Folder
|
|
||||||
FileSearch.GroupingAttributeType.size.displayName=File Size
|
|
||||||
FileSearch.GroupingAttributeType.tag.displayName=Tag
|
|
||||||
FileSearch.HashHitsGroupKey.noHashHits=None
|
|
||||||
FileSearch.InterestingItemGroupKey.noSets=None
|
|
||||||
FileSearch.KeywordListGroupKey.noKeywords=None
|
|
||||||
FileSearch.NoGroupingGroupKey.allFiles=All Files
|
|
||||||
FileSearch.ObjectDetectedGroupKey.noSets=None
|
|
||||||
FileSearchData.FileSize.100kbto1mb=: 100KB-1MB
|
|
||||||
FileSearchData.FileSize.100mbto1gb=: 100MB-1GB
|
|
||||||
FileSearchData.FileSize.10PlusGb=: 10GB+
|
|
||||||
FileSearchData.FileSize.16kbto100kb=: 16-100KB
|
|
||||||
FileSearchData.FileSize.1gbto5gb=: 1-5GB
|
|
||||||
FileSearchData.FileSize.1mbto50mb=: 1-50MB
|
|
||||||
FileSearchData.FileSize.200PlusMb=: 200MB+
|
|
||||||
FileSearchData.FileSize.500kbto100mb=: 500KB-100MB
|
|
||||||
FileSearchData.FileSize.50mbto200mb=: 50-200MB
|
|
||||||
FileSearchData.FileSize.5gbto10gb=: 5-10GB
|
|
||||||
FileSearchData.FileSize.LARGE.displayName=Large
|
|
||||||
FileSearchData.FileSize.MEDIUM.displayName=Medium
|
|
||||||
FileSearchData.FileSize.SMALL.displayName=Small
|
|
||||||
FileSearchData.FileSize.upTo16kb=: 0-16KB
|
|
||||||
FileSearchData.FileSize.upTo500kb=: 0-500KB
|
|
||||||
FileSearchData.FileSize.XLARGE.displayName=XLarge
|
|
||||||
FileSearchData.FileSize.XSMALL.displayName=XSmall
|
|
||||||
FileSearchData.FileSize.XXLARGE.displayName=XXLarge
|
|
||||||
FileSearchData.FileType.Audio.displayName=Audio
|
|
||||||
FileSearchData.FileType.Documents.displayName=Documents
|
|
||||||
FileSearchData.FileType.Executables.displayName=Executables
|
|
||||||
FileSearchData.FileType.Image.displayName=Image
|
|
||||||
FileSearchData.FileType.Other.displayName=Other/Unknown
|
|
||||||
FileSearchData.FileType.Video.displayName=Video
|
|
||||||
FileSearchData.Frequency.common.displayName=Common (11 - 100)
|
|
||||||
FileSearchData.Frequency.known.displayName=Known (NSRL)
|
|
||||||
FileSearchData.Frequency.rare.displayName=Rare (2-10)
|
|
||||||
FileSearchData.Frequency.unique.displayName=Unique (1)
|
|
||||||
FileSearchData.Frequency.unknown.displayName=Unknown
|
|
||||||
FileSearchData.Frequency.verycommon.displayName=Very Common (100+)
|
|
||||||
FileSearchData.Score.interesting.displayName=Interesting
|
|
||||||
FileSearchData.Score.notable.displayName=Notable
|
|
||||||
FileSearchData.Score.unknown.displayName=Unknown
|
|
||||||
FileSearchDialog.jLabel1.text=File Type
|
|
||||||
FileSearchDialog.dsCheckBox.text=Data source
|
|
||||||
FileSearchDialog.cancelButton.text=Cancel
|
|
||||||
FileSearchDialog.freqCheckBox.text=CR Frequency
|
|
||||||
FileSearchDialog.sizeCheckBox.text=Size
|
|
||||||
FileSearchDialog.kwCheckBox.text=Keyword
|
|
||||||
FileSearchDialog.addParentButton.text=Add
|
|
||||||
FileSearchDialog.deleteParentButton.text=Delete
|
|
||||||
FileSearchDialog.parentFullRadioButton.text=Full
|
|
||||||
FileSearchDialog.parentSubstringRadioButton.text=Substring
|
|
||||||
FileSearchDialog.jLabel2.text=(All will be used)
|
|
||||||
FileSearchDialog.jLabel3.text=Group by attribute:
|
|
||||||
FileSearchDialog.jLabel4.text=Order groups by:
|
|
||||||
FileSearchDialog.orderAttrRadioButton.text=Attribute
|
|
||||||
FileSearchDialog.orderSizeRadioButton.text=Group Size
|
|
||||||
FileSearchDialog.jLabel5.text=Order files by:
|
|
||||||
FileSearchDialog.parentCheckBox.text=Parent
|
|
||||||
FileSearchFiltering.concatenateSetNamesForDisplay.comma=,
|
|
||||||
# {0} - filters
|
|
||||||
FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}
|
|
||||||
FileSearchFiltering.KnownFilter.desc=which are not known
|
|
||||||
FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable
|
|
||||||
# {0} - tag names
|
|
||||||
FileSearchFiltering.TagsFilter.desc=Tagged {0}
|
|
||||||
FileSearchFiltering.TagsFilter.or=,
|
|
||||||
FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data
|
|
||||||
FileSearchPanel.sortingPanel.border.title=Grouping
|
|
||||||
FileSearchPanel.addButton.text=Add
|
|
||||||
FileSearchPanel.substringRadioButton.text=Substring
|
|
||||||
FileSearchPanel.fullRadioButton.text=Full
|
|
||||||
FileSearchPanel.parentCheckbox.text=Parent Folder:
|
|
||||||
FileSearchPanel.keywordCheckbox.text=Keyword:
|
|
||||||
FileSearchPanel.crFrequencyCheckbox.text=Past Occurrences:
|
|
||||||
FileSearchPanel.dataSourceCheckbox.text=Data Source:
|
|
||||||
FileSearchPanel.sizeCheckbox.text=File Size:
|
|
||||||
FileSearchPanel.orderGroupsByLabel.text=Order Groups By:
|
|
||||||
FileSearchPanel.filtersScrollPane.border.title=Filters
|
|
||||||
FileSearchPanel.parentLabel.text=(All will be used)
|
|
||||||
FileSearchPanel.deleteButton.text=Delete
|
|
||||||
FileSearchPanel.orderByLabel.text=Order Within Groups By:
|
|
||||||
FileSearchPanel.groupByLabel.text=Group By:
|
|
||||||
FileSearchDialog.searchButton.text=Search
|
|
||||||
FileSearchDialog.hashCheckBox.text=Hash Set
|
|
||||||
FileSearchDialog.intCheckBox.text=Interesting Items
|
|
||||||
FileSearchDialog.tagsCheckBox.text=Tags
|
|
||||||
FileSearchDialog.objCheckBox.text=Objects
|
|
||||||
FileSearchDialog.exifCheckBox.text=Must contain EXIF data
|
|
||||||
FileSearchDialog.notableCheckBox.text=Must have been tagged as notable
|
|
||||||
FileSearchDialog.scoreCheckBox.text=Has score
|
|
||||||
FileSearchPanel.hashSetCheckbox.text=Hash Set:
|
|
||||||
FileSearchPanel.tagsCheckbox.text=Tag:
|
|
||||||
FileSearchPanel.interestingItemsCheckbox.text=Interesting Item:
|
|
||||||
FileSearchPanel.scoreCheckbox.text=Has Score:
|
|
||||||
FileSearchPanel.notableCheckbox.text=Must have been tagged as notable
|
|
||||||
FileSearchPanel.objectsCheckbox.text=Object Detected:
|
|
||||||
FileSorter.SortingMethod.datasource.displayName=Data Source
|
|
||||||
FileSorter.SortingMethod.filename.displayName=File Name
|
|
||||||
FileSorter.SortingMethod.filesize.displayName=File Size
|
|
||||||
FileSorter.SortingMethod.filetype.displayName=File Type
|
|
||||||
FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency
|
|
||||||
FileSorter.SortingMethod.fullPath.displayName=Full Path
|
|
||||||
FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names
|
|
||||||
GroupsListPanel.noResults.message.text=No results were found for the selected filters.\n\nReminder:\n -The File Type Identification module must be run on each data source you want to find results in.\n -The Hash Lookup module must be run on each data source if you want to filter by past occurrence.\n -The Exif module must be run on each data source if you are filtering by User Created content.
|
|
||||||
GroupsListPanel.noResults.title.text=No results found
|
|
||||||
ImageThumbnailPanel.isDeleted.text=All instances of file are deleted.
|
|
||||||
# {0} - otherInstanceCount
|
|
||||||
ImageThumbnailPanel.nameLabel.more.text=\ and {0} more
|
|
||||||
OpenDiscoveryAction.resultsIncomplete.text=Discovery results may be incomplete
|
|
||||||
ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.
|
|
||||||
ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.
|
|
||||||
ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag.
|
|
||||||
ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.
|
|
||||||
# {0} - currentPage
|
|
||||||
# {1} - totalPages
|
|
||||||
ResultsPanel.currentPage.displayValue=Page: {0} of {1}
|
|
||||||
ResultsPanel.currentPageLabel.text=Page: -
|
|
||||||
ResultsPanel.documentPreview.text=Document preview creation cancelled.
|
|
||||||
# {0} - selectedPage
|
|
||||||
# {1} - maxPage
|
|
||||||
ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value from 1 to {1}.
|
|
||||||
ResultsPanel.invalidPageNumber.title=Invalid Page Number
|
|
||||||
ResultsPanel.openInExternalViewer.name=Open in External Viewer
|
|
||||||
ResultsPanel.pageControlsLabel.text=Pages:
|
|
||||||
ResultsPanel.gotoPageLabel.text=Go to Page:
|
|
||||||
ResultsPanel.pageSizeLabel.text=Page Size:
|
|
||||||
DiscoveryExtractAction.title.extractFiles.text=Extract File
|
|
||||||
FileSearchPanel.includeRadioButton.text=Include
|
|
||||||
FileSearchPanel.excludeRadioButton.text=Exclude
|
|
||||||
FileSearchPanel.knownFilesCheckbox.toolTipText=
|
|
||||||
FileSearchPanel.knownFilesCheckbox.text=Hide known files
|
|
||||||
GroupListPanel.groupKeyList.border.title=Groups
|
|
||||||
FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings
|
|
||||||
DocumentPanel.fileSizeLabel.toolTipText=
|
|
||||||
DocumentPanel.isDeletedLabel.toolTipText=
|
|
||||||
ImageThumbnailPanel.isDeletedLabel.toolTipText=
|
|
||||||
FileSearchPanel.userCreatedCheckbox.text=Possibly User Created
|
|
||||||
DiscoveryDialog.documentsButton.text=Documents
|
|
||||||
DiscoveryDialog.videosButton.text=Videos
|
|
||||||
DiscoveryDialog.imagesButton.text=Images
|
|
||||||
DiscoveryDialog.searchButton.text=Search
|
|
||||||
DetailsPanel.instancesList.border.title=Instances
|
|
||||||
ResultsPanel.unableToCreate.text=Unable to create summary.
|
|
||||||
ResultsPanel.viewFileInDir.name=View File in Directory
|
|
||||||
# {0} - Data source name
|
|
||||||
# {1} - Data source ID
|
|
||||||
SearchFiltering.DataSourceFilter.datasource={0}({1})
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.DataSourceFilter.desc=Data source(s): {0}
|
|
||||||
SearchFiltering.DataSourceFilter.or=,
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.FileTypeFilter.desc=Type: {0}
|
|
||||||
SearchFiltering.FileTypeFilter.or=,
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.FrequencyFilter.desc=Past occurrences: {0}
|
|
||||||
SearchFiltering.FrequencyFilter.or=,
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.ParentFilter.desc=Paths matching: {0}
|
|
||||||
SearchFiltering.ParentFilter.exact=(exact match)
|
|
||||||
SearchFiltering.ParentFilter.excluded=(excluded)
|
|
||||||
SearchFiltering.ParentFilter.included=(included)
|
|
||||||
SearchFiltering.ParentFilter.or=,
|
|
||||||
SearchFiltering.ParentFilter.substring=(substring)
|
|
||||||
SearchFiltering.ParentSearchTerm.excludeString=\ (exclude)
|
|
||||||
SearchFiltering.ParentSearchTerm.fullString=\ (exact)
|
|
||||||
SearchFiltering.ParentSearchTerm.includeString=\ (include)
|
|
||||||
SearchFiltering.ParentSearchTerm.subString=\ (substring)
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.ScoreFilter.desc=Score(s) of : {0}
|
|
||||||
# {0} - filters
|
|
||||||
SearchFiltering.SizeFilter.desc=Size(s): {0}
|
|
||||||
SearchFiltering.SizeFilter.or=,
|
|
||||||
SizeFilterPanel.sizeCheckbox.text=File Size:
|
|
||||||
DataSourceFilterPanel.dataSourceCheckbox.text=Data Source:
|
|
||||||
UserCreatedFilterPanel.userCreatedCheckbox.text=Possibly User Created
|
|
||||||
# To change this license header, choose License Headers in Project Properties.
|
|
||||||
# To change this template file, choose Tools | Templates
|
|
||||||
# and open the template in the editor.
|
|
||||||
HashSetFilterPanel.hashSetCheckbox.text=Hash Set:
|
|
||||||
InterestingItemFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
|
||||||
ParentFolderFilterPanel.parentCheckbox.text=Parent Folder:
|
|
||||||
ParentFolderFilterPanel.deleteButton.text=Delete
|
|
||||||
ParentFolderFilterPanel.excludeRadioButton.text=Exclude
|
|
||||||
ParentFolderFilterPanel.includeRadioButton.text=Include
|
|
||||||
ParentFolderFilterPanel.substringRadioButton.text=Substring
|
|
||||||
ParentFolderFilterPanel.fullRadioButton.text=Full
|
|
||||||
ParentFolderFilterPanel.parentLabel.text=(All will be used)
|
|
||||||
ParentFolderFilterPanel.addButton.text=Add
|
|
||||||
ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder:
|
|
||||||
ParentFolderFilterPanel.addButton.text_1=Add
|
|
||||||
ParentFolderFilterPanel.deleteButton.text_1=Delete
|
|
||||||
ParentFolderFilterPanel.excludeRadioButton.text_1=Exclude
|
|
||||||
ParentFolderFilterPanel.substringRadioButton.text_1=Substring
|
|
||||||
ParentFolderFilterPanel.includeRadioButton.text_1=Include
|
|
||||||
ParentFolderFilterPanel.fullRadioButton.text_1=Full
|
|
||||||
ParentFolderFilterPanel.parentLabel.text_1=(All will be used)
|
|
||||||
InterestingItemsFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
|
||||||
UserCreatedFilterPanel.userCreatedCheckbox.text_1=Possibly User Created
|
|
||||||
PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text=Past Occurrences:
|
|
||||||
ObjectDetectedFilterPanel.text=Object Detected:
|
|
||||||
DiscoveryDialog.sortingPanel.border.title=Step 3: Choose display settings
|
|
||||||
DiscoveryDialog.groupByLabel.text=Group By:
|
|
||||||
DiscoveryDialog.orderByLabel.text=Order Within Groups By:
|
|
||||||
DiscoveryDialog.orderGroupsByLabel.text=Order Groups By:
|
|
||||||
ImageFilterPanel.imageFiltersSplitPane.toolTipText=
|
|
||||||
DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which documents to show
|
|
||||||
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
|
|
||||||
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
|
|
||||||
DiscoveryDialog.step1Label.text=Step 1: Choose result type
|
|
||||||
ResultsSplitPaneDivider.hideButton.text=
|
|
||||||
ResultsSplitPaneDivider.showButton.text=
|
|
||||||
ResultsSplitPaneDivider.detailsLabel.text=Details Area
|
|
||||||
DiscoveryDialog.domainsButton.text=Domains
|
|
||||||
DomainFilterPanel.domainFiltersSplitPane.border.title=Step 2: Filter which domains to show
|
|
||||||
DomainFilterPanel.domainFiltersSplitPane.toolTipText=
|
|
||||||
DateFilterPanel.dateFilterCheckbox.text=Date Filter:
|
|
||||||
ArtifactTypeFilterPanel.artifactTypeCheckbox.text=Artifact Type:
|
|
||||||
DomainUniquenessFilterPanel.domainUniquenessCheckbox.text=Domain Uniqueness:
|
|
||||||
DateFilterPanel.mostRecentButton.text=Only last:
|
|
||||||
DateFilterPanel.daysLabel.text=days of activity
|
|
||||||
DateFilterPanel.endCheckBox.text=End:
|
|
||||||
DateFilterPanel.startCheckBox.text=Start:
|
|
||||||
VideoThumbnailPanel.bytes.text=bytes
|
|
||||||
VideoThumbnailPanel.deleted.text=All instances of file are deleted.
|
|
||||||
VideoThumbnailPanel.gigaBytes.text=GB
|
|
||||||
VideoThumbnailPanel.kiloBytes.text=KB
|
|
||||||
VideoThumbnailPanel.megaBytes.text=MB
|
|
||||||
# {0} - otherInstanceCount
|
|
||||||
VideoThumbnailPanel.nameLabel.more.text=\ and {0} more
|
|
||||||
# {0} - fileSize
|
|
||||||
# {1} - units
|
|
||||||
VideoThumbnailPanel.sizeLabel.text=Size: {0} {1}
|
|
||||||
VideoThumbnailPanel.terraBytes.text=TB
|
|
@ -1,253 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.discovery;
|
|
||||||
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTextPane;
|
|
||||||
import org.openide.util.ImageUtilities;
|
|
||||||
import org.openide.util.NbBundle;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class for the various user interface elements used by Discovery.
|
|
||||||
*/
|
|
||||||
final class DiscoveryUiUtils {
|
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(DiscoveryUiUtils.class.getName());
|
|
||||||
private static final int BYTE_UNIT_CONVERSION = 1000;
|
|
||||||
private static final int ICON_SIZE = 16;
|
|
||||||
private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png";
|
|
||||||
private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png";
|
|
||||||
private static final String DELETE_ICON_PATH = "org/sleuthkit/autopsy/images/file-icon-deleted.png";
|
|
||||||
private static final String UNSUPPORTED_DOC_PATH = "org/sleuthkit/autopsy/images/image-extraction-not-supported.png";
|
|
||||||
private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false));
|
|
||||||
private static final ImageIcon NOTABLE_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false));
|
|
||||||
private static final ImageIcon DELETED_ICON = new ImageIcon(ImageUtilities.loadImage(DELETE_ICON_PATH, false));
|
|
||||||
private static final ImageIcon UNSUPPORTED_DOCUMENT_THUMBNAIL = new ImageIcon(ImageUtilities.loadImage(UNSUPPORTED_DOC_PATH, false));
|
|
||||||
|
|
||||||
@NbBundle.Messages({"# {0} - fileSize",
|
|
||||||
"# {1} - units",
|
|
||||||
"DiscoveryUiUtility.sizeLabel.text=Size: {0} {1}",
|
|
||||||
"DiscoveryUiUtility.bytes.text=bytes",
|
|
||||||
"DiscoveryUiUtility.kiloBytes.text=KB",
|
|
||||||
"DiscoveryUiUtility.megaBytes.text=MB",
|
|
||||||
"DiscoveryUiUtility.gigaBytes.text=GB",
|
|
||||||
"DiscoveryUiUtility.terraBytes.text=TB"})
|
|
||||||
/**
|
|
||||||
* Convert a size in bytes to a string with representing the size in the
|
|
||||||
* largest units which represent the value as being greater than or equal to
|
|
||||||
* one. Result will be rounded down to the nearest whole number of those
|
|
||||||
* units.
|
|
||||||
*
|
|
||||||
* @param bytes Size in bytes.
|
|
||||||
*/
|
|
||||||
static String getFileSizeString(long bytes) {
|
|
||||||
long size = bytes;
|
|
||||||
int unitsSwitchValue = 0;
|
|
||||||
while (size > BYTE_UNIT_CONVERSION && unitsSwitchValue < 4) {
|
|
||||||
size /= BYTE_UNIT_CONVERSION;
|
|
||||||
unitsSwitchValue++;
|
|
||||||
}
|
|
||||||
String units;
|
|
||||||
switch (unitsSwitchValue) {
|
|
||||||
case 1:
|
|
||||||
units = Bundle.DiscoveryUiUtility_kiloBytes_text();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
units = Bundle.DiscoveryUiUtility_megaBytes_text();
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
units = Bundle.DiscoveryUiUtility_gigaBytes_text();
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
units = Bundle.DiscoveryUiUtility_terraBytes_text();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
units = Bundle.DiscoveryUiUtility_bytes_text();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return Bundle.DiscoveryUiUtility_sizeLabel_text(size, units);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the image to use when the document type does not support image
|
|
||||||
* extraction.
|
|
||||||
*
|
|
||||||
* @return An image that indicates we don't know if there are images.
|
|
||||||
*/
|
|
||||||
static ImageIcon getUnsupportedImageThumbnail() {
|
|
||||||
return UNSUPPORTED_DOCUMENT_THUMBNAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the names of the sets which exist in the case database for the
|
|
||||||
* specified artifact and attribute types.
|
|
||||||
*
|
|
||||||
* @param artifactType The artifact type to get the list of sets for.
|
|
||||||
* @param setNameAttribute The attribute type which contains the set names.
|
|
||||||
*
|
|
||||||
* @return A list of set names which exist in the case for the specified
|
|
||||||
* artifact and attribute types.
|
|
||||||
*
|
|
||||||
* @throws TskCoreException
|
|
||||||
*/
|
|
||||||
static List<String> getSetNames(BlackboardArtifact.ARTIFACT_TYPE artifactType, BlackboardAttribute.ATTRIBUTE_TYPE setNameAttribute) throws TskCoreException {
|
|
||||||
List<BlackboardArtifact> arts = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(artifactType);
|
|
||||||
List<String> setNames = new ArrayList<>();
|
|
||||||
for (BlackboardArtifact art : arts) {
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
|
||||||
if (attr.getAttributeType().getTypeID() == setNameAttribute.getTypeID()) {
|
|
||||||
String setName = attr.getValueString();
|
|
||||||
if (!setNames.contains(setName)) {
|
|
||||||
setNames.add(setName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collections.sort(setNames);
|
|
||||||
return setNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to see if point is on the icon.
|
|
||||||
*
|
|
||||||
* @param comp The component to check if the cursor is over the icon of
|
|
||||||
* @param point The point the cursor is at.
|
|
||||||
*
|
|
||||||
* @return True if the point is over the icon, false otherwise.
|
|
||||||
*/
|
|
||||||
static boolean isPointOnIcon(Component comp, Point point) {
|
|
||||||
return comp instanceof JComponent && point.x >= comp.getX() && point.x <= comp.getX() + ICON_SIZE && point.y >= comp.getY() && point.y <= comp.getY() + ICON_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to set the icon and tool tip text for a label to show deleted
|
|
||||||
* status.
|
|
||||||
*
|
|
||||||
* @param isDeleted True if the label should reflect deleted status,
|
|
||||||
* false otherwise.
|
|
||||||
* @param isDeletedLabel The label to set the icon and tooltip for.
|
|
||||||
*/
|
|
||||||
static void setDeletedIcon(boolean isDeleted, javax.swing.JLabel isDeletedLabel) {
|
|
||||||
if (isDeleted) {
|
|
||||||
isDeletedLabel.setIcon(DELETED_ICON);
|
|
||||||
isDeletedLabel.setToolTipText(Bundle.ImageThumbnailPanel_isDeleted_text());
|
|
||||||
} else {
|
|
||||||
isDeletedLabel.setIcon(null);
|
|
||||||
isDeletedLabel.setToolTipText(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to set the icon and tool tip text for a label to show the score.
|
|
||||||
*
|
|
||||||
* @param resultFile The result file which the label should reflect the
|
|
||||||
* score of.
|
|
||||||
* @param scoreLabel The label to set the icon and tooltip for.
|
|
||||||
*/
|
|
||||||
static void setScoreIcon(ResultFile resultFile, javax.swing.JLabel scoreLabel) {
|
|
||||||
switch (resultFile.getScore()) {
|
|
||||||
case NOTABLE_SCORE:
|
|
||||||
scoreLabel.setIcon(NOTABLE_SCORE_ICON);
|
|
||||||
break;
|
|
||||||
case INTERESTING_SCORE:
|
|
||||||
scoreLabel.setIcon(INTERESTING_SCORE_ICON);
|
|
||||||
break;
|
|
||||||
case NO_SCORE: // empty case - this is interpreted as an intentional fall-through
|
|
||||||
default:
|
|
||||||
scoreLabel.setIcon(null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
scoreLabel.setToolTipText(resultFile.getScoreDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the icons used by the UI.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static int getIconSize() {
|
|
||||||
return ICON_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to display an error message when the results of the
|
|
||||||
* Discovery Top component may be incomplete.
|
|
||||||
*/
|
|
||||||
static void displayErrorMessage(DiscoveryDialog dialog) {
|
|
||||||
//check if modules run and assemble message
|
|
||||||
try {
|
|
||||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
|
||||||
Map<Long, DataSourceModulesWrapper> dataSourceIngestModules = new HashMap<>();
|
|
||||||
for (DataSource dataSource : skCase.getDataSources()) {
|
|
||||||
dataSourceIngestModules.put(dataSource.getId(), new DataSourceModulesWrapper(dataSource.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IngestJobInfo jobInfo : skCase.getIngestJobs()) {
|
|
||||||
dataSourceIngestModules.get(jobInfo.getObjectId()).updateModulesRun(jobInfo);
|
|
||||||
}
|
|
||||||
String message = "";
|
|
||||||
for (DataSourceModulesWrapper dsmodulesWrapper : dataSourceIngestModules.values()) {
|
|
||||||
message += dsmodulesWrapper.getMessage();
|
|
||||||
}
|
|
||||||
if (!message.isEmpty()) {
|
|
||||||
JScrollPane messageScrollPane = new JScrollPane();
|
|
||||||
JTextPane messageTextPane = new JTextPane();
|
|
||||||
messageTextPane.setText(message);
|
|
||||||
messageTextPane.setVisible(true);
|
|
||||||
messageTextPane.setEditable(false);
|
|
||||||
messageTextPane.setCaretPosition(0);
|
|
||||||
messageScrollPane.setMaximumSize(new Dimension(600, 100));
|
|
||||||
messageScrollPane.setPreferredSize(new Dimension(600, 100));
|
|
||||||
messageScrollPane.setViewportView(messageTextPane);
|
|
||||||
JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE);
|
|
||||||
}
|
|
||||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex);
|
|
||||||
}
|
|
||||||
dialog.validateDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor for DiscoveryUiUtils utility class.
|
|
||||||
*/
|
|
||||||
private DiscoveryUiUtils() {
|
|
||||||
//private constructor in a utility class intentionally left blank
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -26,7 +26,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
|||||||
/**
|
/**
|
||||||
* Base class for the filters.
|
* Base class for the filters.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractFilter {
|
public abstract class AbstractFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns part of a query on the table that can be AND-ed with
|
* Returns part of a query on the table that can be AND-ed with
|
||||||
@ -35,7 +35,7 @@ abstract class AbstractFilter {
|
|||||||
* @return the SQL query or an empty string if there is no SQL query for
|
* @return the SQL query or an empty string if there is no SQL query for
|
||||||
* this filter.
|
* this filter.
|
||||||
*/
|
*/
|
||||||
abstract String getWhereClause();
|
public abstract String getWhereClause();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this filter needs to use the secondary, non-SQL method
|
* Indicates whether this filter needs to use the secondary, non-SQL method
|
||||||
@ -43,7 +43,7 @@ abstract class AbstractFilter {
|
|||||||
*
|
*
|
||||||
* @return false by default
|
* @return false by default
|
||||||
*/
|
*/
|
||||||
boolean useAlternateFilter() {
|
public boolean useAlternateFilter() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ abstract class AbstractFilter {
|
|||||||
*
|
*
|
||||||
* @throws FileSearchException
|
* @throws FileSearchException
|
||||||
*/
|
*/
|
||||||
List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws FileSearchException {
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
@ -71,5 +71,5 @@ abstract class AbstractFilter {
|
|||||||
*
|
*
|
||||||
* @return A description of the filter
|
* @return A description of the filter
|
||||||
*/
|
*/
|
||||||
abstract String getDesc();
|
public abstract String getDesc();
|
||||||
}
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -29,12 +29,12 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
|||||||
/**
|
/**
|
||||||
* Utility enums for searches made for attributes with Discovery.
|
* Utility enums for searches made for attributes with Discovery.
|
||||||
*/
|
*/
|
||||||
public class AttributeSearchData extends SearchData {
|
public class AttributeSearchData implements SearchData {
|
||||||
|
|
||||||
private static final Set<BlackboardArtifact.ARTIFACT_TYPE> DOMAIN_ARTIFACT_TYPES = EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY, BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG);
|
private static final Set<BlackboardArtifact.ARTIFACT_TYPE> DOMAIN_ARTIFACT_TYPES = EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY, BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ResultType getResultType() {
|
public ResultType getResultType() {
|
||||||
return ResultType.ATTRIBUTE;
|
return ResultType.ATTRIBUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ public class AttributeSearchData extends SearchData {
|
|||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"AttributeSearchData.AttributeType.Domain.displayName=Domain",
|
"AttributeSearchData.AttributeType.Domain.displayName=Domain",
|
||||||
"AttributeSearchData.AttributeType.Other.displayName=Other"})
|
"AttributeSearchData.AttributeType.Other.displayName=Other"})
|
||||||
enum AttributeType {
|
public enum AttributeType {
|
||||||
|
|
||||||
DOMAIN(0, Bundle.AttributeSearchData_AttributeType_Domain_displayName(), DOMAIN_ARTIFACT_TYPES),
|
DOMAIN(0, Bundle.AttributeSearchData_AttributeType_Domain_displayName(), DOMAIN_ARTIFACT_TYPES),
|
||||||
OTHER(1, Bundle.AttributeSearchData_AttributeType_Other_displayName(), new HashSet<>());
|
OTHER(1, Bundle.AttributeSearchData_AttributeType_Other_displayName(), new HashSet<>());
|
||||||
@ -64,7 +64,7 @@ public class AttributeSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return Collection of BlackboardArtifact types.
|
* @return Collection of BlackboardArtifact types.
|
||||||
*/
|
*/
|
||||||
Collection<BlackboardArtifact.ARTIFACT_TYPE> getBlackboardTypes() {
|
public Collection<BlackboardArtifact.ARTIFACT_TYPE> getBlackboardTypes() {
|
||||||
return Collections.unmodifiableCollection(artifactTypes);
|
return Collections.unmodifiableCollection(artifactTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,11 +78,11 @@ public class AttributeSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the rank (lower should be displayed first)
|
* @return the rank (lower should be displayed first)
|
||||||
*/
|
*/
|
||||||
int getRanking() {
|
public int getRanking() {
|
||||||
return ranking;
|
return ranking;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AttributeType fromBlackboardArtifact(final BlackboardArtifact.ARTIFACT_TYPE type) {
|
public static AttributeType fromBlackboardArtifact(final BlackboardArtifact.ARTIFACT_TYPE type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TSK_WEB_BOOKMARK:
|
case TSK_WEB_BOOKMARK:
|
||||||
return DOMAIN;
|
return DOMAIN;
|
@ -0,0 +1,115 @@
|
|||||||
|
AttributeSearchData.AttributeType.Domain.displayName=Domain
|
||||||
|
AttributeSearchData.AttributeType.Other.displayName=Other
|
||||||
|
DiscoveryKeyUtils.FileTagGroupKey.noSets=None
|
||||||
|
DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files
|
||||||
|
FileGroup.groupSortingAlgorithm.groupName.text=Group Name
|
||||||
|
FileGroup.groupSortingAlgorithm.groupSize.text=Group Size
|
||||||
|
# {0} - Data source name
|
||||||
|
# {1} - Data source ID
|
||||||
|
FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})
|
||||||
|
# {0} - Data source ID
|
||||||
|
FileSearch.DataSourceGroupKey.idOnly=Data source (ID: {0})
|
||||||
|
FileSearch.documentSummary.noBytes=No bytes read for document, unable to display preview.
|
||||||
|
FileSearch.documentSummary.noPreview=No preview available.
|
||||||
|
FileSearch.GroupingAttributeType.datasource.displayName=Data Source
|
||||||
|
FileSearch.GroupingAttributeType.fileType.displayName=File Type
|
||||||
|
FileSearch.GroupingAttributeType.frequency.displayName=Past Occurrences
|
||||||
|
FileSearch.GroupingAttributeType.hash.displayName=Hash Set
|
||||||
|
FileSearch.GroupingAttributeType.interestingItem.displayName=Interesting Item
|
||||||
|
FileSearch.GroupingAttributeType.keywordList.displayName=Keyword
|
||||||
|
FileSearch.GroupingAttributeType.none.displayName=None
|
||||||
|
FileSearch.GroupingAttributeType.object.displayName=Object Detected
|
||||||
|
FileSearch.GroupingAttributeType.parent.displayName=Parent Folder
|
||||||
|
FileSearch.GroupingAttributeType.size.displayName=File Size
|
||||||
|
FileSearch.GroupingAttributeType.tag.displayName=Tag
|
||||||
|
FileSearch.HashHitsGroupKey.noHashHits=None
|
||||||
|
FileSearch.InterestingItemGroupKey.noSets=None
|
||||||
|
FileSearch.KeywordListGroupKey.noKeywords=None
|
||||||
|
FileSearch.ObjectDetectedGroupKey.noSets=None
|
||||||
|
FileSearchData.FileSize.100kbto1mb=: 100KB-1MB
|
||||||
|
FileSearchData.FileSize.100mbto1gb=: 100MB-1GB
|
||||||
|
FileSearchData.FileSize.10PlusGb=: 10GB+
|
||||||
|
FileSearchData.FileSize.16kbto100kb=: 16-100KB
|
||||||
|
FileSearchData.FileSize.1gbto5gb=: 1-5GB
|
||||||
|
FileSearchData.FileSize.1mbto50mb=: 1-50MB
|
||||||
|
FileSearchData.FileSize.200PlusMb=: 200MB+
|
||||||
|
FileSearchData.FileSize.500kbto100mb=: 500KB-100MB
|
||||||
|
FileSearchData.FileSize.50mbto200mb=: 50-200MB
|
||||||
|
FileSearchData.FileSize.5gbto10gb=: 5-10GB
|
||||||
|
FileSearchData.FileSize.LARGE.displayName=Large
|
||||||
|
FileSearchData.FileSize.MEDIUM.displayName=Medium
|
||||||
|
FileSearchData.FileSize.SMALL.displayName=Small
|
||||||
|
FileSearchData.FileSize.upTo16kb=: 0-16KB
|
||||||
|
FileSearchData.FileSize.upTo500kb=: 0-500KB
|
||||||
|
FileSearchData.FileSize.XLARGE.displayName=XLarge
|
||||||
|
FileSearchData.FileSize.XSMALL.displayName=XSmall
|
||||||
|
FileSearchData.FileSize.XXLARGE.displayName=XXLarge
|
||||||
|
FileSearchData.FileType.Audio.displayName=Audio
|
||||||
|
FileSearchData.FileType.Documents.displayName=Documents
|
||||||
|
FileSearchData.FileType.Executables.displayName=Executables
|
||||||
|
FileSearchData.FileType.Image.displayName=Image
|
||||||
|
FileSearchData.FileType.Other.displayName=Other/Unknown
|
||||||
|
FileSearchData.FileType.Video.displayName=Video
|
||||||
|
FileSearchData.Frequency.common.displayName=Common (11 - 100)
|
||||||
|
FileSearchData.Frequency.known.displayName=Known (NSRL)
|
||||||
|
FileSearchData.Frequency.rare.displayName=Rare (2-10)
|
||||||
|
FileSearchData.Frequency.unique.displayName=Unique (1)
|
||||||
|
FileSearchData.Frequency.unknown.displayName=Unknown
|
||||||
|
FileSearchData.Frequency.verycommon.displayName=Very Common (100+)
|
||||||
|
FileSearchData.Score.interesting.displayName=Interesting
|
||||||
|
FileSearchData.Score.notable.displayName=Notable
|
||||||
|
FileSearchData.Score.unknown.displayName=Unknown
|
||||||
|
FileSearchFiltering.concatenateSetNamesForDisplay.comma=,
|
||||||
|
# {0} - filters
|
||||||
|
FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}
|
||||||
|
FileSearchFiltering.KnownFilter.desc=which are not known
|
||||||
|
FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable
|
||||||
|
# {0} - tag names
|
||||||
|
FileSearchFiltering.TagsFilter.desc=Tagged {0}
|
||||||
|
FileSearchFiltering.TagsFilter.or=,
|
||||||
|
FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data
|
||||||
|
FileSorter.SortingMethod.datasource.displayName=Data Source
|
||||||
|
FileSorter.SortingMethod.filename.displayName=File Name
|
||||||
|
FileSorter.SortingMethod.filesize.displayName=File Size
|
||||||
|
FileSorter.SortingMethod.filetype.displayName=File Type
|
||||||
|
FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency
|
||||||
|
FileSorter.SortingMethod.fullPath.displayName=Full Path
|
||||||
|
FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names
|
||||||
|
ResultFile.score.interestingResult.description=At least one instance of the file has an interesting result associated with it.
|
||||||
|
ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.
|
||||||
|
ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag.
|
||||||
|
ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.
|
||||||
|
# {0} - Data source name
|
||||||
|
# {1} - Data source ID
|
||||||
|
SearchFiltering.DataSourceFilter.datasource={0}({1})
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.DataSourceFilter.desc=Data source(s): {0}
|
||||||
|
SearchFiltering.DataSourceFilter.or=,
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.FileTypeFilter.desc=Type: {0}
|
||||||
|
SearchFiltering.FileTypeFilter.or=,
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.FrequencyFilter.desc=Past occurrences: {0}
|
||||||
|
SearchFiltering.FrequencyFilter.or=,
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.ParentFilter.desc=Paths matching: {0}
|
||||||
|
SearchFiltering.ParentFilter.exact=(exact match)
|
||||||
|
SearchFiltering.ParentFilter.excluded=(excluded)
|
||||||
|
SearchFiltering.ParentFilter.included=(included)
|
||||||
|
SearchFiltering.ParentFilter.or=,
|
||||||
|
SearchFiltering.ParentFilter.substring=(substring)
|
||||||
|
SearchFiltering.ParentSearchTerm.excludeString=\ (exclude)
|
||||||
|
SearchFiltering.ParentSearchTerm.fullString=\ (exact)
|
||||||
|
SearchFiltering.ParentSearchTerm.includeString=\ (include)
|
||||||
|
SearchFiltering.ParentSearchTerm.subString=\ (substring)
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.ScoreFilter.desc=Score(s) of : {0}
|
||||||
|
# {0} - filters
|
||||||
|
SearchFiltering.SizeFilter.desc=Size(s): {0}
|
||||||
|
SearchFiltering.SizeFilter.or=,
|
@ -16,22 +16,22 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.sleuthkit.autopsy.discovery.AttributeSearchData.AttributeType;
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData.AttributeType;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType;
|
||||||
import org.sleuthkit.autopsy.discovery.SearchData.ResultType;
|
import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to handle event bus and events for discovery tool.
|
* Class to handle event bus and events for discovery tool.
|
||||||
*/
|
*/
|
||||||
final class DiscoveryEventUtils {
|
public final class DiscoveryEventUtils {
|
||||||
|
|
||||||
private final static EventBus discoveryEventBus = new EventBus();
|
private final static EventBus discoveryEventBus = new EventBus();
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The discovery event bus.
|
* @return The discovery event bus.
|
||||||
*/
|
*/
|
||||||
static EventBus getDiscoveryEventBus() {
|
public static EventBus getDiscoveryEventBus() {
|
||||||
return discoveryEventBus;
|
return discoveryEventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal the start of a search being performed.
|
* Event to signal the start of a search being performed.
|
||||||
*/
|
*/
|
||||||
static final class SearchStartedEvent {
|
public static final class SearchStartedEvent {
|
||||||
|
|
||||||
private final ResultType resultType;
|
private final ResultType resultType;
|
||||||
private final FileType fileType;
|
private final FileType fileType;
|
||||||
@ -65,7 +65,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @param type The type of file the search event is for.
|
* @param type The type of file the search event is for.
|
||||||
*/
|
*/
|
||||||
SearchStartedEvent(ResultType resultType, FileType fileType, AttributeType attributeType) {
|
public SearchStartedEvent(ResultType resultType, FileType fileType, AttributeType attributeType) {
|
||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
this.fileType = fileType;
|
this.fileType = fileType;
|
||||||
this.attributeType = attributeType;
|
this.attributeType = attributeType;
|
||||||
@ -76,7 +76,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The result type, either FILES, or ATTRIBUTES.
|
* @return The result type, either FILES, or ATTRIBUTES.
|
||||||
*/
|
*/
|
||||||
ResultType getResultType() {
|
public ResultType getResultType() {
|
||||||
return resultType;
|
return resultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The type of files being searched for.
|
* @return The type of files being searched for.
|
||||||
*/
|
*/
|
||||||
FileType getFileType() {
|
public FileType getFileType() {
|
||||||
return fileType;
|
return fileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The type of attribute being searched for.
|
* @return The type of attribute being searched for.
|
||||||
*/
|
*/
|
||||||
AttributeType getAttributeType() {
|
public AttributeType getAttributeType() {
|
||||||
return attributeType;
|
return attributeType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,12 +102,12 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal that the Instances list should have selection cleared.
|
* Event to signal that the Instances list should have selection cleared.
|
||||||
*/
|
*/
|
||||||
static final class ClearInstanceSelectionEvent {
|
public static final class ClearInstanceSelectionEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new ClearInstanceSelectionEvent.
|
* Construct a new ClearInstanceSelectionEvent.
|
||||||
*/
|
*/
|
||||||
ClearInstanceSelectionEvent() {
|
public ClearInstanceSelectionEvent() {
|
||||||
//no arg constructor
|
//no arg constructor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,21 +115,21 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal that the Instances list should be populated.
|
* Event to signal that the Instances list should be populated.
|
||||||
*/
|
*/
|
||||||
static final class PopulateInstancesListEvent {
|
public static final class PopulateInstancesListEvent {
|
||||||
|
|
||||||
private final List<AbstractFile> instances;
|
private final List<AbstractFile> instances;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new PopulateInstancesListEvent.
|
* Construct a new PopulateInstancesListEvent.
|
||||||
*/
|
*/
|
||||||
PopulateInstancesListEvent(List<AbstractFile> files) {
|
public PopulateInstancesListEvent(List<AbstractFile> files) {
|
||||||
instances = files;
|
instances = files;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the instances
|
* @return the instances
|
||||||
*/
|
*/
|
||||||
List<AbstractFile> getInstances() {
|
public List<AbstractFile> getInstances() {
|
||||||
return Collections.unmodifiableList(instances);
|
return Collections.unmodifiableList(instances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal the completion of a search being performed.
|
* Event to signal the completion of a search being performed.
|
||||||
*/
|
*/
|
||||||
static final class SearchCompleteEvent {
|
public static final class SearchCompleteEvent {
|
||||||
|
|
||||||
private final Map<GroupKey, Integer> groupMap;
|
private final Map<GroupKey, Integer> groupMap;
|
||||||
private final List<AbstractFilter> searchFilters;
|
private final List<AbstractFilter> searchFilters;
|
||||||
@ -156,7 +156,7 @@ final class DiscoveryEventUtils {
|
|||||||
* @param groupSort The sorting algorithm used for groups.
|
* @param groupSort The sorting algorithm used for groups.
|
||||||
* @param fileSortMethod The sorting method used for files.
|
* @param fileSortMethod The sorting method used for files.
|
||||||
*/
|
*/
|
||||||
SearchCompleteEvent(Map<GroupKey, Integer> groupMap, List<AbstractFilter> searchfilters,
|
public SearchCompleteEvent(Map<GroupKey, Integer> groupMap, List<AbstractFilter> searchfilters,
|
||||||
FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort,
|
FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort,
|
||||||
FileSorter.SortingMethod fileSortMethod) {
|
FileSorter.SortingMethod fileSortMethod) {
|
||||||
this.groupMap = groupMap;
|
this.groupMap = groupMap;
|
||||||
@ -171,7 +171,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The map of groups which were found by the search.
|
* @return The map of groups which were found by the search.
|
||||||
*/
|
*/
|
||||||
Map<GroupKey, Integer> getGroupMap() {
|
public Map<GroupKey, Integer> getGroupMap() {
|
||||||
return Collections.unmodifiableMap(groupMap);
|
return Collections.unmodifiableMap(groupMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The search filters which were used by the search.
|
* @return The search filters which were used by the search.
|
||||||
*/
|
*/
|
||||||
List<AbstractFilter> getFilters() {
|
public List<AbstractFilter> getFilters() {
|
||||||
return Collections.unmodifiableList(searchFilters);
|
return Collections.unmodifiableList(searchFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The grouping attribute used by the search.
|
* @return The grouping attribute used by the search.
|
||||||
*/
|
*/
|
||||||
FileSearch.AttributeType getGroupingAttr() {
|
public FileSearch.AttributeType getGroupingAttr() {
|
||||||
return groupingAttribute;
|
return groupingAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The sorting algorithm used for groups.
|
* @return The sorting algorithm used for groups.
|
||||||
*/
|
*/
|
||||||
FileGroup.GroupSortingAlgorithm getGroupSort() {
|
public FileGroup.GroupSortingAlgorithm getGroupSort() {
|
||||||
return groupSort;
|
return groupSort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The sorting method used for files.
|
* @return The sorting method used for files.
|
||||||
*/
|
*/
|
||||||
FileSorter.SortingMethod getFileSort() {
|
public FileSorter.SortingMethod getFileSort() {
|
||||||
return fileSortMethod;
|
return fileSortMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ final class DiscoveryEventUtils {
|
|||||||
* Event to signal the completion of page retrieval and include the page
|
* Event to signal the completion of page retrieval and include the page
|
||||||
* contents.
|
* contents.
|
||||||
*/
|
*/
|
||||||
static final class PageRetrievedEvent {
|
public static final class PageRetrievedEvent {
|
||||||
|
|
||||||
private final List<ResultFile> results;
|
private final List<ResultFile> results;
|
||||||
private final int page;
|
private final int page;
|
||||||
@ -230,7 +230,7 @@ final class DiscoveryEventUtils {
|
|||||||
* @param page The number of the page which was retrieved.
|
* @param page The number of the page which was retrieved.
|
||||||
* @param results The list of files in the page retrieved.
|
* @param results The list of files in the page retrieved.
|
||||||
*/
|
*/
|
||||||
PageRetrievedEvent(FileType resultType, int page, List<ResultFile> results) {
|
public PageRetrievedEvent(FileType resultType, int page, List<ResultFile> results) {
|
||||||
this.results = results;
|
this.results = results;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
@ -241,7 +241,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The list of files in the page retrieved.
|
* @return The list of files in the page retrieved.
|
||||||
*/
|
*/
|
||||||
List<ResultFile> getSearchResults() {
|
public List<ResultFile> getSearchResults() {
|
||||||
return Collections.unmodifiableList(results);
|
return Collections.unmodifiableList(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The number of the page which was retrieved.
|
* @return The number of the page which was retrieved.
|
||||||
*/
|
*/
|
||||||
int getPageNumber() {
|
public int getPageNumber() {
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The type of files which exist in the page.
|
* @return The type of files which exist in the page.
|
||||||
*/
|
*/
|
||||||
FileType getType() {
|
public FileType getType() {
|
||||||
return resultType;
|
return resultType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,12 +267,12 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal that there were no results for the search.
|
* Event to signal that there were no results for the search.
|
||||||
*/
|
*/
|
||||||
static final class NoResultsEvent {
|
public static final class NoResultsEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new NoResultsEvent.
|
* Construct a new NoResultsEvent.
|
||||||
*/
|
*/
|
||||||
NoResultsEvent() {
|
public NoResultsEvent() {
|
||||||
//no arg constructor
|
//no arg constructor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,12 +280,12 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal that a search has been cancelled
|
* Event to signal that a search has been cancelled
|
||||||
*/
|
*/
|
||||||
static final class SearchCancelledEvent {
|
public static final class SearchCancelledEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new SearchCancelledEvent.
|
* Construct a new SearchCancelledEvent.
|
||||||
*/
|
*/
|
||||||
SearchCancelledEvent() {
|
public SearchCancelledEvent() {
|
||||||
//no arg constructor
|
//no arg constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal that a group has been selected.
|
* Event to signal that a group has been selected.
|
||||||
*/
|
*/
|
||||||
static final class GroupSelectedEvent {
|
public static final class GroupSelectedEvent {
|
||||||
|
|
||||||
private final FileType resultType;
|
private final FileType resultType;
|
||||||
private final GroupKey groupKey;
|
private final GroupKey groupKey;
|
||||||
@ -318,7 +318,7 @@ final class DiscoveryEventUtils {
|
|||||||
* selected.
|
* selected.
|
||||||
* @param resultType The type of files which exist in the group.
|
* @param resultType The type of files which exist in the group.
|
||||||
*/
|
*/
|
||||||
GroupSelectedEvent(List<AbstractFilter> searchfilters,
|
public GroupSelectedEvent(List<AbstractFilter> searchfilters,
|
||||||
FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort,
|
FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort,
|
||||||
FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, FileType resultType) {
|
FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, FileType resultType) {
|
||||||
this.searchfilters = searchfilters;
|
this.searchfilters = searchfilters;
|
||||||
@ -335,7 +335,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The type of files which exist in the group.
|
* @return The type of files which exist in the group.
|
||||||
*/
|
*/
|
||||||
FileType getResultType() {
|
public FileType getResultType() {
|
||||||
return resultType;
|
return resultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ final class DiscoveryEventUtils {
|
|||||||
* @return The group key which is used to uniquely identify the group
|
* @return The group key which is used to uniquely identify the group
|
||||||
* selected.
|
* selected.
|
||||||
*/
|
*/
|
||||||
GroupKey getGroupKey() {
|
public GroupKey getGroupKey() {
|
||||||
return groupKey;
|
return groupKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The number of files in the group which was selected.
|
* @return The number of files in the group which was selected.
|
||||||
*/
|
*/
|
||||||
int getGroupSize() {
|
public int getGroupSize() {
|
||||||
return groupSize;
|
return groupSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +364,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The sorting algorithm used for groups.
|
* @return The sorting algorithm used for groups.
|
||||||
*/
|
*/
|
||||||
FileGroup.GroupSortingAlgorithm getGroupSort() {
|
public FileGroup.GroupSortingAlgorithm getGroupSort() {
|
||||||
return groupSort;
|
return groupSort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +373,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The sorting method used for files.
|
* @return The sorting method used for files.
|
||||||
*/
|
*/
|
||||||
FileSorter.SortingMethod getFileSort() {
|
public FileSorter.SortingMethod getFileSort() {
|
||||||
return fileSortMethod;
|
return fileSortMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The search filters which were used by the search.
|
* @return The search filters which were used by the search.
|
||||||
*/
|
*/
|
||||||
List<AbstractFilter> getFilters() {
|
public List<AbstractFilter> getFilters() {
|
||||||
return Collections.unmodifiableList(searchfilters);
|
return Collections.unmodifiableList(searchfilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +391,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return The grouping attribute used by the search.
|
* @return The grouping attribute used by the search.
|
||||||
*/
|
*/
|
||||||
FileSearch.AttributeType getGroupingAttr() {
|
public FileSearch.AttributeType getGroupingAttr() {
|
||||||
return groupingAttribute;
|
return groupingAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,7 +400,7 @@ final class DiscoveryEventUtils {
|
|||||||
/**
|
/**
|
||||||
* Event to signal that the visibility of the Details area should change.
|
* Event to signal that the visibility of the Details area should change.
|
||||||
*/
|
*/
|
||||||
static class DetailsVisibleEvent {
|
public static class DetailsVisibleEvent {
|
||||||
|
|
||||||
private final boolean showDetailsArea;
|
private final boolean showDetailsArea;
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ final class DiscoveryEventUtils {
|
|||||||
* @param isVisible True if the details area should be visible, false
|
* @param isVisible True if the details area should be visible, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
DetailsVisibleEvent(boolean isVisible) {
|
public DetailsVisibleEvent(boolean isVisible) {
|
||||||
showDetailsArea = isVisible;
|
showDetailsArea = isVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ final class DiscoveryEventUtils {
|
|||||||
*
|
*
|
||||||
* @return True if the details area should be visible, false otherwise.
|
* @return True if the details area should be visible, false otherwise.
|
||||||
*/
|
*/
|
||||||
boolean isShowDetailsArea() {
|
public boolean isShowDetailsArea() {
|
||||||
return showDetailsArea;
|
return showDetailsArea;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,944 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy
|
||||||
|
*
|
||||||
|
* Copyright 2020 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.discovery.search;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for constructing keys for groups and searches.
|
||||||
|
*/
|
||||||
|
public class DiscoveryKeyUtils {
|
||||||
|
|
||||||
|
private final static Logger logger = Logger.getLogger(DiscoveryKeyUtils.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a key for a specific search for a specific user.
|
||||||
|
*/
|
||||||
|
static class SearchKey implements Comparable<SearchKey> {
|
||||||
|
|
||||||
|
private final String keyString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new SearchKey with all information that defines a search.
|
||||||
|
*
|
||||||
|
* @param userName The name of the user performing the search.
|
||||||
|
* @param filters The FileFilters being used for the search.
|
||||||
|
* @param groupAttributeType The AttributeType to group by.
|
||||||
|
* @param groupSortingType The algorithm to sort the groups by.
|
||||||
|
* @param fileSortingMethod The method to sort the files by.
|
||||||
|
*/
|
||||||
|
SearchKey(String userName, List<AbstractFilter> filters,
|
||||||
|
FileSearch.AttributeType groupAttributeType,
|
||||||
|
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||||
|
FileSorter.SortingMethod fileSortingMethod) {
|
||||||
|
StringBuilder searchStringBuilder = new StringBuilder();
|
||||||
|
searchStringBuilder.append(userName);
|
||||||
|
for (AbstractFilter filter : filters) {
|
||||||
|
searchStringBuilder.append(filter.toString());
|
||||||
|
}
|
||||||
|
searchStringBuilder.append(groupAttributeType).append(groupSortingType).append(fileSortingMethod);
|
||||||
|
keyString = searchStringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(SearchKey otherSearchKey) {
|
||||||
|
return getKeyString().compareTo(otherSearchKey.getKeyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof SearchKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchKey otherSearchKey = (SearchKey) otherKey;
|
||||||
|
return getKeyString().equals(otherSearchKey.getKeyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 5;
|
||||||
|
hash = 79 * hash + Objects.hashCode(getKeyString());
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the keyString
|
||||||
|
*/
|
||||||
|
String getKeyString() {
|
||||||
|
return keyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key used for grouping for each attribute type.
|
||||||
|
*/
|
||||||
|
public abstract static class GroupKey implements Comparable<GroupKey> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string version of the group key for display. Each display
|
||||||
|
* name should correspond to a unique GroupKey object.
|
||||||
|
*
|
||||||
|
* @return The display name for this key
|
||||||
|
*/
|
||||||
|
abstract String getDisplayName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses must implement equals().
|
||||||
|
*
|
||||||
|
* @param otherKey
|
||||||
|
*
|
||||||
|
* @return true if the keys are equal, false otherwise
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
abstract public boolean equals(Object otherKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses must implement hashCode().
|
||||||
|
*
|
||||||
|
* @return the hash code
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
abstract public int hashCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It should not happen with the current setup, but we need to cover the
|
||||||
|
* case where two different GroupKey subclasses are compared against
|
||||||
|
* each other. Use a lexicographic comparison on the class names.
|
||||||
|
*
|
||||||
|
* @param otherGroupKey The other group key
|
||||||
|
*
|
||||||
|
* @return result of alphabetical comparison on the class name
|
||||||
|
*/
|
||||||
|
int compareClassNames(GroupKey otherGroupKey) {
|
||||||
|
return this.getClass().getName().compareTo(otherGroupKey.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getDisplayName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a file size group
|
||||||
|
*/
|
||||||
|
static class FileSizeGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final FileSearchData.FileSize fileSize;
|
||||||
|
|
||||||
|
FileSizeGroupKey(ResultFile file) {
|
||||||
|
if (file.getFileType() == FileSearchData.FileType.VIDEO) {
|
||||||
|
fileSize = FileSearchData.FileSize.fromVideoSize(file.getFirstInstance().getSize());
|
||||||
|
} else {
|
||||||
|
fileSize = FileSearchData.FileSize.fromImageSize(file.getFirstInstance().getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getFileSize().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof FileSizeGroupKey) {
|
||||||
|
FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherGroupKey;
|
||||||
|
return Integer.compare(getFileSize().getRanking(), otherFileSizeGroupKey.getFileSize().getRanking());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof FileSizeGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSizeGroupKey otherFileSizeGroupKey = (FileSizeGroupKey) otherKey;
|
||||||
|
return getFileSize().equals(otherFileSizeGroupKey.getFileSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getFileSize().getRanking());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileSize
|
||||||
|
*/
|
||||||
|
FileSearchData.FileSize getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a file type group
|
||||||
|
*/
|
||||||
|
static class FileTypeGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final FileSearchData.FileType fileType;
|
||||||
|
|
||||||
|
FileTypeGroupKey(ResultFile file) {
|
||||||
|
fileType = file.getFileType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getFileType().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof FileTypeGroupKey) {
|
||||||
|
FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherGroupKey;
|
||||||
|
return Integer.compare(getFileType().getRanking(), otherFileTypeGroupKey.getFileType().getRanking());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof FileTypeGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileTypeGroupKey otherFileTypeGroupKey = (FileTypeGroupKey) otherKey;
|
||||||
|
return getFileType().equals(otherFileTypeGroupKey.getFileType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getFileType().getRanking());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileType
|
||||||
|
*/
|
||||||
|
FileSearchData.FileType getFileType() {
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a keyword list group
|
||||||
|
*/
|
||||||
|
static class KeywordListGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final List<String> keywordListNames;
|
||||||
|
private final String keywordListNamesString;
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"FileSearch.KeywordListGroupKey.noKeywords=None"})
|
||||||
|
KeywordListGroupKey(ResultFile file) {
|
||||||
|
keywordListNames = file.getKeywordListNames();
|
||||||
|
|
||||||
|
if (keywordListNames.isEmpty()) {
|
||||||
|
keywordListNamesString = Bundle.FileSearch_KeywordListGroupKey_noKeywords();
|
||||||
|
} else {
|
||||||
|
keywordListNamesString = String.join(",", keywordListNames); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getKeywordListNamesString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof KeywordListGroupKey) {
|
||||||
|
KeywordListGroupKey otherKeywordListNamesGroupKey = (KeywordListGroupKey) otherGroupKey;
|
||||||
|
|
||||||
|
// Put the empty list at the end
|
||||||
|
if (getKeywordListNames().isEmpty()) {
|
||||||
|
if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (otherKeywordListNamesGroupKey.getKeywordListNames().isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getKeywordListNamesString().compareTo(otherKeywordListNamesGroupKey.getKeywordListNamesString());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof KeywordListGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeywordListGroupKey otherKeywordListGroupKey = (KeywordListGroupKey) otherKey;
|
||||||
|
return getKeywordListNamesString().equals(otherKeywordListGroupKey.getKeywordListNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getKeywordListNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the keywordListNames
|
||||||
|
*/
|
||||||
|
List<String> getKeywordListNames() {
|
||||||
|
return Collections.unmodifiableList(keywordListNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the keywordListNamesString
|
||||||
|
*/
|
||||||
|
String getKeywordListNamesString() {
|
||||||
|
return keywordListNamesString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a file tag group
|
||||||
|
*/
|
||||||
|
static class FileTagGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final List<String> tagNames;
|
||||||
|
private final String tagNamesString;
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"DiscoveryKeyUtils.FileTagGroupKey.noSets=None"})
|
||||||
|
FileTagGroupKey(ResultFile file) {
|
||||||
|
tagNames = file.getTagNames();
|
||||||
|
|
||||||
|
if (tagNames.isEmpty()) {
|
||||||
|
tagNamesString = Bundle.DiscoveryKeyUtils_FileTagGroupKey_noSets();
|
||||||
|
} else {
|
||||||
|
tagNamesString = String.join(",", tagNames); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getTagNamesString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof FileTagGroupKey) {
|
||||||
|
FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherGroupKey;
|
||||||
|
|
||||||
|
// Put the empty list at the end
|
||||||
|
if (getTagNames().isEmpty()) {
|
||||||
|
if (otherFileTagGroupKey.getTagNames().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (otherFileTagGroupKey.getTagNames().isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getTagNamesString().compareTo(otherFileTagGroupKey.getTagNamesString());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof FileTagGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherKey;
|
||||||
|
return getTagNamesString().equals(otherFileTagGroupKey.getTagNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getTagNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tagNames
|
||||||
|
*/
|
||||||
|
List<String> getTagNames() {
|
||||||
|
return Collections.unmodifiableList(tagNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tagNamesString
|
||||||
|
*/
|
||||||
|
String getTagNamesString() {
|
||||||
|
return tagNamesString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a parent path group
|
||||||
|
*/
|
||||||
|
static class ParentPathGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private String parentPath;
|
||||||
|
private Long parentID;
|
||||||
|
|
||||||
|
ParentPathGroupKey(ResultFile file) {
|
||||||
|
Content parent;
|
||||||
|
try {
|
||||||
|
parent = file.getFirstInstance().getParent();
|
||||||
|
} catch (TskCoreException ignored) {
|
||||||
|
parent = null;
|
||||||
|
}
|
||||||
|
//Find the directory this file is in if it is an embedded file
|
||||||
|
while (parent != null && parent instanceof AbstractFile && ((AbstractFile) parent).isFile()) {
|
||||||
|
try {
|
||||||
|
parent = parent.getParent();
|
||||||
|
} catch (TskCoreException ignored) {
|
||||||
|
parent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setParentPathAndID(parent, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to set the parent path and parent ID.
|
||||||
|
*
|
||||||
|
* @param parent The parent content object.
|
||||||
|
* @param file The ResultFile object.
|
||||||
|
*/
|
||||||
|
private void setParentPathAndID(Content parent, ResultFile file) {
|
||||||
|
if (parent != null) {
|
||||||
|
try {
|
||||||
|
parentPath = parent.getUniquePath();
|
||||||
|
parentID = parent.getId();
|
||||||
|
} catch (TskCoreException ignored) {
|
||||||
|
//catch block left blank purposefully next if statement will handle case when exception takes place as well as when parent is null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (parentPath == null) {
|
||||||
|
if (file.getFirstInstance().getParentPath() != null) {
|
||||||
|
parentPath = file.getFirstInstance().getParentPath();
|
||||||
|
} else {
|
||||||
|
parentPath = ""; // NON-NLS
|
||||||
|
}
|
||||||
|
parentID = -1L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getParentPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof ParentPathGroupKey) {
|
||||||
|
ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherGroupKey;
|
||||||
|
int comparisonResult = getParentPath().compareTo(otherParentPathGroupKey.getParentPath());
|
||||||
|
if (comparisonResult == 0) {
|
||||||
|
comparisonResult = getParentID().compareTo(otherParentPathGroupKey.getParentID());
|
||||||
|
}
|
||||||
|
return comparisonResult;
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof ParentPathGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherKey;
|
||||||
|
return getParentPath().equals(otherParentPathGroupKey.getParentPath()) && getParentID().equals(otherParentPathGroupKey.getParentID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hashCode = 11;
|
||||||
|
hashCode = 61 * hashCode + Objects.hash(getParentPath());
|
||||||
|
hashCode = 61 * hashCode + Objects.hash(getParentID());
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parentPath
|
||||||
|
*/
|
||||||
|
String getParentPath() {
|
||||||
|
return parentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parentID
|
||||||
|
*/
|
||||||
|
Long getParentID() {
|
||||||
|
return parentID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a data source group
|
||||||
|
*/
|
||||||
|
static class DataSourceGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final long dataSourceID;
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"# {0} - Data source name",
|
||||||
|
"# {1} - Data source ID",
|
||||||
|
"FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
|
||||||
|
"# {0} - Data source ID",
|
||||||
|
"FileSearch.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
|
||||||
|
DataSourceGroupKey(ResultFile file) {
|
||||||
|
dataSourceID = file.getFirstInstance().getDataSourceObjectId();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// The data source should be cached so this won't actually be a database query.
|
||||||
|
Content ds = file.getFirstInstance().getDataSource();
|
||||||
|
displayName = Bundle.FileSearch_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
|
||||||
|
displayName = Bundle.FileSearch_DataSourceGroupKey_idOnly(dataSourceID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof DataSourceGroupKey) {
|
||||||
|
DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherGroupKey;
|
||||||
|
return Long.compare(getDataSourceID(), otherDataSourceGroupKey.getDataSourceID());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof DataSourceGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSourceGroupKey otherDataSourceGroupKey = (DataSourceGroupKey) otherKey;
|
||||||
|
return getDataSourceID() == otherDataSourceGroupKey.getDataSourceID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getDataSourceID());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dataSourceID
|
||||||
|
*/
|
||||||
|
long getDataSourceID() {
|
||||||
|
return dataSourceID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy key for when there is no grouping. All files will have the same
|
||||||
|
* key.
|
||||||
|
*/
|
||||||
|
static class NoGroupingGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
NoGroupingGroupKey() {
|
||||||
|
// Nothing to save - all files will get the same GroupKey
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files"})
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return Bundle.DiscoveryKeyUtils_NoGroupingGroupKey_allFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
// As long as the other key is the same type, they are equal
|
||||||
|
if (otherGroupKey instanceof NoGroupingGroupKey) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// As long as the other key is the same type, they are equal
|
||||||
|
return otherKey instanceof NoGroupingGroupKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a central repository frequency group
|
||||||
|
*/
|
||||||
|
static class FrequencyGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final FileSearchData.Frequency frequency;
|
||||||
|
|
||||||
|
FrequencyGroupKey(ResultFile file) {
|
||||||
|
frequency = file.getFrequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getFrequency().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof FrequencyGroupKey) {
|
||||||
|
FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherGroupKey;
|
||||||
|
return Integer.compare(getFrequency().getRanking(), otherFrequencyGroupKey.getFrequency().getRanking());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof FrequencyGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherKey;
|
||||||
|
return getFrequency().equals(otherFrequencyGroupKey.getFrequency());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getFrequency().getRanking());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the frequency
|
||||||
|
*/
|
||||||
|
FileSearchData.Frequency getFrequency() {
|
||||||
|
return frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a hash hits group
|
||||||
|
*/
|
||||||
|
static class HashHitsGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final List<String> hashSetNames;
|
||||||
|
private final String hashSetNamesString;
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"FileSearch.HashHitsGroupKey.noHashHits=None"})
|
||||||
|
HashHitsGroupKey(ResultFile file) {
|
||||||
|
hashSetNames = file.getHashSetNames();
|
||||||
|
|
||||||
|
if (hashSetNames.isEmpty()) {
|
||||||
|
hashSetNamesString = Bundle.FileSearch_HashHitsGroupKey_noHashHits();
|
||||||
|
} else {
|
||||||
|
hashSetNamesString = String.join(",", hashSetNames); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getHashSetNamesString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof HashHitsGroupKey) {
|
||||||
|
HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherGroupKey;
|
||||||
|
|
||||||
|
// Put the empty list at the end
|
||||||
|
if (getHashSetNames().isEmpty()) {
|
||||||
|
if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (otherHashHitsGroupKey.getHashSetNames().isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getHashSetNamesString().compareTo(otherHashHitsGroupKey.getHashSetNamesString());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof HashHitsGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashHitsGroupKey otherHashHitsGroupKey = (HashHitsGroupKey) otherKey;
|
||||||
|
return getHashSetNamesString().equals(otherHashHitsGroupKey.getHashSetNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getHashSetNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the hashSetNames
|
||||||
|
*/
|
||||||
|
List<String> getHashSetNames() {
|
||||||
|
return Collections.unmodifiableList(hashSetNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the hashSetNamesString
|
||||||
|
*/
|
||||||
|
String getHashSetNamesString() {
|
||||||
|
return hashSetNamesString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing a interesting item set group
|
||||||
|
*/
|
||||||
|
static class InterestingItemGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final List<String> interestingItemSetNames;
|
||||||
|
private final String interestingItemSetNamesString;
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"FileSearch.InterestingItemGroupKey.noSets=None"})
|
||||||
|
InterestingItemGroupKey(ResultFile file) {
|
||||||
|
interestingItemSetNames = file.getInterestingSetNames();
|
||||||
|
|
||||||
|
if (interestingItemSetNames.isEmpty()) {
|
||||||
|
interestingItemSetNamesString = Bundle.FileSearch_InterestingItemGroupKey_noSets();
|
||||||
|
} else {
|
||||||
|
interestingItemSetNamesString = String.join(",", interestingItemSetNames); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getInterestingItemSetNamesString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof InterestingItemGroupKey) {
|
||||||
|
InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherGroupKey;
|
||||||
|
|
||||||
|
// Put the empty list at the end
|
||||||
|
if (this.getInterestingItemSetNames().isEmpty()) {
|
||||||
|
if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (otherInterestingItemGroupKey.getInterestingItemSetNames().isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getInterestingItemSetNamesString().compareTo(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof InterestingItemGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
InterestingItemGroupKey otherInterestingItemGroupKey = (InterestingItemGroupKey) otherKey;
|
||||||
|
return getInterestingItemSetNamesString().equals(otherInterestingItemGroupKey.getInterestingItemSetNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getInterestingItemSetNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the interestingItemSetNames
|
||||||
|
*/
|
||||||
|
List<String> getInterestingItemSetNames() {
|
||||||
|
return Collections.unmodifiableList(interestingItemSetNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the interestingItemSetNamesString
|
||||||
|
*/
|
||||||
|
String getInterestingItemSetNamesString() {
|
||||||
|
return interestingItemSetNamesString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key representing an object detected group
|
||||||
|
*/
|
||||||
|
static class ObjectDetectedGroupKey extends GroupKey {
|
||||||
|
|
||||||
|
private final List<String> objectDetectedNames;
|
||||||
|
private final String objectDetectedNamesString;
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"FileSearch.ObjectDetectedGroupKey.noSets=None"})
|
||||||
|
ObjectDetectedGroupKey(ResultFile file) {
|
||||||
|
objectDetectedNames = file.getObjectDetectedNames();
|
||||||
|
|
||||||
|
if (objectDetectedNames.isEmpty()) {
|
||||||
|
objectDetectedNamesString = Bundle.FileSearch_ObjectDetectedGroupKey_noSets();
|
||||||
|
} else {
|
||||||
|
objectDetectedNamesString = String.join(",", objectDetectedNames); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getDisplayName() {
|
||||||
|
return getObjectDetectedNamesString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
if (otherGroupKey instanceof ObjectDetectedGroupKey) {
|
||||||
|
ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherGroupKey;
|
||||||
|
|
||||||
|
// Put the empty list at the end
|
||||||
|
if (this.getObjectDetectedNames().isEmpty()) {
|
||||||
|
if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (otherObjectDetectedGroupKey.getObjectDetectedNames().isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getObjectDetectedNamesString().compareTo(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
|
||||||
|
} else {
|
||||||
|
return compareClassNames(otherGroupKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object otherKey) {
|
||||||
|
if (otherKey == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(otherKey instanceof ObjectDetectedGroupKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectDetectedGroupKey otherObjectDetectedGroupKey = (ObjectDetectedGroupKey) otherKey;
|
||||||
|
return getObjectDetectedNamesString().equals(otherObjectDetectedGroupKey.getObjectDetectedNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getObjectDetectedNamesString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the objectDetectedNames
|
||||||
|
*/
|
||||||
|
List<String> getObjectDetectedNames() {
|
||||||
|
return Collections.unmodifiableList(objectDetectedNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the objectDetectedNamesString
|
||||||
|
*/
|
||||||
|
String getObjectDetectedNamesString() {
|
||||||
|
return objectDetectedNamesString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor for GroupKeyUtils utility class.
|
||||||
|
*/
|
||||||
|
private DiscoveryKeyUtils() {
|
||||||
|
//private constructor in a utility class intentionally left blank
|
||||||
|
}
|
||||||
|
}
|
@ -16,21 +16,20 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for storing files that belong to a particular group.
|
* Class for storing files that belong to a particular group.
|
||||||
*/
|
*/
|
||||||
class FileGroup implements Comparable<FileGroup> {
|
public class FileGroup implements Comparable<FileGroup> {
|
||||||
|
|
||||||
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
||||||
private final GroupKey groupKey;
|
private final DiscoveryKeyUtils.GroupKey groupKey;
|
||||||
private final List<ResultFile> files;
|
private final List<ResultFile> files;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
* @param groupSortingType The method for sorting the group
|
* @param groupSortingType The method for sorting the group
|
||||||
* @param groupKey The GroupKey for this group
|
* @param groupKey The GroupKey for this group
|
||||||
*/
|
*/
|
||||||
FileGroup(FileGroup.GroupSortingAlgorithm groupSortingType, GroupKey groupKey) {
|
public FileGroup(FileGroup.GroupSortingAlgorithm groupSortingType, DiscoveryKeyUtils.GroupKey groupKey) {
|
||||||
this.groupSortingType = groupSortingType;
|
this.groupSortingType = groupSortingType;
|
||||||
this.groupKey = groupKey;
|
this.groupKey = groupKey;
|
||||||
files = new ArrayList<>();
|
files = new ArrayList<>();
|
||||||
@ -66,7 +65,7 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
*
|
*
|
||||||
* @return The display name of the group.
|
* @return The display name of the group.
|
||||||
*/
|
*/
|
||||||
String getDisplayName() {
|
public String getDisplayName() {
|
||||||
return displayName; // NON-NLS
|
return displayName; // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,14 +74,14 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
*
|
*
|
||||||
* @return The unique key for the group.
|
* @return The unique key for the group.
|
||||||
*/
|
*/
|
||||||
GroupKey getGroupKey() {
|
public DiscoveryKeyUtils.GroupKey getGroupKey() {
|
||||||
return groupKey;
|
return groupKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort all the files in the group
|
* Sort all the files in the group
|
||||||
*/
|
*/
|
||||||
void sortFiles(FileSorter sorter) {
|
public void sortFiles(FileSorter sorter) {
|
||||||
Collections.sort(files, sorter);
|
Collections.sort(files, sorter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
*/
|
*/
|
||||||
@Messages({"FileGroup.groupSortingAlgorithm.groupSize.text=Group Size",
|
@Messages({"FileGroup.groupSortingAlgorithm.groupSize.text=Group Size",
|
||||||
"FileGroup.groupSortingAlgorithm.groupName.text=Group Name"})
|
"FileGroup.groupSortingAlgorithm.groupName.text=Group Name"})
|
||||||
enum GroupSortingAlgorithm {
|
public enum GroupSortingAlgorithm {
|
||||||
BY_GROUP_NAME(Bundle.FileGroup_groupSortingAlgorithm_groupName_text()), // Sort using the group key (for example, if grouping by size sort from largest to smallest value)
|
BY_GROUP_NAME(Bundle.FileGroup_groupSortingAlgorithm_groupName_text()), // Sort using the group key (for example, if grouping by size sort from largest to smallest value)
|
||||||
BY_GROUP_SIZE(Bundle.FileGroup_groupSortingAlgorithm_groupSize_text()); // Sort from largest to smallest group
|
BY_GROUP_SIZE(Bundle.FileGroup_groupSortingAlgorithm_groupSize_text()); // Sort from largest to smallest group
|
||||||
|
|
||||||
@ -169,7 +168,7 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
*
|
*
|
||||||
* @return List of ResultFile objects
|
* @return List of ResultFile objects
|
||||||
*/
|
*/
|
||||||
List<ResultFile> getFiles() {
|
public List<ResultFile> getFiles() {
|
||||||
return Collections.unmodifiableList(files);
|
return Collections.unmodifiableList(files);
|
||||||
}
|
}
|
||||||
|
|
936
Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java
Normal file
936
Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java
Normal file
@ -0,0 +1,936 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020 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.discovery.search;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.Frequency;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.CaseDbAccessManager;
|
||||||
|
import org.sleuthkit.datamodel.ContentTag;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.SearchKey;
|
||||||
|
import org.sleuthkit.autopsy.textsummarizer.TextSummarizer;
|
||||||
|
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main class to perform the file search.
|
||||||
|
*/
|
||||||
|
public class FileSearch {
|
||||||
|
|
||||||
|
private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
|
||||||
|
private static final int MAXIMUM_CACHE_SIZE = 10;
|
||||||
|
private static final Cache<SearchKey, Map<GroupKey, List<ResultFile>>> searchCache = CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(MAXIMUM_CACHE_SIZE)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the file search and returns the SearchResults object for debugging.
|
||||||
|
* Caching new results for access at later time.
|
||||||
|
*
|
||||||
|
* @param userName The name of the user performing the search.
|
||||||
|
* @param filters The filters to apply
|
||||||
|
* @param groupAttributeType The attribute to use for grouping
|
||||||
|
* @param groupSortingType The method to use to sort the groups
|
||||||
|
* @param fileSortingMethod The method to use to sort the files within the
|
||||||
|
* groups
|
||||||
|
* @param caseDb The case database
|
||||||
|
* @param centralRepoDb The central repository database. Can be null if
|
||||||
|
* not needed.
|
||||||
|
*
|
||||||
|
* @return The raw search results
|
||||||
|
*
|
||||||
|
* @throws FileSearchException
|
||||||
|
*/
|
||||||
|
static SearchResults runFileSearchDebug(String userName,
|
||||||
|
List<AbstractFilter> filters,
|
||||||
|
AttributeType groupAttributeType,
|
||||||
|
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||||
|
FileSorter.SortingMethod fileSortingMethod,
|
||||||
|
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
// Make a list of attributes that we want to add values for. This ensures the
|
||||||
|
// ResultFile objects will have all needed fields set when it's time to group
|
||||||
|
// and sort them. For example, if we're grouping by central repo frequency, we need
|
||||||
|
// to make sure we've loaded those values before grouping.
|
||||||
|
List<AttributeType> attributesNeededForGroupingOrSorting = new ArrayList<>();
|
||||||
|
attributesNeededForGroupingOrSorting.add(groupAttributeType);
|
||||||
|
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
|
||||||
|
|
||||||
|
// Run the queries for each filter
|
||||||
|
List<ResultFile> resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
|
||||||
|
|
||||||
|
// Add the data to resultFiles for any attributes needed for sorting and grouping
|
||||||
|
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
|
||||||
|
|
||||||
|
// Collect everything in the search results
|
||||||
|
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||||
|
searchResults.add(resultFiles);
|
||||||
|
|
||||||
|
// Sort and group the results
|
||||||
|
searchResults.sortGroupsAndFiles();
|
||||||
|
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||||
|
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
||||||
|
synchronized (searchCache) {
|
||||||
|
searchCache.put(searchKey, resultHashMap);
|
||||||
|
}
|
||||||
|
return searchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the file search to get the group keys and sizes. Clears cache of
|
||||||
|
* search results, caching new results for access at later time.
|
||||||
|
*
|
||||||
|
* @param userName The name of the user performing the search.
|
||||||
|
* @param filters The filters to apply
|
||||||
|
* @param groupAttributeType The attribute to use for grouping
|
||||||
|
* @param groupSortingType The method to use to sort the groups
|
||||||
|
* @param fileSortingMethod The method to use to sort the files within the
|
||||||
|
* groups
|
||||||
|
* @param caseDb The case database
|
||||||
|
* @param centralRepoDb The central repository database. Can be null if
|
||||||
|
* not needed.
|
||||||
|
*
|
||||||
|
* @return A LinkedHashMap grouped and sorted according to the parameters
|
||||||
|
*
|
||||||
|
* @throws FileSearchException
|
||||||
|
*/
|
||||||
|
public static Map<GroupKey, Integer> getGroupSizes(String userName,
|
||||||
|
List<AbstractFilter> filters,
|
||||||
|
AttributeType groupAttributeType,
|
||||||
|
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||||
|
FileSorter.SortingMethod fileSortingMethod,
|
||||||
|
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
Map<GroupKey, List<ResultFile>> searchResults = runFileSearch(userName, filters,
|
||||||
|
groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||||
|
LinkedHashMap<GroupKey, Integer> groupSizes = new LinkedHashMap<>();
|
||||||
|
for (GroupKey groupKey : searchResults.keySet()) {
|
||||||
|
groupSizes.put(groupKey, searchResults.get(groupKey).size());
|
||||||
|
}
|
||||||
|
return groupSizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the files from the specified group from the cache, if the the group
|
||||||
|
* was not cached perform a search caching the groups.
|
||||||
|
*
|
||||||
|
* @param userName The name of the user performing the search.
|
||||||
|
* @param filters The filters to apply
|
||||||
|
* @param groupAttributeType The attribute to use for grouping
|
||||||
|
* @param groupSortingType The method to use to sort the groups
|
||||||
|
* @param fileSortingMethod The method to use to sort the files within the
|
||||||
|
* groups
|
||||||
|
* @param groupKey The key which uniquely identifies the group to
|
||||||
|
* get entries from
|
||||||
|
* @param startingEntry The first entry to return
|
||||||
|
* @param numberOfEntries The number of entries to return
|
||||||
|
* @param caseDb The case database
|
||||||
|
* @param centralRepoDb The central repository database. Can be null if
|
||||||
|
* not needed.
|
||||||
|
*
|
||||||
|
* @return A LinkedHashMap grouped and sorted according to the parameters
|
||||||
|
*
|
||||||
|
* @throws FileSearchException
|
||||||
|
*/
|
||||||
|
public static List<ResultFile> getFilesInGroup(String userName,
|
||||||
|
List<AbstractFilter> filters,
|
||||||
|
AttributeType groupAttributeType,
|
||||||
|
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||||
|
FileSorter.SortingMethod fileSortingMethod,
|
||||||
|
GroupKey groupKey,
|
||||||
|
int startingEntry,
|
||||||
|
int numberOfEntries,
|
||||||
|
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
//the group should be in the cache at this point
|
||||||
|
List<ResultFile> filesInGroup = null;
|
||||||
|
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
||||||
|
Map<GroupKey, List<ResultFile>> resultsMap;
|
||||||
|
synchronized (searchCache) {
|
||||||
|
resultsMap = searchCache.getIfPresent(searchKey);
|
||||||
|
}
|
||||||
|
if (resultsMap != null) {
|
||||||
|
filesInGroup = resultsMap.get(groupKey);
|
||||||
|
}
|
||||||
|
List<ResultFile> page = new ArrayList<>();
|
||||||
|
if (filesInGroup == null) {
|
||||||
|
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey);
|
||||||
|
runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||||
|
synchronized (searchCache) {
|
||||||
|
resultsMap = searchCache.getIfPresent(searchKey.getKeyString());
|
||||||
|
}
|
||||||
|
if (resultsMap != null) {
|
||||||
|
filesInGroup = resultsMap.get(groupKey);
|
||||||
|
}
|
||||||
|
if (filesInGroup == null) {
|
||||||
|
logger.log(Level.WARNING, "Group {0} did not exist in cache or new search results", groupKey);
|
||||||
|
return page; //group does not exist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check that there is data after the starting point
|
||||||
|
if (filesInGroup.size() < startingEntry) {
|
||||||
|
logger.log(Level.WARNING, "Group only contains {0} files, starting entry of {1} is too large.", new Object[]{filesInGroup.size(), startingEntry});
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
// Add files to the page
|
||||||
|
for (int i = startingEntry; (i < startingEntry + numberOfEntries)
|
||||||
|
&& (i < filesInGroup.size()); i++) {
|
||||||
|
page.add(filesInGroup.get(i));
|
||||||
|
}
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a summary for the specified AbstractFile. If no TextSummarizers exist
|
||||||
|
* get the beginning of the file.
|
||||||
|
*
|
||||||
|
* @param file The AbstractFile to summarize.
|
||||||
|
*
|
||||||
|
* @return The summary or beginning of the specified file as a String.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({"FileSearch.documentSummary.noPreview=No preview available.",
|
||||||
|
"FileSearch.documentSummary.noBytes=No bytes read for document, unable to display preview."})
|
||||||
|
public static TextSummary summarize(AbstractFile file) {
|
||||||
|
TextSummary summary = null;
|
||||||
|
TextSummarizer localSummarizer;
|
||||||
|
synchronized (searchCache) {
|
||||||
|
localSummarizer = SummaryHelpers.getLocalSummarizer();
|
||||||
|
|
||||||
|
}
|
||||||
|
if (localSummarizer != null) {
|
||||||
|
try {
|
||||||
|
//a summary of length 40 seems to fit without vertical scroll bars
|
||||||
|
summary = localSummarizer.summarize(file, 40);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return new TextSummary(Bundle.FileSearch_documentSummary_noPreview(), null, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (summary == null || StringUtils.isBlank(summary.getSummaryText())) {
|
||||||
|
//summary text was empty grab the beginning of the file
|
||||||
|
summary = SummaryHelpers.getDefaultSummary(file);
|
||||||
|
}
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the file search. Caching new results for access at later time.
|
||||||
|
*
|
||||||
|
* @param userName The name of the user performing the search.
|
||||||
|
* @param filters The filters to apply
|
||||||
|
* @param groupAttributeType The attribute to use for grouping
|
||||||
|
* @param groupSortingType The method to use to sort the groups
|
||||||
|
* @param fileSortingMethod The method to use to sort the files within the
|
||||||
|
* groups
|
||||||
|
* @param caseDb The case database
|
||||||
|
* @param centralRepoDb The central repository database. Can be null if
|
||||||
|
* not needed.
|
||||||
|
*
|
||||||
|
* @return A LinkedHashMap grouped and sorted according to the parameters
|
||||||
|
*
|
||||||
|
* @throws FileSearchException
|
||||||
|
*/
|
||||||
|
private static Map<GroupKey, List<ResultFile>> runFileSearch(String userName,
|
||||||
|
List<AbstractFilter> filters,
|
||||||
|
AttributeType groupAttributeType,
|
||||||
|
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||||
|
FileSorter.SortingMethod fileSortingMethod,
|
||||||
|
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
|
// Make a list of attributes that we want to add values for. This ensures the
|
||||||
|
// ResultFile objects will have all needed fields set when it's time to group
|
||||||
|
// and sort them. For example, if we're grouping by central repo frequency, we need
|
||||||
|
// to make sure we've loaded those values before grouping.
|
||||||
|
List<AttributeType> attributesNeededForGroupingOrSorting = new ArrayList<>();
|
||||||
|
attributesNeededForGroupingOrSorting.add(groupAttributeType);
|
||||||
|
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
|
||||||
|
|
||||||
|
// Run the queries for each filter
|
||||||
|
List<ResultFile> resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
|
||||||
|
|
||||||
|
// Add the data to resultFiles for any attributes needed for sorting and grouping
|
||||||
|
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
|
||||||
|
|
||||||
|
// Collect everything in the search results
|
||||||
|
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||||
|
searchResults.add(resultFiles);
|
||||||
|
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||||
|
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
|
||||||
|
synchronized (searchCache) {
|
||||||
|
searchCache.put(searchKey, resultHashMap);
|
||||||
|
}
|
||||||
|
// Return a version of the results in general Java objects
|
||||||
|
return resultHashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add any attributes corresponding to the attribute list to the given
|
||||||
|
* result files. For example, specifying the KeywordListAttribute will
|
||||||
|
* populate the list of keyword set names in the ResultFile objects.
|
||||||
|
*
|
||||||
|
* @param attrs The attributes to add to the list of result files
|
||||||
|
* @param resultFiles The result files
|
||||||
|
* @param caseDb The case database
|
||||||
|
* @param centralRepoDb The central repository database. Can be null if not
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* @throws FileSearchException
|
||||||
|
*/
|
||||||
|
private static void addAttributes(List<AttributeType> attrs, List<ResultFile> resultFiles, SleuthkitCase caseDb, CentralRepository centralRepoDb)
|
||||||
|
throws FileSearchException {
|
||||||
|
for (AttributeType attr : attrs) {
|
||||||
|
attr.addAttributeToResultFiles(resultFiles, caseDb, centralRepoDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the CR frequency of all the given hashes and updates the list of
|
||||||
|
* files.
|
||||||
|
*
|
||||||
|
* @param hashesToLookUp Hashes to find the frequency of
|
||||||
|
* @param currentFiles List of files to update with frequencies
|
||||||
|
*/
|
||||||
|
private static void computeFrequency(Set<String> hashesToLookUp, List<ResultFile> currentFiles, CentralRepository centralRepoDb) {
|
||||||
|
|
||||||
|
if (hashesToLookUp.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String hashes = String.join("','", hashesToLookUp);
|
||||||
|
hashes = "'" + hashes + "'";
|
||||||
|
try {
|
||||||
|
CorrelationAttributeInstance.Type attributeType = centralRepoDb.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
|
||||||
|
String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(attributeType);
|
||||||
|
|
||||||
|
String selectClause = " value, COUNT(value) FROM "
|
||||||
|
+ "(SELECT DISTINCT case_id, value FROM " + tableName
|
||||||
|
+ " WHERE value IN ("
|
||||||
|
+ hashes
|
||||||
|
+ ")) AS foo GROUP BY value";
|
||||||
|
|
||||||
|
FrequencyCallback callback = new FrequencyCallback(currentFiles);
|
||||||
|
centralRepoDb.processSelectClause(selectClause, callback);
|
||||||
|
|
||||||
|
} catch (CentralRepoException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error getting frequency counts from Central Repository", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String createSetNameClause(List<ResultFile> files,
|
||||||
|
int artifactTypeID, int setNameAttrID) throws FileSearchException {
|
||||||
|
|
||||||
|
// Concatenate the object IDs in the list of files
|
||||||
|
String objIdList = ""; // NON-NLS
|
||||||
|
for (ResultFile file : files) {
|
||||||
|
if (!objIdList.isEmpty()) {
|
||||||
|
objIdList += ","; // NON-NLS
|
||||||
|
}
|
||||||
|
objIdList += "\'" + file.getFirstInstance().getId() + "\'"; // NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pairs of (object ID, set name) for all files in the list of files that have
|
||||||
|
// the given artifact type.
|
||||||
|
return "blackboard_artifacts.obj_id AS object_id, blackboard_attributes.value_text AS set_name "
|
||||||
|
+ "FROM blackboard_artifacts "
|
||||||
|
+ "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id "
|
||||||
|
+ "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' "
|
||||||
|
+ "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' "
|
||||||
|
+ "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileSearch() {
|
||||||
|
// Class should not be instantiated
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for the grouping attributes.
|
||||||
|
*/
|
||||||
|
public abstract static class AttributeType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given file, return the key for the group it belongs to for this
|
||||||
|
* attribute type.
|
||||||
|
*
|
||||||
|
* @param file the result file to be grouped
|
||||||
|
*
|
||||||
|
* @return the key for the group this file goes in
|
||||||
|
*/
|
||||||
|
public abstract GroupKey getGroupKey(ResultFile file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add any extra data to the ResultFile object from this attribute.
|
||||||
|
*
|
||||||
|
* @param files The list of files to enhance
|
||||||
|
* @param caseDb The case database
|
||||||
|
* @param centralRepoDb The central repository database. Can be null if
|
||||||
|
* not needed.
|
||||||
|
*
|
||||||
|
* @throws FileSearchException
|
||||||
|
*/
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
// Default is to do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by file size
|
||||||
|
*/
|
||||||
|
public static class FileSizeAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.FileSizeGroupKey(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by parent path
|
||||||
|
*/
|
||||||
|
public static class ParentPathAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.ParentPathGroupKey(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default attribute used to make one group
|
||||||
|
*/
|
||||||
|
static class NoGroupingAttribute extends FileSearch.AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.NoGroupingGroupKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by data source
|
||||||
|
*/
|
||||||
|
static class DataSourceAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.DataSourceGroupKey(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by file type
|
||||||
|
*/
|
||||||
|
static class FileTypeAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.FileTypeGroupKey(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by keyword lists
|
||||||
|
*/
|
||||||
|
static class KeywordListAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.KeywordListGroupKey(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
|
// Get pairs of (object ID, keyword list name) for all files in the list of files that have
|
||||||
|
// keyword list hits.
|
||||||
|
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||||
|
|
||||||
|
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(files);
|
||||||
|
try {
|
||||||
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new FileSearchException("Error looking up keyword list attributes", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to process the results of the CaseDbAccessManager select
|
||||||
|
* query. Will add the keyword list names to the list of ResultFile
|
||||||
|
* objects.
|
||||||
|
*/
|
||||||
|
private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
|
List<ResultFile> resultFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the callback.
|
||||||
|
*
|
||||||
|
* @param resultFiles List of files to add keyword list names to
|
||||||
|
*/
|
||||||
|
SetKeywordListNamesCallback(List<ResultFile> resultFiles) {
|
||||||
|
this.resultFiles = resultFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
// Create a temporary map of object ID to ResultFile
|
||||||
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
|
for (ResultFile file : resultFiles) {
|
||||||
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
try {
|
||||||
|
Long objId = rs.getLong("object_id"); // NON-NLS
|
||||||
|
String keywordListName = rs.getString("set_name"); // NON-NLS
|
||||||
|
|
||||||
|
tempMap.get(objId).addKeywordListName(keywordListName);
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get keyword list names", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by frequency in the central repository
|
||||||
|
*/
|
||||||
|
static class FrequencyAttribute extends AttributeType {
|
||||||
|
|
||||||
|
static final int BATCH_SIZE = 50; // Number of hashes to look up at one time
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.FrequencyGroupKey(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
if (centralRepoDb == null) {
|
||||||
|
for (ResultFile file : files) {
|
||||||
|
if (file.getFrequency() == Frequency.UNKNOWN && file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
|
||||||
|
file.setFrequency(Frequency.KNOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
processResultFilesForCR(files, centralRepoDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private helper method for adding Frequency attribute when CR is
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* @param files The list of ResultFiles to caluclate frequency
|
||||||
|
* for.
|
||||||
|
* @param centralRepoDb The central repository currently in use.
|
||||||
|
*/
|
||||||
|
private void processResultFilesForCR(List<ResultFile> files,
|
||||||
|
CentralRepository centralRepoDb) {
|
||||||
|
List<ResultFile> currentFiles = new ArrayList<>();
|
||||||
|
Set<String> hashesToLookUp = new HashSet<>();
|
||||||
|
for (ResultFile file : files) {
|
||||||
|
if (file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
|
||||||
|
file.setFrequency(Frequency.KNOWN);
|
||||||
|
}
|
||||||
|
if (file.getFrequency() == Frequency.UNKNOWN
|
||||||
|
&& file.getFirstInstance().getMd5Hash() != null
|
||||||
|
&& !file.getFirstInstance().getMd5Hash().isEmpty()) {
|
||||||
|
hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
|
||||||
|
currentFiles.add(file);
|
||||||
|
}
|
||||||
|
if (hashesToLookUp.size() >= BATCH_SIZE) {
|
||||||
|
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
|
||||||
|
|
||||||
|
hashesToLookUp.clear();
|
||||||
|
currentFiles.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to use with findInterCaseValuesByCount which generates a list of
|
||||||
|
* values for common property search
|
||||||
|
*/
|
||||||
|
private static class FrequencyCallback implements InstanceTableCallback {
|
||||||
|
|
||||||
|
private final List<ResultFile> files;
|
||||||
|
|
||||||
|
private FrequencyCallback(List<ResultFile> files) {
|
||||||
|
this.files = new ArrayList<>(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet resultSet) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
while (resultSet.next()) {
|
||||||
|
String hash = resultSet.getString(1);
|
||||||
|
int count = resultSet.getInt(2);
|
||||||
|
for (Iterator<ResultFile> iterator = files.iterator(); iterator.hasNext();) {
|
||||||
|
ResultFile file = iterator.next();
|
||||||
|
if (file.getFirstInstance().getMd5Hash().equalsIgnoreCase(hash)) {
|
||||||
|
file.setFrequency(Frequency.fromCount(count));
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The files left had no matching entries in the CR, so mark them as unique
|
||||||
|
for (ResultFile file : files) {
|
||||||
|
file.setFrequency(Frequency.UNIQUE);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error getting frequency counts from Central Repository", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by hash set lists
|
||||||
|
*/
|
||||||
|
static class HashHitsAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.HashHitsGroupKey(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
|
// Get pairs of (object ID, hash set name) for all files in the list of files that have
|
||||||
|
// hash set hits.
|
||||||
|
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||||
|
|
||||||
|
HashSetNamesCallback callback = new HashSetNamesCallback(files);
|
||||||
|
try {
|
||||||
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new FileSearchException("Error looking up hash set attributes", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to process the results of the CaseDbAccessManager select
|
||||||
|
* query. Will add the hash set names to the list of ResultFile objects.
|
||||||
|
*/
|
||||||
|
private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
|
List<ResultFile> resultFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the callback.
|
||||||
|
*
|
||||||
|
* @param resultFiles List of files to add hash set names to
|
||||||
|
*/
|
||||||
|
HashSetNamesCallback(List<ResultFile> resultFiles) {
|
||||||
|
this.resultFiles = resultFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
// Create a temporary map of object ID to ResultFile
|
||||||
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
|
for (ResultFile file : resultFiles) {
|
||||||
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
try {
|
||||||
|
Long objId = rs.getLong("object_id"); // NON-NLS
|
||||||
|
String hashSetName = rs.getString("set_name"); // NON-NLS
|
||||||
|
|
||||||
|
tempMap.get(objId).addHashSetName(hashSetName);
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get hash set names", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by interesting item set lists
|
||||||
|
*/
|
||||||
|
static class InterestingItemAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.InterestingItemGroupKey(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
|
// Get pairs of (object ID, interesting item set name) for all files in the list of files that have
|
||||||
|
// interesting file set hits.
|
||||||
|
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||||
|
|
||||||
|
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(files);
|
||||||
|
try {
|
||||||
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new FileSearchException("Error looking up interesting file set attributes", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to process the results of the CaseDbAccessManager select
|
||||||
|
* query. Will add the interesting file set names to the list of
|
||||||
|
* ResultFile objects.
|
||||||
|
*/
|
||||||
|
private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
|
List<ResultFile> resultFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the callback.
|
||||||
|
*
|
||||||
|
* @param resultFiles List of files to add interesting file set
|
||||||
|
* names to
|
||||||
|
*/
|
||||||
|
InterestingFileSetNamesCallback(List<ResultFile> resultFiles) {
|
||||||
|
this.resultFiles = resultFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
// Create a temporary map of object ID to ResultFile
|
||||||
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
|
for (ResultFile file : resultFiles) {
|
||||||
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
try {
|
||||||
|
Long objId = rs.getLong("object_id"); // NON-NLS
|
||||||
|
String setName = rs.getString("set_name"); // NON-NLS
|
||||||
|
|
||||||
|
tempMap.get(objId).addInterestingSetName(setName);
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get interesting file set names", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by objects detected
|
||||||
|
*/
|
||||||
|
static class ObjectDetectedAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
|
// Get pairs of (object ID, object type name) for all files in the list of files that have
|
||||||
|
// objects detected
|
||||||
|
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
|
||||||
|
|
||||||
|
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(files);
|
||||||
|
try {
|
||||||
|
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new FileSearchException("Error looking up object detected attributes", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to process the results of the CaseDbAccessManager select
|
||||||
|
* query. Will add the object type names to the list of ResultFile
|
||||||
|
* objects.
|
||||||
|
*/
|
||||||
|
private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
|
List<ResultFile> resultFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the callback.
|
||||||
|
*
|
||||||
|
* @param resultFiles List of files to add object detected names to
|
||||||
|
*/
|
||||||
|
ObjectDetectedNamesCallback(List<ResultFile> resultFiles) {
|
||||||
|
this.resultFiles = resultFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
// Create a temporary map of object ID to ResultFile
|
||||||
|
Map<Long, ResultFile> tempMap = new HashMap<>();
|
||||||
|
for (ResultFile file : resultFiles) {
|
||||||
|
tempMap.put(file.getFirstInstance().getId(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
try {
|
||||||
|
Long objId = rs.getLong("object_id"); // NON-NLS
|
||||||
|
String setName = rs.getString("set_name"); // NON-NLS
|
||||||
|
|
||||||
|
tempMap.get(objId).addObjectDetectedName(setName);
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get object detected names", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute for grouping/sorting by tag name
|
||||||
|
*/
|
||||||
|
static class FileTagAttribute extends AttributeType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupKey getGroupKey(ResultFile file) {
|
||||||
|
return new DiscoveryKeyUtils.FileTagGroupKey(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (ResultFile resultFile : files) {
|
||||||
|
List<ContentTag> contentTags = caseDb.getContentTagsByContent(resultFile.getFirstInstance());
|
||||||
|
|
||||||
|
for (ContentTag tag : contentTags) {
|
||||||
|
resultFile.addTagName(tag.getName().getDisplayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new FileSearchException("Error looking up file tag attributes", ex); // NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for the attribute types that can be used for grouping.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"FileSearch.GroupingAttributeType.fileType.displayName=File Type",
|
||||||
|
"FileSearch.GroupingAttributeType.frequency.displayName=Past Occurrences",
|
||||||
|
"FileSearch.GroupingAttributeType.keywordList.displayName=Keyword",
|
||||||
|
"FileSearch.GroupingAttributeType.size.displayName=File Size",
|
||||||
|
"FileSearch.GroupingAttributeType.datasource.displayName=Data Source",
|
||||||
|
"FileSearch.GroupingAttributeType.parent.displayName=Parent Folder",
|
||||||
|
"FileSearch.GroupingAttributeType.hash.displayName=Hash Set",
|
||||||
|
"FileSearch.GroupingAttributeType.interestingItem.displayName=Interesting Item",
|
||||||
|
"FileSearch.GroupingAttributeType.tag.displayName=Tag",
|
||||||
|
"FileSearch.GroupingAttributeType.object.displayName=Object Detected",
|
||||||
|
"FileSearch.GroupingAttributeType.none.displayName=None"})
|
||||||
|
public enum GroupingAttributeType {
|
||||||
|
FILE_SIZE(new FileSizeAttribute(), Bundle.FileSearch_GroupingAttributeType_size_displayName()),
|
||||||
|
FREQUENCY(new FrequencyAttribute(), Bundle.FileSearch_GroupingAttributeType_frequency_displayName()),
|
||||||
|
KEYWORD_LIST_NAME(new KeywordListAttribute(), Bundle.FileSearch_GroupingAttributeType_keywordList_displayName()),
|
||||||
|
DATA_SOURCE(new DataSourceAttribute(), Bundle.FileSearch_GroupingAttributeType_datasource_displayName()),
|
||||||
|
PARENT_PATH(new ParentPathAttribute(), Bundle.FileSearch_GroupingAttributeType_parent_displayName()),
|
||||||
|
HASH_LIST_NAME(new HashHitsAttribute(), Bundle.FileSearch_GroupingAttributeType_hash_displayName()),
|
||||||
|
INTERESTING_ITEM_SET(new InterestingItemAttribute(), Bundle.FileSearch_GroupingAttributeType_interestingItem_displayName()),
|
||||||
|
FILE_TAG(new FileTagAttribute(), Bundle.FileSearch_GroupingAttributeType_tag_displayName()),
|
||||||
|
OBJECT_DETECTED(new ObjectDetectedAttribute(), Bundle.FileSearch_GroupingAttributeType_object_displayName()),
|
||||||
|
NO_GROUPING(new NoGroupingAttribute(), Bundle.FileSearch_GroupingAttributeType_none_displayName());
|
||||||
|
|
||||||
|
private final AttributeType attributeType;
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
|
GroupingAttributeType(AttributeType attributeType, String displayName) {
|
||||||
|
this.attributeType = attributeType;
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributeType getAttributeType() {
|
||||||
|
return attributeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of enums that are valid for grouping images.
|
||||||
|
*
|
||||||
|
* @return enums that can be used to group images
|
||||||
|
*/
|
||||||
|
public static List<GroupingAttributeType> getOptionsForGrouping() {
|
||||||
|
return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -30,12 +30,12 @@ import org.sleuthkit.autopsy.coreutils.FileTypeUtils;
|
|||||||
/**
|
/**
|
||||||
* Utility enums for searches made for files with Discovery.
|
* Utility enums for searches made for files with Discovery.
|
||||||
*/
|
*/
|
||||||
final class FileSearchData extends SearchData {
|
public final class FileSearchData implements SearchData {
|
||||||
|
|
||||||
private final static long BYTES_PER_MB = 1000000;
|
private final static long BYTES_PER_MB = 1000000;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ResultType getResultType() {
|
public ResultType getResultType() {
|
||||||
return ResultType.FILE;
|
return ResultType.FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ final class FileSearchData extends SearchData {
|
|||||||
"FileSearchData.Frequency.verycommon.displayName=Very Common (100+)",
|
"FileSearchData.Frequency.verycommon.displayName=Very Common (100+)",
|
||||||
"FileSearchData.Frequency.known.displayName=Known (NSRL)",
|
"FileSearchData.Frequency.known.displayName=Known (NSRL)",
|
||||||
"FileSearchData.Frequency.unknown.displayName=Unknown",})
|
"FileSearchData.Frequency.unknown.displayName=Unknown",})
|
||||||
enum Frequency {
|
public enum Frequency {
|
||||||
UNIQUE(0, 1, Bundle.FileSearchData_Frequency_unique_displayName()),
|
UNIQUE(0, 1, Bundle.FileSearchData_Frequency_unique_displayName()),
|
||||||
RARE(1, 10, Bundle.FileSearchData_Frequency_rare_displayName()),
|
RARE(1, 10, Bundle.FileSearchData_Frequency_rare_displayName()),
|
||||||
COMMON(2, 100, Bundle.FileSearchData_Frequency_common_displayName()),
|
COMMON(2, 100, Bundle.FileSearchData_Frequency_common_displayName()),
|
||||||
@ -72,7 +72,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the rank (lower should be displayed first)
|
* @return the rank (lower should be displayed first)
|
||||||
*/
|
*/
|
||||||
int getRanking() {
|
public int getRanking() {
|
||||||
return ranking;
|
return ranking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the corresponding enum
|
* @return the corresponding enum
|
||||||
*/
|
*/
|
||||||
static Frequency fromCount(long count) {
|
public static Frequency fromCount(long count) {
|
||||||
if (count <= UNIQUE.getMaxOccur()) {
|
if (count <= UNIQUE.getMaxOccur()) {
|
||||||
return UNIQUE;
|
return UNIQUE;
|
||||||
} else if (count <= RARE.getMaxOccur()) {
|
} else if (count <= RARE.getMaxOccur()) {
|
||||||
@ -100,7 +100,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return enums that can be used to filter with a CR.
|
* @return enums that can be used to filter with a CR.
|
||||||
*/
|
*/
|
||||||
static List<Frequency> getOptionsForFilteringWithCr() {
|
public static List<Frequency> getOptionsForFilteringWithCr() {
|
||||||
return Arrays.asList(UNIQUE, RARE, COMMON, VERY_COMMON, KNOWN);
|
return Arrays.asList(UNIQUE, RARE, COMMON, VERY_COMMON, KNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return enums that can be used to filter without a CR.
|
* @return enums that can be used to filter without a CR.
|
||||||
*/
|
*/
|
||||||
static List<Frequency> getOptionsForFilteringWithoutCr() {
|
public static List<Frequency> getOptionsForFilteringWithoutCr() {
|
||||||
return Arrays.asList(KNOWN, UNKNOWN);
|
return Arrays.asList(KNOWN, UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ final class FileSearchData extends SearchData {
|
|||||||
/**
|
/**
|
||||||
* @return the maxOccur
|
* @return the maxOccur
|
||||||
*/
|
*/
|
||||||
int getMaxOccur() {
|
public int getMaxOccur() {
|
||||||
return maxOccur;
|
return maxOccur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ final class FileSearchData extends SearchData {
|
|||||||
"FileSearchData.FileSize.16kbto100kb=: 16-100KB",
|
"FileSearchData.FileSize.16kbto100kb=: 16-100KB",
|
||||||
"FileSearchData.FileSize.upTo500kb=: 0-500KB",
|
"FileSearchData.FileSize.upTo500kb=: 0-500KB",
|
||||||
"FileSearchData.FileSize.upTo16kb=: 0-16KB",})
|
"FileSearchData.FileSize.upTo16kb=: 0-16KB",})
|
||||||
enum FileSize {
|
public enum FileSize {
|
||||||
XXLARGE_VIDEO(0, 10000 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_XXLARGE_displayName(), Bundle.FileSearchData_FileSize_10PlusGb()),
|
XXLARGE_VIDEO(0, 10000 * BYTES_PER_MB, -1, Bundle.FileSearchData_FileSize_XXLARGE_displayName(), Bundle.FileSearchData_FileSize_10PlusGb()),
|
||||||
XLARGE_VIDEO(1, 5000 * BYTES_PER_MB, 10000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_XLARGE_displayName(), Bundle.FileSearchData_FileSize_5gbto10gb()),
|
XLARGE_VIDEO(1, 5000 * BYTES_PER_MB, 10000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_XLARGE_displayName(), Bundle.FileSearchData_FileSize_5gbto10gb()),
|
||||||
LARGE_VIDEO(2, 1000 * BYTES_PER_MB, 5000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_LARGE_displayName(), Bundle.FileSearchData_FileSize_1gbto5gb()),
|
LARGE_VIDEO(2, 1000 * BYTES_PER_MB, 5000 * BYTES_PER_MB, Bundle.FileSearchData_FileSize_LARGE_displayName(), Bundle.FileSearchData_FileSize_1gbto5gb()),
|
||||||
@ -190,7 +190,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the enum whose range contains the file size
|
* @return the enum whose range contains the file size
|
||||||
*/
|
*/
|
||||||
static FileSize fromImageSize(long size) {
|
public static FileSize fromImageSize(long size) {
|
||||||
if (size > XXLARGE_IMAGE.getMinBytes()) {
|
if (size > XXLARGE_IMAGE.getMinBytes()) {
|
||||||
return XXLARGE_IMAGE;
|
return XXLARGE_IMAGE;
|
||||||
} else if (size > XLARGE_IMAGE.getMinBytes()) {
|
} else if (size > XLARGE_IMAGE.getMinBytes()) {
|
||||||
@ -214,7 +214,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the enum whose range contains the file size
|
* @return the enum whose range contains the file size
|
||||||
*/
|
*/
|
||||||
static FileSize fromVideoSize(long size) {
|
public static FileSize fromVideoSize(long size) {
|
||||||
if (size > XXLARGE_VIDEO.getMinBytes()) {
|
if (size > XXLARGE_VIDEO.getMinBytes()) {
|
||||||
return XXLARGE_VIDEO;
|
return XXLARGE_VIDEO;
|
||||||
} else if (size > XLARGE_VIDEO.getMinBytes()) {
|
} else if (size > XLARGE_VIDEO.getMinBytes()) {
|
||||||
@ -235,7 +235,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the maximum file size that will fit in this range.
|
* @return the maximum file size that will fit in this range.
|
||||||
*/
|
*/
|
||||||
long getMaxBytes() {
|
public long getMaxBytes() {
|
||||||
return maxBytes;
|
return maxBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the maximum file size that is not part of this range
|
* @return the maximum file size that is not part of this range
|
||||||
*/
|
*/
|
||||||
long getMinBytes() {
|
public long getMinBytes() {
|
||||||
return minBytes;
|
return minBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the rank (lower should be displayed first)
|
* @return the rank (lower should be displayed first)
|
||||||
*/
|
*/
|
||||||
int getRanking() {
|
public int getRanking() {
|
||||||
return ranking;
|
return ranking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ final class FileSearchData extends SearchData {
|
|||||||
return sizeGroup + displaySize;
|
return sizeGroup + displaySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSizeGroup() {
|
public String getSizeGroup() {
|
||||||
return sizeGroup;
|
return sizeGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ final class FileSearchData extends SearchData {
|
|||||||
* @return Enums that can be used to filter most file including images
|
* @return Enums that can be used to filter most file including images
|
||||||
* by size.
|
* by size.
|
||||||
*/
|
*/
|
||||||
static List<FileSize> getDefaultSizeOptions() {
|
public static List<FileSize> getDefaultSizeOptions() {
|
||||||
return Arrays.asList(XXLARGE_IMAGE, XLARGE_IMAGE, LARGE_IMAGE, MEDIUM_IMAGE, SMALL_IMAGE, XSMALL_IMAGE);
|
return Arrays.asList(XXLARGE_IMAGE, XLARGE_IMAGE, LARGE_IMAGE, MEDIUM_IMAGE, SMALL_IMAGE, XSMALL_IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return enums that can be used to filter videos by size.
|
* @return enums that can be used to filter videos by size.
|
||||||
*/
|
*/
|
||||||
static List<FileSize> getOptionsForVideos() {
|
public static List<FileSize> getOptionsForVideos() {
|
||||||
return Arrays.asList(XXLARGE_VIDEO, XLARGE_VIDEO, LARGE_VIDEO, MEDIUM_VIDEO, SMALL_VIDEO, XSMALL_VIDEO);
|
return Arrays.asList(XXLARGE_VIDEO, XLARGE_VIDEO, LARGE_VIDEO, MEDIUM_VIDEO, SMALL_VIDEO, XSMALL_VIDEO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ final class FileSearchData extends SearchData {
|
|||||||
.add("application/pdf", //NON-NLS
|
.add("application/pdf", //NON-NLS
|
||||||
"application/xhtml+xml").build(); //NON-NLS
|
"application/xhtml+xml").build(); //NON-NLS
|
||||||
|
|
||||||
static Collection<String> getDocTypesWithoutImageExtraction() {
|
public static Collection<String> getDocTypesWithoutImageExtraction() {
|
||||||
return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES);
|
return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +331,7 @@ final class FileSearchData extends SearchData {
|
|||||||
"FileSearchData.FileType.Documents.displayName=Documents",
|
"FileSearchData.FileType.Documents.displayName=Documents",
|
||||||
"FileSearchData.FileType.Executables.displayName=Executables",
|
"FileSearchData.FileType.Executables.displayName=Executables",
|
||||||
"FileSearchData.FileType.Other.displayName=Other/Unknown"})
|
"FileSearchData.FileType.Other.displayName=Other/Unknown"})
|
||||||
enum FileType {
|
public enum FileType {
|
||||||
|
|
||||||
IMAGE(0, Bundle.FileSearchData_FileType_Image_displayName(), FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes()),
|
IMAGE(0, Bundle.FileSearchData_FileType_Image_displayName(), FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes()),
|
||||||
AUDIO(1, Bundle.FileSearchData_FileType_Audio_displayName(), FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes()),
|
AUDIO(1, Bundle.FileSearchData_FileType_Audio_displayName(), FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes()),
|
||||||
@ -355,7 +355,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return Collection of MIME type strings
|
* @return Collection of MIME type strings
|
||||||
*/
|
*/
|
||||||
Collection<String> getMediaTypes() {
|
public Collection<String> getMediaTypes() {
|
||||||
return Collections.unmodifiableCollection(mediaTypes);
|
return Collections.unmodifiableCollection(mediaTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the rank (lower should be displayed first)
|
* @return the rank (lower should be displayed first)
|
||||||
*/
|
*/
|
||||||
int getRanking() {
|
public int getRanking() {
|
||||||
return ranking;
|
return ranking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +380,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the corresponding enum (will be OTHER if no types matched)
|
* @return the corresponding enum (will be OTHER if no types matched)
|
||||||
*/
|
*/
|
||||||
static FileType fromMIMEtype(String mimeType) {
|
public static FileType fromMIMEtype(String mimeType) {
|
||||||
for (FileType type : FileType.values()) {
|
for (FileType type : FileType.values()) {
|
||||||
if (type.getMediaTypes().contains(mimeType)) {
|
if (type.getMediaTypes().contains(mimeType)) {
|
||||||
return type;
|
return type;
|
||||||
@ -398,7 +398,7 @@ final class FileSearchData extends SearchData {
|
|||||||
"FileSearchData.Score.notable.displayName=Notable",
|
"FileSearchData.Score.notable.displayName=Notable",
|
||||||
"FileSearchData.Score.interesting.displayName=Interesting",
|
"FileSearchData.Score.interesting.displayName=Interesting",
|
||||||
"FileSearchData.Score.unknown.displayName=Unknown",})
|
"FileSearchData.Score.unknown.displayName=Unknown",})
|
||||||
enum Score {
|
public enum Score {
|
||||||
NOTABLE(0, Bundle.FileSearchData_Score_notable_displayName()),
|
NOTABLE(0, Bundle.FileSearchData_Score_notable_displayName()),
|
||||||
INTERESTING(1, Bundle.FileSearchData_Score_interesting_displayName()),
|
INTERESTING(1, Bundle.FileSearchData_Score_interesting_displayName()),
|
||||||
UNKNOWN(2, Bundle.FileSearchData_Score_unknown_displayName());
|
UNKNOWN(2, Bundle.FileSearchData_Score_unknown_displayName());
|
||||||
@ -416,7 +416,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return the rank (lower should be displayed first)
|
* @return the rank (lower should be displayed first)
|
||||||
*/
|
*/
|
||||||
int getRanking() {
|
public int getRanking() {
|
||||||
return ranking;
|
return ranking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +425,7 @@ final class FileSearchData extends SearchData {
|
|||||||
*
|
*
|
||||||
* @return enums that can be used to filter
|
* @return enums that can be used to filter
|
||||||
*/
|
*/
|
||||||
static List<Score> getOptionsForFiltering() {
|
public static List<Score> getOptionsForFiltering() {
|
||||||
return Arrays.asList(NOTABLE, INTERESTING);
|
return Arrays.asList(NOTABLE, INTERESTING);
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception type used for FileSearch.
|
* Exception type used for FileSearch.
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -29,7 +29,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
* Class used to sort ResultFiles using the supplied method.
|
* Class used to sort ResultFiles using the supplied method.
|
||||||
*/
|
*/
|
||||||
class FileSorter implements Comparator<ResultFile> {
|
public class FileSorter implements Comparator<ResultFile> {
|
||||||
|
|
||||||
private final List<Comparator<ResultFile>> comparators = new ArrayList<>();
|
private final List<Comparator<ResultFile>> comparators = new ArrayList<>();
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @param method The method that should be used to sort the files
|
* @param method The method that should be used to sort the files
|
||||||
*/
|
*/
|
||||||
FileSorter(SortingMethod method) {
|
public FileSorter(SortingMethod method) {
|
||||||
|
|
||||||
// Set up the primary comparators that should applied to the files
|
// Set up the primary comparators that should applied to the files
|
||||||
switch (method) {
|
switch (method) {
|
||||||
@ -247,7 +247,7 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
"FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency",
|
"FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency",
|
||||||
"FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names",
|
"FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names",
|
||||||
"FileSorter.SortingMethod.fullPath.displayName=Full Path"})
|
"FileSorter.SortingMethod.fullPath.displayName=Full Path"})
|
||||||
enum SortingMethod {
|
public enum SortingMethod {
|
||||||
BY_FILE_NAME(new ArrayList<>(),
|
BY_FILE_NAME(new ArrayList<>(),
|
||||||
Bundle.FileSorter_SortingMethod_filename_displayName()), // Sort alphabetically by file name
|
Bundle.FileSorter_SortingMethod_filename_displayName()), // Sort alphabetically by file name
|
||||||
BY_DATA_SOURCE(new ArrayList<>(),
|
BY_DATA_SOURCE(new ArrayList<>(),
|
||||||
@ -276,7 +276,7 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FileSearch.AttributeType> getRequiredAttributes() {
|
public List<FileSearch.AttributeType> getRequiredAttributes() {
|
||||||
return Collections.unmodifiableList(requiredAttributes);
|
return Collections.unmodifiableList(requiredAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
*
|
*
|
||||||
* @return enums that can be used to ordering images.
|
* @return enums that can be used to ordering images.
|
||||||
*/
|
*/
|
||||||
static List<SortingMethod> getOptionsForOrdering() {
|
public static List<SortingMethod> getOptionsForOrdering() {
|
||||||
return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE);
|
return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,9 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
/**
|
/**
|
||||||
* Container for files that holds all necessary data for grouping and sorting.
|
* Container for files that holds all necessary data for grouping and sorting.
|
||||||
*/
|
*/
|
||||||
class ResultFile {
|
public class ResultFile {
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
|
private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
|
||||||
private FileSearchData.Frequency frequency;
|
private FileSearchData.Frequency frequency;
|
||||||
@ -59,7 +59,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param abstractFile
|
* @param abstractFile
|
||||||
*/
|
*/
|
||||||
ResultFile(AbstractFile abstractFile) {
|
public ResultFile(AbstractFile abstractFile) {
|
||||||
try {
|
try {
|
||||||
//call get uniquePath to cache the path
|
//call get uniquePath to cache the path
|
||||||
abstractFile.getUniquePath();
|
abstractFile.getUniquePath();
|
||||||
@ -86,7 +86,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return The Frequency enum
|
* @return The Frequency enum
|
||||||
*/
|
*/
|
||||||
FileSearchData.Frequency getFrequency() {
|
public FileSearchData.Frequency getFrequency() {
|
||||||
return frequency;
|
return frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param frequency The frequency of the file as an enum
|
* @param frequency The frequency of the file as an enum
|
||||||
*/
|
*/
|
||||||
void setFrequency(FileSearchData.Frequency frequency) {
|
public void setFrequency(FileSearchData.Frequency frequency) {
|
||||||
this.frequency = frequency;
|
this.frequency = frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param duplicate The abstract file to add as a duplicate.
|
* @param duplicate The abstract file to add as a duplicate.
|
||||||
*/
|
*/
|
||||||
void addDuplicate(AbstractFile duplicate) {
|
public void addDuplicate(AbstractFile duplicate) {
|
||||||
if (deleted && !duplicate.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
|
if (deleted && !duplicate.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
|
||||||
deleted = false;
|
deleted = false;
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return The score of this ResultFile.
|
* @return The score of this ResultFile.
|
||||||
*/
|
*/
|
||||||
DataResultViewerTable.Score getScore() {
|
public DataResultViewerTable.Score getScore() {
|
||||||
return currentScore;
|
return currentScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return The score description of this ResultFile.
|
* @return The score description of this ResultFile.
|
||||||
*/
|
*/
|
||||||
String getScoreDescription() {
|
public String getScoreDescription() {
|
||||||
return scoreDescription;
|
return scoreDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return The deleted status of this ResultFile.
|
* @return The deleted status of this ResultFile.
|
||||||
*/
|
*/
|
||||||
boolean isDeleted() {
|
public boolean isDeleted() {
|
||||||
return deleted;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ class ResultFile {
|
|||||||
* @return The list of AbstractFiles which have been identified as instances
|
* @return The list of AbstractFiles which have been identified as instances
|
||||||
* of this file.
|
* of this file.
|
||||||
*/
|
*/
|
||||||
List<AbstractFile> getAllInstances() {
|
public List<AbstractFile> getAllInstances() {
|
||||||
return Collections.unmodifiableList(instances);
|
return Collections.unmodifiableList(instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return The FileType enum.
|
* @return The FileType enum.
|
||||||
*/
|
*/
|
||||||
FileType getFileType() {
|
public FileType getFileType() {
|
||||||
return fileType;
|
return fileType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param keywordListName
|
* @param keywordListName
|
||||||
*/
|
*/
|
||||||
void addKeywordListName(String keywordListName) {
|
public void addKeywordListName(String keywordListName) {
|
||||||
if (!keywordListNames.contains(keywordListName)) {
|
if (!keywordListNames.contains(keywordListName)) {
|
||||||
keywordListNames.add(keywordListName);
|
keywordListNames.add(keywordListName);
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return the keyword list names that matched this file.
|
* @return the keyword list names that matched this file.
|
||||||
*/
|
*/
|
||||||
List<String> getKeywordListNames() {
|
public List<String> getKeywordListNames() {
|
||||||
return Collections.unmodifiableList(keywordListNames);
|
return Collections.unmodifiableList(keywordListNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param hashSetName
|
* @param hashSetName
|
||||||
*/
|
*/
|
||||||
void addHashSetName(String hashSetName) {
|
public void addHashSetName(String hashSetName) {
|
||||||
if (!hashSetNames.contains(hashSetName)) {
|
if (!hashSetNames.contains(hashSetName)) {
|
||||||
hashSetNames.add(hashSetName);
|
hashSetNames.add(hashSetName);
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return The hash set names that matched this file.
|
* @return The hash set names that matched this file.
|
||||||
*/
|
*/
|
||||||
List<String> getHashSetNames() {
|
public List<String> getHashSetNames() {
|
||||||
return Collections.unmodifiableList(hashSetNames);
|
return Collections.unmodifiableList(hashSetNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param tagName
|
* @param tagName
|
||||||
*/
|
*/
|
||||||
void addTagName(String tagName) {
|
public void addTagName(String tagName) {
|
||||||
if (!tagNames.contains(tagName)) {
|
if (!tagNames.contains(tagName)) {
|
||||||
tagNames.add(tagName);
|
tagNames.add(tagName);
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return the tag names that matched this file.
|
* @return the tag names that matched this file.
|
||||||
*/
|
*/
|
||||||
List<String> getTagNames() {
|
public List<String> getTagNames() {
|
||||||
return Collections.unmodifiableList(tagNames);
|
return Collections.unmodifiableList(tagNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +245,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param interestingSetName
|
* @param interestingSetName
|
||||||
*/
|
*/
|
||||||
void addInterestingSetName(String interestingSetName) {
|
public void addInterestingSetName(String interestingSetName) {
|
||||||
if (!interestingSetNames.contains(interestingSetName)) {
|
if (!interestingSetNames.contains(interestingSetName)) {
|
||||||
interestingSetNames.add(interestingSetName);
|
interestingSetNames.add(interestingSetName);
|
||||||
}
|
}
|
||||||
@ -259,7 +259,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return the interesting item set names that matched this file.
|
* @return the interesting item set names that matched this file.
|
||||||
*/
|
*/
|
||||||
List<String> getInterestingSetNames() {
|
public List<String> getInterestingSetNames() {
|
||||||
return Collections.unmodifiableList(interestingSetNames);
|
return Collections.unmodifiableList(interestingSetNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @param objectDetectedName
|
* @param objectDetectedName
|
||||||
*/
|
*/
|
||||||
void addObjectDetectedName(String objectDetectedName) {
|
public void addObjectDetectedName(String objectDetectedName) {
|
||||||
if (!objectDetectedNames.contains(objectDetectedName)) {
|
if (!objectDetectedNames.contains(objectDetectedName)) {
|
||||||
objectDetectedNames.add(objectDetectedName);
|
objectDetectedNames.add(objectDetectedName);
|
||||||
}
|
}
|
||||||
@ -282,7 +282,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return the objects detected in this file.
|
* @return the objects detected in this file.
|
||||||
*/
|
*/
|
||||||
List<String> getObjectDetectedNames() {
|
public List<String> getObjectDetectedNames() {
|
||||||
return Collections.unmodifiableList(objectDetectedNames);
|
return Collections.unmodifiableList(objectDetectedNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ class ResultFile {
|
|||||||
*
|
*
|
||||||
* @return the AbstractFile object
|
* @return the AbstractFile object
|
||||||
*/
|
*/
|
||||||
AbstractFile getFirstInstance() {
|
public AbstractFile getFirstInstance() {
|
||||||
return instances.get(0);
|
return instances.get(0);
|
||||||
}
|
}
|
||||||
|
|
@ -16,17 +16,17 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class to contain data that is common to all result types.
|
* Abstract class to contain data that is common to all result types.
|
||||||
*/
|
*/
|
||||||
abstract class SearchData {
|
public interface SearchData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum of the broad result type categories.
|
* Enum of the broad result type categories.
|
||||||
*/
|
*/
|
||||||
enum ResultType {
|
public enum ResultType {
|
||||||
FILE,
|
FILE,
|
||||||
ATTRIBUTE;
|
ATTRIBUTE;
|
||||||
}
|
}
|
||||||
@ -34,6 +34,6 @@ abstract class SearchData {
|
|||||||
/**
|
/**
|
||||||
* Get the broad result type.
|
* Get the broad result type.
|
||||||
*/
|
*/
|
||||||
abstract ResultType getResultType();
|
public abstract ResultType getResultType();
|
||||||
|
|
||||||
}
|
}
|
@ -16,15 +16,15 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileSize;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.Frequency;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Score;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.Score;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
@ -42,7 +42,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
|||||||
/**
|
/**
|
||||||
* Run various filters to return a subset of files from the current case.
|
* Run various filters to return a subset of files from the current case.
|
||||||
*/
|
*/
|
||||||
class SearchFiltering {
|
public class SearchFiltering {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the given filters to get a list of matching files.
|
* Run the given filters to get a list of matching files.
|
||||||
@ -125,7 +125,7 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying the file size
|
* A filter for specifying the file size
|
||||||
*/
|
*/
|
||||||
static class SizeFilter extends AbstractFilter {
|
public static class SizeFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<FileSize> fileSizes;
|
private final List<FileSize> fileSizes;
|
||||||
|
|
||||||
@ -134,12 +134,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param fileSizes the file sizes that should match
|
* @param fileSizes the file sizes that should match
|
||||||
*/
|
*/
|
||||||
SizeFilter(List<FileSize> fileSizes) {
|
public SizeFilter(List<FileSize> fileSizes) {
|
||||||
this.fileSizes = fileSizes;
|
this.fileSizes = fileSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (FileSize size : fileSizes) {
|
for (FileSize size : fileSizes) {
|
||||||
if (!queryStr.isEmpty()) {
|
if (!queryStr.isEmpty()) {
|
||||||
@ -159,7 +159,7 @@ class SearchFiltering {
|
|||||||
"SearchFiltering.SizeFilter.desc=Size(s): {0}",
|
"SearchFiltering.SizeFilter.desc=Size(s): {0}",
|
||||||
"SearchFiltering.SizeFilter.or=, "})
|
"SearchFiltering.SizeFilter.or=, "})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
String desc = ""; // NON-NLS
|
String desc = ""; // NON-NLS
|
||||||
for (FileSize size : fileSizes) {
|
for (FileSize size : fileSizes) {
|
||||||
if (!desc.isEmpty()) {
|
if (!desc.isEmpty()) {
|
||||||
@ -176,7 +176,7 @@ class SearchFiltering {
|
|||||||
* A utility class for the ParentFilter to store the search string and
|
* A utility class for the ParentFilter to store the search string and
|
||||||
* whether it is a full path or a substring.
|
* whether it is a full path or a substring.
|
||||||
*/
|
*/
|
||||||
static class ParentSearchTerm {
|
public static class ParentSearchTerm {
|
||||||
|
|
||||||
private final String searchStr;
|
private final String searchStr;
|
||||||
private final boolean fullPath;
|
private final boolean fullPath;
|
||||||
@ -191,7 +191,7 @@ class SearchFiltering {
|
|||||||
* @param isIncluded True if the results must include the path, false if
|
* @param isIncluded True if the results must include the path, false if
|
||||||
* the path should be excluded from the results.
|
* the path should be excluded from the results.
|
||||||
*/
|
*/
|
||||||
ParentSearchTerm(String searchStr, boolean isFullPath, boolean isIncluded) {
|
public ParentSearchTerm(String searchStr, boolean isFullPath, boolean isIncluded) {
|
||||||
this.searchStr = searchStr;
|
this.searchStr = searchStr;
|
||||||
this.fullPath = isFullPath;
|
this.fullPath = isFullPath;
|
||||||
this.included = isIncluded;
|
this.included = isIncluded;
|
||||||
@ -202,7 +202,7 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @return The SQL for a where clause to search for a matching path
|
* @return The SQL for a where clause to search for a matching path
|
||||||
*/
|
*/
|
||||||
String getSQLForTerm() {
|
public String getSQLForTerm() {
|
||||||
// TODO - these should really be prepared statements
|
// TODO - these should really be prepared statements
|
||||||
if (isIncluded()) {
|
if (isIncluded()) {
|
||||||
if (isFullPath()) {
|
if (isFullPath()) {
|
||||||
@ -243,21 +243,21 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* @return the fullPath
|
* @return the fullPath
|
||||||
*/
|
*/
|
||||||
boolean isFullPath() {
|
public boolean isFullPath() {
|
||||||
return fullPath;
|
return fullPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the included
|
* @return the included
|
||||||
*/
|
*/
|
||||||
boolean isIncluded() {
|
public boolean isIncluded() {
|
||||||
return included;
|
return included;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the searchStr
|
* @return the searchStr
|
||||||
*/
|
*/
|
||||||
String getSearchStr() {
|
public String getSearchStr() {
|
||||||
return searchStr;
|
return searchStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying parent path (either full path or substring)
|
* A filter for specifying parent path (either full path or substring)
|
||||||
*/
|
*/
|
||||||
static class ParentFilter extends AbstractFilter {
|
public static class ParentFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<ParentSearchTerm> parentSearchTerms;
|
private final List<ParentSearchTerm> parentSearchTerms;
|
||||||
|
|
||||||
@ -274,12 +274,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param parentSearchTerms Full paths or substrings to filter on
|
* @param parentSearchTerms Full paths or substrings to filter on
|
||||||
*/
|
*/
|
||||||
ParentFilter(List<ParentSearchTerm> parentSearchTerms) {
|
public ParentFilter(List<ParentSearchTerm> parentSearchTerms) {
|
||||||
this.parentSearchTerms = parentSearchTerms;
|
this.parentSearchTerms = parentSearchTerms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String includeQueryStr = ""; // NON-NLS
|
String includeQueryStr = ""; // NON-NLS
|
||||||
String excludeQueryStr = "";
|
String excludeQueryStr = "";
|
||||||
for (ParentSearchTerm searchTerm : parentSearchTerms) {
|
for (ParentSearchTerm searchTerm : parentSearchTerms) {
|
||||||
@ -317,7 +317,7 @@ class SearchFiltering {
|
|||||||
"SearchFiltering.ParentFilter.included=(included)",
|
"SearchFiltering.ParentFilter.included=(included)",
|
||||||
"SearchFiltering.ParentFilter.excluded=(excluded)"})
|
"SearchFiltering.ParentFilter.excluded=(excluded)"})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
String desc = ""; // NON-NLS
|
String desc = ""; // NON-NLS
|
||||||
for (ParentSearchTerm searchTerm : parentSearchTerms) {
|
for (ParentSearchTerm searchTerm : parentSearchTerms) {
|
||||||
if (!desc.isEmpty()) {
|
if (!desc.isEmpty()) {
|
||||||
@ -342,7 +342,7 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying data sources
|
* A filter for specifying data sources
|
||||||
*/
|
*/
|
||||||
static class DataSourceFilter extends AbstractFilter {
|
public static class DataSourceFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<DataSource> dataSources;
|
private final List<DataSource> dataSources;
|
||||||
|
|
||||||
@ -351,12 +351,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param dataSources the data sources to filter on
|
* @param dataSources the data sources to filter on
|
||||||
*/
|
*/
|
||||||
DataSourceFilter(List<DataSource> dataSources) {
|
public DataSourceFilter(List<DataSource> dataSources) {
|
||||||
this.dataSources = dataSources;
|
this.dataSources = dataSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (DataSource ds : dataSources) {
|
for (DataSource ds : dataSources) {
|
||||||
if (!queryStr.isEmpty()) {
|
if (!queryStr.isEmpty()) {
|
||||||
@ -376,7 +376,7 @@ class SearchFiltering {
|
|||||||
"# {1} - Data source ID",
|
"# {1} - Data source ID",
|
||||||
"SearchFiltering.DataSourceFilter.datasource={0}({1})",})
|
"SearchFiltering.DataSourceFilter.datasource={0}({1})",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
String desc = ""; // NON-NLS
|
String desc = ""; // NON-NLS
|
||||||
for (DataSource ds : dataSources) {
|
for (DataSource ds : dataSources) {
|
||||||
if (!desc.isEmpty()) {
|
if (!desc.isEmpty()) {
|
||||||
@ -393,7 +393,7 @@ class SearchFiltering {
|
|||||||
* A filter for specifying keyword list names. A file must contain a keyword
|
* A filter for specifying keyword list names. A file must contain a keyword
|
||||||
* from one of the given lists to pass.
|
* from one of the given lists to pass.
|
||||||
*/
|
*/
|
||||||
static class KeywordListFilter extends AbstractFilter {
|
public static class KeywordListFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<String> listNames;
|
private final List<String> listNames;
|
||||||
|
|
||||||
@ -402,12 +402,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param listNames
|
* @param listNames
|
||||||
*/
|
*/
|
||||||
KeywordListFilter(List<String> listNames) {
|
public KeywordListFilter(List<String> listNames) {
|
||||||
this.listNames = listNames;
|
this.listNames = listNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String keywordListPart = concatenateNamesForSQL(listNames);
|
String keywordListPart = concatenateNamesForSQL(listNames);
|
||||||
|
|
||||||
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
||||||
@ -421,7 +421,7 @@ class SearchFiltering {
|
|||||||
"# {0} - filters",
|
"# {0} - filters",
|
||||||
"SearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}",})
|
"SearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.SearchFiltering_KeywordListFilter_desc(concatenateSetNamesForDisplay(listNames));
|
return Bundle.SearchFiltering_KeywordListFilter_desc(concatenateSetNamesForDisplay(listNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,7 +429,7 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying file types.
|
* A filter for specifying file types.
|
||||||
*/
|
*/
|
||||||
static class FileTypeFilter extends AbstractFilter {
|
public static class FileTypeFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<FileType> categories;
|
private final List<FileType> categories;
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param categories List of file types to filter on
|
* @param categories List of file types to filter on
|
||||||
*/
|
*/
|
||||||
FileTypeFilter(List<FileType> categories) {
|
public FileTypeFilter(List<FileType> categories) {
|
||||||
this.categories = categories;
|
this.categories = categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,13 +447,13 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param category the file type to filter on
|
* @param category the file type to filter on
|
||||||
*/
|
*/
|
||||||
FileTypeFilter(FileType category) {
|
public FileTypeFilter(FileType category) {
|
||||||
this.categories = new ArrayList<>();
|
this.categories = new ArrayList<>();
|
||||||
this.categories.add(category);
|
this.categories.add(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (FileType cat : categories) {
|
for (FileType cat : categories) {
|
||||||
for (String type : cat.getMediaTypes()) {
|
for (String type : cat.getMediaTypes()) {
|
||||||
@ -472,7 +472,7 @@ class SearchFiltering {
|
|||||||
"SearchFiltering.FileTypeFilter.desc=Type: {0}",
|
"SearchFiltering.FileTypeFilter.desc=Type: {0}",
|
||||||
"SearchFiltering.FileTypeFilter.or=, ",})
|
"SearchFiltering.FileTypeFilter.or=, ",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
String desc = "";
|
String desc = "";
|
||||||
for (FileType cat : categories) {
|
for (FileType cat : categories) {
|
||||||
if (!desc.isEmpty()) {
|
if (!desc.isEmpty()) {
|
||||||
@ -488,7 +488,7 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying frequency in the central repository.
|
* A filter for specifying frequency in the central repository.
|
||||||
*/
|
*/
|
||||||
static class FrequencyFilter extends AbstractFilter {
|
public static class FrequencyFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<Frequency> frequencies;
|
private final List<Frequency> frequencies;
|
||||||
|
|
||||||
@ -497,24 +497,24 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param frequencies List of frequencies that will pass the filter
|
* @param frequencies List of frequencies that will pass the filter
|
||||||
*/
|
*/
|
||||||
FrequencyFilter(List<Frequency> frequencies) {
|
public FrequencyFilter(List<Frequency> frequencies) {
|
||||||
this.frequencies = frequencies;
|
this.frequencies = frequencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
// Since this relies on the central repository database, there is no
|
// Since this relies on the central repository database, there is no
|
||||||
// query on the case database.
|
// query on the case database.
|
||||||
return ""; // NON-NLS
|
return ""; // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean useAlternateFilter() {
|
public boolean useAlternateFilter() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws FileSearchException {
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
// We have to have run some kind of SQL filter before getting to this point,
|
// We have to have run some kind of SQL filter before getting to this point,
|
||||||
@ -542,7 +542,7 @@ class SearchFiltering {
|
|||||||
"SearchFiltering.FrequencyFilter.desc=Past occurrences: {0}",
|
"SearchFiltering.FrequencyFilter.desc=Past occurrences: {0}",
|
||||||
"SearchFiltering.FrequencyFilter.or=, ",})
|
"SearchFiltering.FrequencyFilter.or=, ",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
String desc = ""; // NON-NLS
|
String desc = ""; // NON-NLS
|
||||||
for (Frequency freq : frequencies) {
|
for (Frequency freq : frequencies) {
|
||||||
if (!desc.isEmpty()) {
|
if (!desc.isEmpty()) {
|
||||||
@ -558,7 +558,7 @@ class SearchFiltering {
|
|||||||
* A filter for specifying hash set names. A file must match one of the
|
* A filter for specifying hash set names. A file must match one of the
|
||||||
* given sets to pass.
|
* given sets to pass.
|
||||||
*/
|
*/
|
||||||
static class HashSetFilter extends AbstractFilter {
|
public static class HashSetFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<String> setNames;
|
private final List<String> setNames;
|
||||||
|
|
||||||
@ -567,12 +567,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param setNames
|
* @param setNames
|
||||||
*/
|
*/
|
||||||
HashSetFilter(List<String> setNames) {
|
public HashSetFilter(List<String> setNames) {
|
||||||
this.setNames = setNames;
|
this.setNames = setNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String hashSetPart = concatenateNamesForSQL(setNames);
|
String hashSetPart = concatenateNamesForSQL(setNames);
|
||||||
|
|
||||||
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
||||||
@ -587,7 +587,7 @@ class SearchFiltering {
|
|||||||
"# {0} - filters",
|
"# {0} - filters",
|
||||||
"FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}",})
|
"FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.FileSearchFiltering_HashSetFilter_desc(concatenateSetNamesForDisplay(setNames));
|
return Bundle.FileSearchFiltering_HashSetFilter_desc(concatenateSetNamesForDisplay(setNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -596,7 +596,7 @@ class SearchFiltering {
|
|||||||
* A filter for specifying interesting file set names. A file must match one
|
* A filter for specifying interesting file set names. A file must match one
|
||||||
* of the given sets to pass.
|
* of the given sets to pass.
|
||||||
*/
|
*/
|
||||||
static class InterestingFileSetFilter extends AbstractFilter {
|
public static class InterestingFileSetFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<String> setNames;
|
private final List<String> setNames;
|
||||||
|
|
||||||
@ -605,12 +605,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param setNames
|
* @param setNames
|
||||||
*/
|
*/
|
||||||
InterestingFileSetFilter(List<String> setNames) {
|
public InterestingFileSetFilter(List<String> setNames) {
|
||||||
this.setNames = setNames;
|
this.setNames = setNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String intItemSetPart = concatenateNamesForSQL(setNames);
|
String intItemSetPart = concatenateNamesForSQL(setNames);
|
||||||
|
|
||||||
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
||||||
@ -625,7 +625,7 @@ class SearchFiltering {
|
|||||||
"# {0} - filters",
|
"# {0} - filters",
|
||||||
"SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}",})
|
"SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.SearchFiltering_InterestingItemSetFilter_desc(concatenateSetNamesForDisplay(setNames));
|
return Bundle.SearchFiltering_InterestingItemSetFilter_desc(concatenateSetNamesForDisplay(setNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,7 +634,7 @@ class SearchFiltering {
|
|||||||
* A filter for specifying object types detected. A file must match one of
|
* A filter for specifying object types detected. A file must match one of
|
||||||
* the given types to pass.
|
* the given types to pass.
|
||||||
*/
|
*/
|
||||||
static class ObjectDetectionFilter extends AbstractFilter {
|
public static class ObjectDetectionFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<String> typeNames;
|
private final List<String> typeNames;
|
||||||
|
|
||||||
@ -643,12 +643,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param typeNames
|
* @param typeNames
|
||||||
*/
|
*/
|
||||||
ObjectDetectionFilter(List<String> typeNames) {
|
public ObjectDetectionFilter(List<String> typeNames) {
|
||||||
this.typeNames = typeNames;
|
this.typeNames = typeNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String objTypePart = concatenateNamesForSQL(typeNames);
|
String objTypePart = concatenateNamesForSQL(typeNames);
|
||||||
|
|
||||||
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
||||||
@ -663,7 +663,7 @@ class SearchFiltering {
|
|||||||
"# {0} - filters",
|
"# {0} - filters",
|
||||||
"SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}",})
|
"SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.SearchFiltering_ObjectDetectionFilter_desc(concatenateSetNamesForDisplay(typeNames));
|
return Bundle.SearchFiltering_ObjectDetectionFilter_desc(concatenateSetNamesForDisplay(typeNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -672,7 +672,7 @@ class SearchFiltering {
|
|||||||
* A filter for specifying the score. A file must have one of the given
|
* A filter for specifying the score. A file must have one of the given
|
||||||
* scores to pass
|
* scores to pass
|
||||||
*/
|
*/
|
||||||
static class ScoreFilter extends AbstractFilter {
|
public static class ScoreFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<Score> scores;
|
private final List<Score> scores;
|
||||||
|
|
||||||
@ -681,12 +681,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param typeNames
|
* @param typeNames
|
||||||
*/
|
*/
|
||||||
ScoreFilter(List<Score> scores) {
|
public ScoreFilter(List<Score> scores) {
|
||||||
this.scores = scores;
|
this.scores = scores;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
|
|
||||||
// Current algorithm:
|
// Current algorithm:
|
||||||
// "Notable" if the file is a match for a notable hashset or has been tagged with a notable tag.
|
// "Notable" if the file is a match for a notable hashset or has been tagged with a notable tag.
|
||||||
@ -739,7 +739,7 @@ class SearchFiltering {
|
|||||||
"# {0} - filters",
|
"# {0} - filters",
|
||||||
"SearchFiltering.ScoreFilter.desc=Score(s) of : {0}",})
|
"SearchFiltering.ScoreFilter.desc=Score(s) of : {0}",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.SearchFiltering_ScoreFilter_desc(
|
return Bundle.SearchFiltering_ScoreFilter_desc(
|
||||||
concatenateSetNamesForDisplay(scores.stream().map(p -> p.toString()).collect(Collectors.toList())));
|
concatenateSetNamesForDisplay(scores.stream().map(p -> p.toString()).collect(Collectors.toList())));
|
||||||
}
|
}
|
||||||
@ -749,7 +749,7 @@ class SearchFiltering {
|
|||||||
* A filter for specifying tag names. A file must contain one of the given
|
* A filter for specifying tag names. A file must contain one of the given
|
||||||
* tags to pass.
|
* tags to pass.
|
||||||
*/
|
*/
|
||||||
static class TagsFilter extends AbstractFilter {
|
public static class TagsFilter extends AbstractFilter {
|
||||||
|
|
||||||
private final List<TagName> tagNames;
|
private final List<TagName> tagNames;
|
||||||
|
|
||||||
@ -758,12 +758,12 @@ class SearchFiltering {
|
|||||||
*
|
*
|
||||||
* @param tagNames
|
* @param tagNames
|
||||||
*/
|
*/
|
||||||
TagsFilter(List<TagName> tagNames) {
|
public TagsFilter(List<TagName> tagNames) {
|
||||||
this.tagNames = tagNames;
|
this.tagNames = tagNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
String tagIDs = ""; // NON-NLS
|
String tagIDs = ""; // NON-NLS
|
||||||
for (TagName tagName : tagNames) {
|
for (TagName tagName : tagNames) {
|
||||||
if (!tagIDs.isEmpty()) {
|
if (!tagIDs.isEmpty()) {
|
||||||
@ -782,7 +782,7 @@ class SearchFiltering {
|
|||||||
"FileSearchFiltering.TagsFilter.desc=Tagged {0}",
|
"FileSearchFiltering.TagsFilter.desc=Tagged {0}",
|
||||||
"FileSearchFiltering.TagsFilter.or=, ",})
|
"FileSearchFiltering.TagsFilter.or=, ",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
String desc = ""; // NON-NLS
|
String desc = ""; // NON-NLS
|
||||||
for (TagName name : tagNames) {
|
for (TagName name : tagNames) {
|
||||||
if (!desc.isEmpty()) {
|
if (!desc.isEmpty()) {
|
||||||
@ -798,17 +798,10 @@ class SearchFiltering {
|
|||||||
* A filter for specifying that the file must have user content suspected
|
* A filter for specifying that the file must have user content suspected
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
static class UserCreatedFilter extends AbstractFilter {
|
public static class UserCreatedFilter extends AbstractFilter {
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the ExifFilter
|
|
||||||
*/
|
|
||||||
UserCreatedFilter() {
|
|
||||||
// Nothing to save
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
return "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
return "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN "
|
||||||
+ "(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = "
|
+ "(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = "
|
||||||
+ BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() + ")))";
|
+ BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() + ")))";
|
||||||
@ -817,7 +810,7 @@ class SearchFiltering {
|
|||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data",})
|
"FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.FileSearchFiltering_UserCreatedFilter_desc();
|
return Bundle.FileSearchFiltering_UserCreatedFilter_desc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,29 +819,22 @@ class SearchFiltering {
|
|||||||
* A filter for specifying that the file must have been marked as notable in
|
* A filter for specifying that the file must have been marked as notable in
|
||||||
* the CR.
|
* the CR.
|
||||||
*/
|
*/
|
||||||
static class NotableFilter extends AbstractFilter {
|
public static class NotableFilter extends AbstractFilter {
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the NotableFilter
|
|
||||||
*/
|
|
||||||
NotableFilter() {
|
|
||||||
// Nothing to save
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
// Since this relies on the central repository database, there is no
|
// Since this relies on the central repository database, there is no
|
||||||
// query on the case database.
|
// query on the case database.
|
||||||
return ""; // NON-NLS
|
return ""; // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean useAlternateFilter() {
|
public boolean useAlternateFilter() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
|
||||||
CentralRepository centralRepoDb) throws FileSearchException {
|
CentralRepository centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
if (centralRepoDb == null) {
|
if (centralRepoDb == null) {
|
||||||
@ -886,7 +872,7 @@ class SearchFiltering {
|
|||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable",})
|
"FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable",})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc();
|
return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -894,17 +880,17 @@ class SearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying if known files should be included.
|
* A filter for specifying if known files should be included.
|
||||||
*/
|
*/
|
||||||
static class KnownFilter extends AbstractFilter {
|
public static class KnownFilter extends AbstractFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getWhereClause() {
|
public String getWhereClause() {
|
||||||
return "known!=" + TskData.FileKnown.KNOWN.getFileKnownValue(); // NON-NLS
|
return "known!=" + TskData.FileKnown.KNOWN.getFileKnownValue(); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"FileSearchFiltering.KnownFilter.desc=which are not known"})
|
"FileSearchFiltering.KnownFilter.desc=which are not known"})
|
||||||
@Override
|
@Override
|
||||||
String getDesc() {
|
public String getDesc() {
|
||||||
return Bundle.FileSearchFiltering_KnownFilter_desc();
|
return Bundle.FileSearchFiltering_KnownFilter_desc();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.search;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -25,7 +25,7 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to hold the results of the filtering/grouping/sorting operations.
|
* Class to hold the results of the filtering/grouping/sorting operations.
|
||||||
@ -36,7 +36,7 @@ class SearchResults {
|
|||||||
private final FileSearch.AttributeType attrType;
|
private final FileSearch.AttributeType attrType;
|
||||||
private final FileSorter fileSorter;
|
private final FileSorter fileSorter;
|
||||||
|
|
||||||
private final Map<FileSearch.GroupKey, FileGroup> groupMap = new HashMap<>();
|
private final Map<GroupKey, FileGroup> groupMap = new HashMap<>();
|
||||||
private List<FileGroup> groupList = new ArrayList<>();
|
private List<FileGroup> groupList = new ArrayList<>();
|
||||||
|
|
||||||
private static final long MAX_OUTPUT_FILES = 2000; // For debug UI - maximum number of lines to print
|
private static final long MAX_OUTPUT_FILES = 2000; // For debug UI - maximum number of lines to print
|
||||||
@ -75,7 +75,7 @@ class SearchResults {
|
|||||||
void add(List<ResultFile> files) {
|
void add(List<ResultFile> files) {
|
||||||
for (ResultFile file : files) {
|
for (ResultFile file : files) {
|
||||||
// Add the file to the appropriate group, creating it if necessary
|
// Add the file to the appropriate group, creating it if necessary
|
||||||
FileSearch.GroupKey groupKey = attrType.getGroupKey(file);
|
GroupKey groupKey = attrType.getGroupKey(file);
|
||||||
|
|
||||||
if (!groupMap.containsKey(groupKey)) {
|
if (!groupMap.containsKey(groupKey)) {
|
||||||
groupMap.put(groupKey, new FileGroup(groupSortingType, groupKey));
|
groupMap.put(groupKey, new FileGroup(groupSortingType, groupKey));
|
@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 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.discovery.search;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.textextractors.TextExtractor;
|
||||||
|
import org.sleuthkit.autopsy.textextractors.TextExtractorFactory;
|
||||||
|
import org.sleuthkit.autopsy.textsummarizer.TextSummarizer;
|
||||||
|
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.TranslationException;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for code which helps create summaries for Discovery.
|
||||||
|
*/
|
||||||
|
class SummaryHelpers {
|
||||||
|
|
||||||
|
private static final int PREVIEW_SIZE = 256;
|
||||||
|
private final static Logger logger = Logger.getLogger(SummaryHelpers.class.getName());
|
||||||
|
private static volatile TextSummarizer summarizerToUse = null;
|
||||||
|
|
||||||
|
private SummaryHelpers() {
|
||||||
|
// Class should not be instantiated
|
||||||
|
}
|
||||||
|
|
||||||
|
static TextSummary getDefaultSummary(AbstractFile file) {
|
||||||
|
Image image = null;
|
||||||
|
int countOfImages = 0;
|
||||||
|
try {
|
||||||
|
Content largestChild = null;
|
||||||
|
for (Content child : file.getChildren()) {
|
||||||
|
if (child instanceof AbstractFile && ImageUtils.isImageThumbnailSupported((AbstractFile) child)) {
|
||||||
|
countOfImages++;
|
||||||
|
if (largestChild == null || child.getSize() > largestChild.getSize()) {
|
||||||
|
largestChild = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (largestChild != null) {
|
||||||
|
image = ImageUtils.getThumbnail(largestChild, ImageUtils.ICON_SIZE_LARGE);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error getting children for file: " + file.getId(), ex);
|
||||||
|
}
|
||||||
|
image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM,
|
||||||
|
Image.SCALE_SMOOTH);
|
||||||
|
String summaryText = null;
|
||||||
|
if (file.getMd5Hash() != null) {
|
||||||
|
try {
|
||||||
|
summaryText = getSavedSummary(Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString());
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to retrieve saved summary. No case is open.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(summaryText)) {
|
||||||
|
String firstLines = getFirstLines(file);
|
||||||
|
String translatedFirstLines = getTranslatedVersion(firstLines);
|
||||||
|
if (!StringUtils.isBlank(translatedFirstLines)) {
|
||||||
|
summaryText = translatedFirstLines;
|
||||||
|
if (file.getMd5Hash() != null) {
|
||||||
|
try {
|
||||||
|
saveSummary(summaryText, Paths.get(Case.getCurrentCaseThrows().getCacheDirectory(), "summaries", file.getMd5Hash() + "-default-" + PREVIEW_SIZE + "-translated.txt").toString());
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to save translated summary. No case is open.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
summaryText = firstLines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TextSummary(summaryText, image, countOfImages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide an English version of the specified String if it is not English,
|
||||||
|
* translation is enabled, and it can be translated.
|
||||||
|
*
|
||||||
|
* @param documentString The String to provide an English version of.
|
||||||
|
*
|
||||||
|
* @return The English version of the provided String, or null if no
|
||||||
|
* translation occurred.
|
||||||
|
*/
|
||||||
|
static String getTranslatedVersion(String documentString) {
|
||||||
|
try {
|
||||||
|
TextTranslationService translatorInstance = TextTranslationService.getInstance();
|
||||||
|
if (translatorInstance.hasProvider()) {
|
||||||
|
String translatedResult = translatorInstance.translate(documentString);
|
||||||
|
if (translatedResult.isEmpty() == false) {
|
||||||
|
return translatedResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoServiceProviderException | TranslationException ex) {
|
||||||
|
logger.log(Level.INFO, "Error translating string for summary", ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find and load a saved summary from the case folder for the specified
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* @param summarySavePath The full path for the saved summary file.
|
||||||
|
*
|
||||||
|
* @return The summary found given the specified path, null if no summary
|
||||||
|
* was found.
|
||||||
|
*/
|
||||||
|
static String getSavedSummary(String summarySavePath) {
|
||||||
|
if (summarySavePath == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
File savedFile = new File(summarySavePath);
|
||||||
|
if (savedFile.exists()) {
|
||||||
|
try (BufferedReader bReader = new BufferedReader(new FileReader(savedFile))) {
|
||||||
|
// pass the path to the file as a parameter
|
||||||
|
StringBuilder sBuilder = new StringBuilder(PREVIEW_SIZE);
|
||||||
|
String sCurrentLine = bReader.readLine();
|
||||||
|
while (sCurrentLine != null) {
|
||||||
|
sBuilder.append(sCurrentLine).append('\n');
|
||||||
|
sCurrentLine = bReader.readLine();
|
||||||
|
}
|
||||||
|
return sBuilder.toString();
|
||||||
|
} catch (IOException ingored) {
|
||||||
|
//summary file may not exist or may be incomplete in which case return null so a summary can be generated
|
||||||
|
return null; //no saved summary was able to be found
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try { //if the file didn't exist make sure the parent directories exist before we move on to creating a summary
|
||||||
|
Files.createParentDirs(savedFile);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to create summaries directory in case folder for file at: " + summarySavePath, ex);
|
||||||
|
}
|
||||||
|
return null; //no saved summary was able to be found
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a summary at the specified location.
|
||||||
|
*
|
||||||
|
* @param summary The text of the summary being saved.
|
||||||
|
* @param summarySavePath The full path for the saved summary file.
|
||||||
|
*/
|
||||||
|
static void saveSummary(String summary, String summarySavePath) {
|
||||||
|
if (summarySavePath == null) {
|
||||||
|
return; //can't save a summary if we don't have a path
|
||||||
|
}
|
||||||
|
try (FileWriter myWriter = new FileWriter(summarySavePath)) {
|
||||||
|
myWriter.write(summary);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to save summary at: " + summarySavePath, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the beginning of text from the specified AbstractFile.
|
||||||
|
*
|
||||||
|
* @param file The AbstractFile to get text from.
|
||||||
|
*
|
||||||
|
* @return The beginning of text from the specified AbstractFile.
|
||||||
|
*/
|
||||||
|
static String getFirstLines(AbstractFile file) {
|
||||||
|
TextExtractor extractor;
|
||||||
|
try {
|
||||||
|
extractor = TextExtractorFactory.getExtractor(file, null);
|
||||||
|
} catch (TextExtractorFactory.NoTextExtractorFound ignored) {
|
||||||
|
//no extractor found, use Strings Extractor
|
||||||
|
extractor = TextExtractorFactory.getStringsExtractor(file, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Reader reader = extractor.getReader()) {
|
||||||
|
char[] cbuf = new char[PREVIEW_SIZE];
|
||||||
|
reader.read(cbuf, 0, PREVIEW_SIZE);
|
||||||
|
return new String(cbuf);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return Bundle.FileSearch_documentSummary_noBytes();
|
||||||
|
} catch (TextExtractor.InitReaderException ex) {
|
||||||
|
return Bundle.FileSearch_documentSummary_noPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first TextSummarizer found by a lookup of TextSummarizers.
|
||||||
|
*
|
||||||
|
* @return The first TextSummarizer found by a lookup of TextSummarizers.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
static TextSummarizer getLocalSummarizer() {
|
||||||
|
if (summarizerToUse == null) {
|
||||||
|
Collection<? extends TextSummarizer> summarizers
|
||||||
|
= Lookup.getDefault().lookupAll(TextSummarizer.class
|
||||||
|
);
|
||||||
|
if (!summarizers.isEmpty()) {
|
||||||
|
summarizerToUse = summarizers.iterator().next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return summarizerToUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
@ -31,6 +32,10 @@ import javax.swing.JSplitPane;
|
|||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class extending JPanel for displaying all the filters associated
|
* Abstract class extending JPanel for displaying all the filters associated
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="artifactTypeCheckbox">
|
<Component class="javax.swing.JCheckBox" name="artifactTypeCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ArtifactTypeFilterPanel.artifactTypeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ArtifactTypeFilterPanel.artifactTypeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
@ -16,16 +16,18 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter for selection of a specific Arrtifact type to limit results to.
|
* Filter for selection of a specific Artifact type to limit results to.
|
||||||
*/
|
*/
|
||||||
class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
|
class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
|
||||||
|
|
||||||
@ -80,11 +82,11 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
|
|||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(artifactTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 229, Short.MAX_VALUE)
|
.addComponent(artifactTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(artifactTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 38, Short.MAX_VALUE)
|
.addComponent(artifactTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
@ -0,0 +1,56 @@
|
|||||||
|
# To change this license header, choose License Headers in Project Properties.
|
||||||
|
# To change this template file, choose Tools | Templates
|
||||||
|
# and open the template in the editor.
|
||||||
|
ResultsPanel.currentPageLabel.text=Page: -
|
||||||
|
DiscoveryDialog.sortingPanel.border.title=Step 3: Choose display settings
|
||||||
|
DiscoveryDialog.searchButton.text=Search
|
||||||
|
DiscoveryDialog.domainsButton.text=Domains
|
||||||
|
DiscoveryDialog.groupByLabel.text=Group By:
|
||||||
|
DiscoveryDialog.step1Label.text=Step 1: Choose result type
|
||||||
|
DiscoveryDialog.orderByLabel.text=Order Within Groups By:
|
||||||
|
DiscoveryDialog.documentsButton.text=Documents
|
||||||
|
DiscoveryDialog.orderGroupsByLabel.text=Order Groups By:
|
||||||
|
DiscoveryDialog.videosButton.text=Videos
|
||||||
|
DiscoveryDialog.imagesButton.text=Images
|
||||||
|
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
|
||||||
|
DataSourceFilterPanel.dataSourceCheckbox.text=Data Source:
|
||||||
|
ParentFolderFilterPanel.parentLabel.text_1=(All will be used)
|
||||||
|
ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder:
|
||||||
|
ParentFolderFilterPanel.addButton.text_1=Add
|
||||||
|
ParentFolderFilterPanel.deleteButton.text_1=Delete
|
||||||
|
ParentFolderFilterPanel.excludeRadioButton.text_1=Exclude
|
||||||
|
ParentFolderFilterPanel.substringRadioButton.text_1=Substring
|
||||||
|
ParentFolderFilterPanel.includeRadioButton.text_1=Include
|
||||||
|
ParentFolderFilterPanel.fullRadioButton.text_1=Full
|
||||||
|
UserCreatedFilterPanel.userCreatedCheckbox.text_1=Possibly User Created
|
||||||
|
GroupListPanel.groupKeyList.border.title=Groups
|
||||||
|
ResultsSplitPaneDivider.detailsLabel.text=Details Area
|
||||||
|
ResultsSplitPaneDivider.showButton.text=
|
||||||
|
ResultsSplitPaneDivider.hideButton.text=
|
||||||
|
ImageFilterPanel.imageFiltersSplitPane.toolTipText=
|
||||||
|
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
|
||||||
|
ArtifactTypeFilterPanel.artifactTypeCheckbox.text=Artifact Type:
|
||||||
|
InterestingItemsFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||||
|
DocumentPanel.fileSizeLabel.toolTipText=
|
||||||
|
DocumentPanel.isDeletedLabel.toolTipText=
|
||||||
|
DomainFilterPanel.domainFiltersSplitPane.toolTipText=
|
||||||
|
DomainFilterPanel.domainFiltersSplitPane.border.title=Step 2: Filter which domains to show
|
||||||
|
SizeFilterPanel.sizeCheckbox.text=File Size:
|
||||||
|
DateFilterPanel.dateFilterCheckbox.text=Date Filter:
|
||||||
|
DateFilterPanel.endCheckBox.text=End:
|
||||||
|
DateFilterPanel.startCheckBox.text=Start:
|
||||||
|
DateFilterPanel.mostRecentButton.text=Only last:
|
||||||
|
DateFilterPanel.daysLabel.text=days of activity
|
||||||
|
ImageThumbnailPanel.isDeletedLabel.toolTipText=
|
||||||
|
ResultsPanel.pageControlsLabel.text=Pages:
|
||||||
|
ResultsPanel.currentPageLabel.text=Page: -
|
||||||
|
ResultsPanel.pageSizeLabel.text=Page Size:
|
||||||
|
ResultsPanel.gotoPageLabel.text=Go to Page:
|
||||||
|
# To change this license header, choose License Headers in Project Properties.
|
||||||
|
# To change this template file, choose Tools | Templates
|
||||||
|
# and open the template in the editor.
|
||||||
|
HashSetFilterPanel.hashSetCheckbox.text=Hash Set:
|
||||||
|
PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text=Past Occurrences:
|
||||||
|
DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which documents to show
|
||||||
|
ObjectDetectedFilterPanel.text=Object Detected:
|
||||||
|
DetailsPanel.instancesList.border.title=Instances
|
@ -0,0 +1,121 @@
|
|||||||
|
CTL_OpenDiscoveryAction=Discovery
|
||||||
|
# {0} - dataSourceName
|
||||||
|
DataSourceModuleWrapper.exifModule.text=Exif Parser module was not run on data source: {0}\n
|
||||||
|
# {0} - dataSourceName
|
||||||
|
DataSourceModuleWrapper.fileTypeModule.text=File Type Identification module was not run on data source: {0}\n
|
||||||
|
# {0} - dataSourceName
|
||||||
|
DataSourceModuleWrapper.hashModule.text=Hash Lookup module was not run on data source: {0}\n
|
||||||
|
# {0} - timeZone
|
||||||
|
DateFilterPanel.dateRange.text=Date Range ({0}):
|
||||||
|
DiscoveryDialog.name.text=Discovery
|
||||||
|
DiscoveryTopComponent.cancelButton.text=Cancel Search
|
||||||
|
DiscoveryTopComponent.name=\ Discovery
|
||||||
|
DiscoveryTopComponent.newSearch.text=New Search
|
||||||
|
DiscoveryTopComponent.searchCancelled.text=Search has been cancelled.
|
||||||
|
# {0} - search
|
||||||
|
DiscoveryTopComponent.searchComplete.text=Results with {0}
|
||||||
|
DiscoveryTopComponent.searchError.text=Error no type specified for search.
|
||||||
|
# {0} - searchType
|
||||||
|
DiscoveryTopComponent.searchInProgress.text=Performing search for results of type {0}. Please wait.
|
||||||
|
DiscoveryUiUtility.bytes.text=bytes
|
||||||
|
DiscoveryUiUtility.gigaBytes.text=GB
|
||||||
|
DiscoveryUiUtility.kiloBytes.text=KB
|
||||||
|
DiscoveryUiUtility.megaBytes.text=MB
|
||||||
|
# {0} - fileSize
|
||||||
|
# {1} - units
|
||||||
|
DiscoveryUiUtility.sizeLabel.text=Size: {0} {1}
|
||||||
|
DiscoveryUiUtility.terraBytes.text=TB
|
||||||
|
# {0} - file name
|
||||||
|
DiscoveryUiUtils.genVideoThumb.progress.text=extracting temporary file {0}
|
||||||
|
DiscoveryUiUtils.isDeleted.text=All instances of file are deleted.
|
||||||
|
# {0} - otherInstanceCount
|
||||||
|
DocumentPanel.nameLabel.more.text=\ and {0} more
|
||||||
|
DocumentPanel.noImageExtraction.text=0 of ? images
|
||||||
|
DocumentPanel.numberOfImages.noImages=No images
|
||||||
|
# {0} - numberOfImages
|
||||||
|
DocumentPanel.numberOfImages.text=1 of {0} images
|
||||||
|
DocumentWrapper.previewInitialValue=Preview not generated yet.
|
||||||
|
GroupsListPanel.noResults.message.text=No results were found for the selected filters.\n\nReminder:\n -The File Type Identification module must be run on each data source you want to find results in.\n -The Hash Lookup module must be run on each data source if you want to filter by past occurrence.\n -The Exif module must be run on each data source if you are filtering by User Created content.
|
||||||
|
GroupsListPanel.noResults.title.text=No results found
|
||||||
|
ImageThumbnailPanel.isDeleted.text=All instances of file are deleted.
|
||||||
|
# {0} - otherInstanceCount
|
||||||
|
ImageThumbnailPanel.nameLabel.more.text=\ and {0} more
|
||||||
|
OpenDiscoveryAction.resultsIncomplete.text=Discovery results may be incomplete
|
||||||
|
# {0} - currentPage
|
||||||
|
# {1} - totalPages
|
||||||
|
ResultsPanel.currentPage.displayValue=Page: {0} of {1}
|
||||||
|
# To change this license header, choose License Headers in Project Properties.
|
||||||
|
# To change this template file, choose Tools | Templates
|
||||||
|
# and open the template in the editor.
|
||||||
|
ResultsPanel.currentPageLabel.text=Page: -
|
||||||
|
DiscoveryDialog.sortingPanel.border.title=Step 3: Choose display settings
|
||||||
|
DiscoveryDialog.searchButton.text=Search
|
||||||
|
DiscoveryDialog.domainsButton.text=Domains
|
||||||
|
DiscoveryDialog.groupByLabel.text=Group By:
|
||||||
|
DiscoveryDialog.step1Label.text=Step 1: Choose result type
|
||||||
|
DiscoveryDialog.orderByLabel.text=Order Within Groups By:
|
||||||
|
DiscoveryDialog.documentsButton.text=Documents
|
||||||
|
DiscoveryDialog.orderGroupsByLabel.text=Order Groups By:
|
||||||
|
DiscoveryDialog.videosButton.text=Videos
|
||||||
|
DiscoveryDialog.imagesButton.text=Images
|
||||||
|
ResultsPanel.documentPreview.text=Document preview creation cancelled.
|
||||||
|
# {0} - selectedPage
|
||||||
|
# {1} - maxPage
|
||||||
|
ResultsPanel.invalidPageNumber.message=The selected page number {0} does not exist. Please select a value from 1 to {1}.
|
||||||
|
ResultsPanel.invalidPageNumber.title=Invalid Page Number
|
||||||
|
ResultsPanel.openInExternalViewer.name=Open in External Viewer
|
||||||
|
ResultsPanel.unableToCreate.text=Unable to create summary.
|
||||||
|
ResultsPanel.viewFileInDir.name=View File in Directory
|
||||||
|
VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show
|
||||||
|
DataSourceFilterPanel.dataSourceCheckbox.text=Data Source:
|
||||||
|
ParentFolderFilterPanel.parentLabel.text_1=(All will be used)
|
||||||
|
ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder:
|
||||||
|
ParentFolderFilterPanel.addButton.text_1=Add
|
||||||
|
ParentFolderFilterPanel.deleteButton.text_1=Delete
|
||||||
|
ParentFolderFilterPanel.excludeRadioButton.text_1=Exclude
|
||||||
|
ParentFolderFilterPanel.substringRadioButton.text_1=Substring
|
||||||
|
ParentFolderFilterPanel.includeRadioButton.text_1=Include
|
||||||
|
ParentFolderFilterPanel.fullRadioButton.text_1=Full
|
||||||
|
UserCreatedFilterPanel.userCreatedCheckbox.text_1=Possibly User Created
|
||||||
|
GroupListPanel.groupKeyList.border.title=Groups
|
||||||
|
ResultsSplitPaneDivider.detailsLabel.text=Details Area
|
||||||
|
ResultsSplitPaneDivider.showButton.text=
|
||||||
|
ResultsSplitPaneDivider.hideButton.text=
|
||||||
|
ImageFilterPanel.imageFiltersSplitPane.toolTipText=
|
||||||
|
ImageFilterPanel.imageFiltersSplitPane.border.title=Step 2: Filter which images to show
|
||||||
|
ArtifactTypeFilterPanel.artifactTypeCheckbox.text=Artifact Type:
|
||||||
|
InterestingItemsFilterPanel.interestingItemsCheckbox.text=Interesting Item:
|
||||||
|
DocumentPanel.fileSizeLabel.toolTipText=
|
||||||
|
DocumentPanel.isDeletedLabel.toolTipText=
|
||||||
|
DomainFilterPanel.domainFiltersSplitPane.toolTipText=
|
||||||
|
DomainFilterPanel.domainFiltersSplitPane.border.title=Step 2: Filter which domains to show
|
||||||
|
SizeFilterPanel.sizeCheckbox.text=File Size:
|
||||||
|
DateFilterPanel.dateFilterCheckbox.text=Date Filter:
|
||||||
|
DateFilterPanel.endCheckBox.text=End:
|
||||||
|
DateFilterPanel.startCheckBox.text=Start:
|
||||||
|
DateFilterPanel.mostRecentButton.text=Only last:
|
||||||
|
DateFilterPanel.daysLabel.text=days of activity
|
||||||
|
ImageThumbnailPanel.isDeletedLabel.toolTipText=
|
||||||
|
ResultsPanel.pageControlsLabel.text=Pages:
|
||||||
|
ResultsPanel.currentPageLabel.text=Page: -
|
||||||
|
ResultsPanel.pageSizeLabel.text=Page Size:
|
||||||
|
ResultsPanel.gotoPageLabel.text=Go to Page:
|
||||||
|
# To change this license header, choose License Headers in Project Properties.
|
||||||
|
# To change this template file, choose Tools | Templates
|
||||||
|
# and open the template in the editor.
|
||||||
|
HashSetFilterPanel.hashSetCheckbox.text=Hash Set:
|
||||||
|
PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text=Past Occurrences:
|
||||||
|
DocumentFilterPanel.documentsFiltersSplitPane.border.title=Step 2: Filter which documents to show
|
||||||
|
ObjectDetectedFilterPanel.text=Object Detected:
|
||||||
|
DetailsPanel.instancesList.border.title=Instances
|
||||||
|
VideoThumbnailPanel.bytes.text=bytes
|
||||||
|
VideoThumbnailPanel.deleted.text=All instances of file are deleted.
|
||||||
|
VideoThumbnailPanel.gigaBytes.text=GB
|
||||||
|
VideoThumbnailPanel.kiloBytes.text=KB
|
||||||
|
VideoThumbnailPanel.megaBytes.text=MB
|
||||||
|
# {0} - otherInstanceCount
|
||||||
|
VideoThumbnailPanel.nameLabel.more.text=\ and {0} more
|
||||||
|
# {0} - fileSize
|
||||||
|
# {1} - units
|
||||||
|
VideoThumbnailPanel.sizeLabel.text=Size: {0} {1}
|
||||||
|
VideoThumbnailPanel.terraBytes.text=TB
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="dataSourceCheckbox">
|
<Component class="javax.swing.JCheckBox" name="dataSourceCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DataSourceFilterPanel.dataSourceCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DataSourceFilterPanel.dataSourceCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -27,6 +28,7 @@ import javax.swing.JLabel;
|
|||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory;
|
@ -7,7 +7,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="dateFilterCheckbox">
|
<Component class="javax.swing.JCheckBox" name="dateFilterCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DateFilterPanel.dateFilterCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DateFilterPanel.dateFilterCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
@ -112,7 +112,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="daysLabel">
|
<Component class="javax.swing.JLabel" name="daysLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DateFilterPanel.daysLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DateFilterPanel.daysLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -123,7 +123,7 @@
|
|||||||
<ComponentRef name="buttonGroup1"/>
|
<ComponentRef name="buttonGroup1"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DateFilterPanel.mostRecentButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DateFilterPanel.mostRecentButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -134,7 +134,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="startCheckBox">
|
<Component class="javax.swing.JCheckBox" name="startCheckBox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DateFilterPanel.startCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DateFilterPanel.startCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -167,7 +167,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="endCheckBox">
|
<Component class="javax.swing.JCheckBox" name="endCheckBox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DateFilterPanel.endCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DateFilterPanel.endCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
@ -106,7 +106,7 @@
|
|||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Instances">
|
<TitledBorder title="Instances">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DetailsPanel.instancesList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DetailsPanel.instancesList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
@ -39,6 +39,7 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
|||||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||||
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||||
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction;
|
import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
@ -94,7 +94,7 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/pictures-icon.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/pictures-icon.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.imagesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.imagesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/pictures-icon.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/pictures-icon.png"/>
|
||||||
@ -121,7 +121,7 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.videosButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.videosButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/video-icon.png"/>
|
||||||
@ -151,7 +151,7 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.documentsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.documentsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/documents-icon.png"/>
|
||||||
@ -168,7 +168,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="step1Label">
|
<Component class="javax.swing.JLabel" name="step1Label">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.step1Label.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.step1Label.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -200,7 +200,7 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/domain-32.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/domain-32.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.domainsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.domainsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="disabledIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/domain-32.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/domain-32.png"/>
|
||||||
@ -263,7 +263,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="searchButton">
|
<Component class="javax.swing.JButton" name="searchButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.searchButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
@ -282,7 +282,7 @@
|
|||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Step 3: Choose display settings">
|
<TitledBorder title="Step 3: Choose display settings">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.sortingPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.sortingPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
||||||
@ -361,7 +361,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="orderGroupsByLabel">
|
<Component class="javax.swing.JLabel" name="orderGroupsByLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.orderGroupsByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.orderGroupsByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -372,7 +372,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="orderByLabel">
|
<Component class="javax.swing.JLabel" name="orderByLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.orderByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.orderByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -383,7 +383,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="groupByLabel">
|
<Component class="javax.swing.JLabel" name="groupByLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DiscoveryDialog.groupByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DiscoveryDialog.groupByLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import static java.awt.BorderLayout.CENTER;
|
import static java.awt.BorderLayout.CENTER;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
@ -36,17 +37,24 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm;
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType;
|
import org.sleuthkit.autopsy.discovery.search.FileGroup;
|
||||||
import static org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType.PARENT_PATH;
|
import org.sleuthkit.autopsy.discovery.search.FileGroup.GroupSortingAlgorithm;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod;
|
import static org.sleuthkit.autopsy.discovery.search.FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearch;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearch.GroupingAttributeType;
|
||||||
|
import static org.sleuthkit.autopsy.discovery.search.FileSearch.GroupingAttributeType.PARENT_PATH;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSorter.SortingMethod;
|
||||||
|
import static org.sleuthkit.autopsy.discovery.search.FileSorter.SortingMethod.BY_FILE_NAME;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import static org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod.BY_FILE_NAME;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for displaying the controls and filters for configuration of a
|
* Dialog for displaying the controls and filters for configuration of a
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.directorytree.actionhelpers.ExtractActionHelper;
|
import org.sleuthkit.autopsy.directorytree.actionhelpers.ExtractActionHelper;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
@ -105,8 +105,8 @@
|
|||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JButton" name="newSearchButton">
|
<Component class="javax.swing.JButton" name="newSearchButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="FileSearchDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<Connection code="Bundle.DiscoveryTopComponent_cancelButton_text()" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[110, 26]"/>
|
<Dimension value="[110, 26]"/>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
@ -36,19 +37,20 @@ import org.openide.windows.RetainLocation;
|
|||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.discovery.SearchData.ResultType;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a dialog for displaying the Discovery results.
|
* Create a dialog for displaying the Discovery results.
|
||||||
*/
|
*/
|
||||||
@TopComponent.Description(preferredID = "Discovery", persistenceType = TopComponent.PERSISTENCE_NEVER)
|
@TopComponent.Description(preferredID = "DiscoveryTc", persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||||
@TopComponent.Registration(mode = "discovery", openAtStartup = false)
|
@TopComponent.Registration(mode = "discovery", openAtStartup = false)
|
||||||
@RetainLocation("discovery")
|
@RetainLocation("discovery")
|
||||||
@NbBundle.Messages("DiscoveryTopComponent.name= Discovery")
|
@NbBundle.Messages("DiscoveryTopComponent.name= Discovery")
|
||||||
public final class DiscoveryTopComponent extends TopComponent {
|
public final class DiscoveryTopComponent extends TopComponent {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final String PREFERRED_ID = "Discovery"; // NON-NLS
|
private static final String PREFERRED_ID = "DiscoveryTc"; // NON-NLS
|
||||||
private static final int ANIMATION_INCREMENT = 30;
|
private static final int ANIMATION_INCREMENT = 30;
|
||||||
private volatile static int resultsAreaSize = 250;
|
private volatile static int resultsAreaSize = 250;
|
||||||
private final GroupListPanel groupListPanel;
|
private final GroupListPanel groupListPanel;
|
||||||
@ -182,7 +184,7 @@ public final class DiscoveryTopComponent extends TopComponent {
|
|||||||
|
|
||||||
add(mainSplitPane, java.awt.BorderLayout.CENTER);
|
add(mainSplitPane, java.awt.BorderLayout.CENTER);
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(newSearchButton, org.openide.util.NbBundle.getMessage(DiscoveryTopComponent.class, "FileSearchDialog.cancelButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(newSearchButton, Bundle.DiscoveryTopComponent_cancelButton_text());
|
||||||
newSearchButton.setMaximumSize(new java.awt.Dimension(110, 26));
|
newSearchButton.setMaximumSize(new java.awt.Dimension(110, 26));
|
||||||
newSearchButton.setMinimumSize(new java.awt.Dimension(110, 26));
|
newSearchButton.setMinimumSize(new java.awt.Dimension(110, 26));
|
||||||
newSearchButton.setPreferredSize(new java.awt.Dimension(110, 26));
|
newSearchButton.setPreferredSize(new java.awt.Dimension(110, 26));
|
@ -0,0 +1,541 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy
|
||||||
|
*
|
||||||
|
* Copyright 2020 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.discovery.ui;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextPane;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.imgscalr.Scalr;
|
||||||
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.highgui.VideoCapture;
|
||||||
|
import org.openide.util.ImageUtilities;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.corelibs.ScalrWrapper;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import static org.sleuthkit.autopsy.coreutils.VideoUtils.getVideoFileInTempDir;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for the various user interface elements used by Discovery.
|
||||||
|
*/
|
||||||
|
final class DiscoveryUiUtils {
|
||||||
|
|
||||||
|
private final static Logger logger = Logger.getLogger(DiscoveryUiUtils.class.getName());
|
||||||
|
private static final int BYTE_UNIT_CONVERSION = 1000;
|
||||||
|
private static final int ICON_SIZE = 16;
|
||||||
|
private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png";
|
||||||
|
private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png";
|
||||||
|
private static final String DELETE_ICON_PATH = "org/sleuthkit/autopsy/images/file-icon-deleted.png";
|
||||||
|
private static final String UNSUPPORTED_DOC_PATH = "org/sleuthkit/autopsy/images/image-extraction-not-supported.png";
|
||||||
|
private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false));
|
||||||
|
private static final ImageIcon NOTABLE_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false));
|
||||||
|
private static final ImageIcon DELETED_ICON = new ImageIcon(ImageUtilities.loadImage(DELETE_ICON_PATH, false));
|
||||||
|
private static final ImageIcon UNSUPPORTED_DOCUMENT_THUMBNAIL = new ImageIcon(ImageUtilities.loadImage(UNSUPPORTED_DOC_PATH, false));
|
||||||
|
private static final String THUMBNAIL_FORMAT = "png"; //NON-NLS
|
||||||
|
private static final String VIDEO_THUMBNAIL_DIR = "video-thumbnails"; //NON-NLS
|
||||||
|
private static final BufferedImage VIDEO_DEFAULT_IMAGE = getDefaultVideoThumbnail();
|
||||||
|
|
||||||
|
@NbBundle.Messages({"# {0} - fileSize",
|
||||||
|
"# {1} - units",
|
||||||
|
"DiscoveryUiUtility.sizeLabel.text=Size: {0} {1}",
|
||||||
|
"DiscoveryUiUtility.bytes.text=bytes",
|
||||||
|
"DiscoveryUiUtility.kiloBytes.text=KB",
|
||||||
|
"DiscoveryUiUtility.megaBytes.text=MB",
|
||||||
|
"DiscoveryUiUtility.gigaBytes.text=GB",
|
||||||
|
"DiscoveryUiUtility.terraBytes.text=TB"})
|
||||||
|
/**
|
||||||
|
* Convert a size in bytes to a string with representing the size in the
|
||||||
|
* largest units which represent the value as being greater than or equal to
|
||||||
|
* one. Result will be rounded down to the nearest whole number of those
|
||||||
|
* units.
|
||||||
|
*
|
||||||
|
* @param bytes Size in bytes.
|
||||||
|
*/
|
||||||
|
static String getFileSizeString(long bytes) {
|
||||||
|
long size = bytes;
|
||||||
|
int unitsSwitchValue = 0;
|
||||||
|
while (size > BYTE_UNIT_CONVERSION && unitsSwitchValue < 4) {
|
||||||
|
size /= BYTE_UNIT_CONVERSION;
|
||||||
|
unitsSwitchValue++;
|
||||||
|
}
|
||||||
|
String units;
|
||||||
|
switch (unitsSwitchValue) {
|
||||||
|
case 1:
|
||||||
|
units = Bundle.DiscoveryUiUtility_kiloBytes_text();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
units = Bundle.DiscoveryUiUtility_megaBytes_text();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
units = Bundle.DiscoveryUiUtility_gigaBytes_text();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
units = Bundle.DiscoveryUiUtility_terraBytes_text();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
units = Bundle.DiscoveryUiUtility_bytes_text();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Bundle.DiscoveryUiUtility_sizeLabel_text(size, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the image to use when the document type does not support image
|
||||||
|
* extraction.
|
||||||
|
*
|
||||||
|
* @return An image that indicates we don't know if there are images.
|
||||||
|
*/
|
||||||
|
static ImageIcon getUnsupportedImageThumbnail() {
|
||||||
|
return UNSUPPORTED_DOCUMENT_THUMBNAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the names of the sets which exist in the case database for the
|
||||||
|
* specified artifact and attribute types.
|
||||||
|
*
|
||||||
|
* @param artifactType The artifact type to get the list of sets for.
|
||||||
|
* @param setNameAttribute The attribute type which contains the set names.
|
||||||
|
*
|
||||||
|
* @return A list of set names which exist in the case for the specified
|
||||||
|
* artifact and attribute types.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
static List<String> getSetNames(BlackboardArtifact.ARTIFACT_TYPE artifactType, BlackboardAttribute.ATTRIBUTE_TYPE setNameAttribute) throws TskCoreException {
|
||||||
|
List<BlackboardArtifact> arts = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(artifactType);
|
||||||
|
List<String> setNames = new ArrayList<>();
|
||||||
|
for (BlackboardArtifact art : arts) {
|
||||||
|
for (BlackboardAttribute attr : art.getAttributes()) {
|
||||||
|
if (attr.getAttributeType().getTypeID() == setNameAttribute.getTypeID()) {
|
||||||
|
String setName = attr.getValueString();
|
||||||
|
if (!setNames.contains(setName)) {
|
||||||
|
setNames.add(setName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(setNames);
|
||||||
|
return setNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to see if point is on the icon.
|
||||||
|
*
|
||||||
|
* @param comp The component to check if the cursor is over the icon of
|
||||||
|
* @param point The point the cursor is at.
|
||||||
|
*
|
||||||
|
* @return True if the point is over the icon, false otherwise.
|
||||||
|
*/
|
||||||
|
static boolean isPointOnIcon(Component comp, Point point) {
|
||||||
|
return comp instanceof JComponent && point.x >= comp.getX() && point.x <= comp.getX() + ICON_SIZE && point.y >= comp.getY() && point.y <= comp.getY() + ICON_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set the icon and tool tip text for a label to show deleted
|
||||||
|
* status.
|
||||||
|
*
|
||||||
|
* @param isDeleted True if the label should reflect deleted status,
|
||||||
|
* false otherwise.
|
||||||
|
* @param isDeletedLabel The label to set the icon and tooltip for.
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({"DiscoveryUiUtils.isDeleted.text=All instances of file are deleted."})
|
||||||
|
static void setDeletedIcon(boolean isDeleted, javax.swing.JLabel isDeletedLabel) {
|
||||||
|
if (isDeleted) {
|
||||||
|
isDeletedLabel.setIcon(DELETED_ICON);
|
||||||
|
isDeletedLabel.setToolTipText(Bundle.DiscoveryUiUtils_isDeleted_text());
|
||||||
|
} else {
|
||||||
|
isDeletedLabel.setIcon(null);
|
||||||
|
isDeletedLabel.setToolTipText(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set the icon and tool tip text for a label to show the score.
|
||||||
|
*
|
||||||
|
* @param resultFile The result file which the label should reflect the
|
||||||
|
* score of.
|
||||||
|
* @param scoreLabel The label to set the icon and tooltip for.
|
||||||
|
*/
|
||||||
|
static void setScoreIcon(ResultFile resultFile, javax.swing.JLabel scoreLabel) {
|
||||||
|
switch (resultFile.getScore()) {
|
||||||
|
case NOTABLE_SCORE:
|
||||||
|
scoreLabel.setIcon(NOTABLE_SCORE_ICON);
|
||||||
|
break;
|
||||||
|
case INTERESTING_SCORE:
|
||||||
|
scoreLabel.setIcon(INTERESTING_SCORE_ICON);
|
||||||
|
break;
|
||||||
|
case NO_SCORE: // empty case - this is interpreted as an intentional fall-through
|
||||||
|
default:
|
||||||
|
scoreLabel.setIcon(null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
scoreLabel.setToolTipText(resultFile.getScoreDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of the icons used by the UI.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static int getIconSize() {
|
||||||
|
return ICON_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to display an error message when the results of the
|
||||||
|
* Discovery Top component may be incomplete.
|
||||||
|
*/
|
||||||
|
static void displayErrorMessage(DiscoveryDialog dialog) {
|
||||||
|
//check if modules run and assemble message
|
||||||
|
try {
|
||||||
|
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
Map<Long, DataSourceModulesWrapper> dataSourceIngestModules = new HashMap<>();
|
||||||
|
for (DataSource dataSource : skCase.getDataSources()) {
|
||||||
|
dataSourceIngestModules.put(dataSource.getId(), new DataSourceModulesWrapper(dataSource.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IngestJobInfo jobInfo : skCase.getIngestJobs()) {
|
||||||
|
dataSourceIngestModules.get(jobInfo.getObjectId()).updateModulesRun(jobInfo);
|
||||||
|
}
|
||||||
|
String message = "";
|
||||||
|
for (DataSourceModulesWrapper dsmodulesWrapper : dataSourceIngestModules.values()) {
|
||||||
|
message += dsmodulesWrapper.getMessage();
|
||||||
|
}
|
||||||
|
if (!message.isEmpty()) {
|
||||||
|
JScrollPane messageScrollPane = new JScrollPane();
|
||||||
|
JTextPane messageTextPane = new JTextPane();
|
||||||
|
messageTextPane.setText(message);
|
||||||
|
messageTextPane.setVisible(true);
|
||||||
|
messageTextPane.setEditable(false);
|
||||||
|
messageTextPane.setCaretPosition(0);
|
||||||
|
messageScrollPane.setMaximumSize(new Dimension(600, 100));
|
||||||
|
messageScrollPane.setPreferredSize(new Dimension(600, 100));
|
||||||
|
messageScrollPane.setViewportView(messageTextPane);
|
||||||
|
JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE);
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex);
|
||||||
|
}
|
||||||
|
dialog.validateDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the video thumbnails for a file which exists in a
|
||||||
|
* VideoThumbnailsWrapper and update the VideoThumbnailsWrapper to include
|
||||||
|
* them.
|
||||||
|
*
|
||||||
|
* @param thumbnailWrapper the object which contains the file to generate
|
||||||
|
* thumbnails for.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({"# {0} - file name",
|
||||||
|
"DiscoveryUiUtils.genVideoThumb.progress.text=extracting temporary file {0}"})
|
||||||
|
static void getVideoThumbnails(VideoThumbnailsWrapper thumbnailWrapper) {
|
||||||
|
AbstractFile file = thumbnailWrapper.getResultFile().getFirstInstance();
|
||||||
|
String cacheDirectory;
|
||||||
|
try {
|
||||||
|
cacheDirectory = Case.getCurrentCaseThrows().getCacheDirectory();
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
cacheDirectory = null;
|
||||||
|
logger.log(Level.WARNING, "Unable to get cache directory, video thumbnails will not be saved", ex);
|
||||||
|
}
|
||||||
|
if (cacheDirectory == null || file.getMd5Hash() == null || !Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash()).toFile().exists()) {
|
||||||
|
java.io.File tempFile;
|
||||||
|
try {
|
||||||
|
tempFile = getVideoFileInTempDir(file);
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
logger.log(Level.WARNING, "Exception while getting open case.", ex); //NON-NLS
|
||||||
|
int[] framePositions = new int[]{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0};
|
||||||
|
thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tempFile.exists() == false || tempFile.length() < file.getSize()) {
|
||||||
|
ProgressHandle progress = ProgressHandle.createHandle(Bundle.DiscoveryUiUtils_genVideoThumb_progress_text(file.getName()));
|
||||||
|
progress.start(100);
|
||||||
|
try {
|
||||||
|
Files.createParentDirs(tempFile);
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
int[] framePositions = new int[]{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0};
|
||||||
|
thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ContentUtils.writeToFile(file, tempFile, progress, null, true);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error extracting temporary file for " + file.getParentPath() + "/" + file.getName(), ex); //NON-NLS
|
||||||
|
} finally {
|
||||||
|
progress.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VideoCapture videoFile = new VideoCapture(); // will contain the video
|
||||||
|
BufferedImage bufferedImage = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!videoFile.open(tempFile.toString())) {
|
||||||
|
logger.log(Level.WARNING, "Error opening {0} for preview generation.", file.getParentPath() + "/" + file.getName()); //NON-NLS
|
||||||
|
int[] framePositions = new int[]{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0};
|
||||||
|
thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
double fps = videoFile.get(5); // gets frame per second
|
||||||
|
double totalFrames = videoFile.get(7); // gets total frames
|
||||||
|
if (fps <= 0 || totalFrames <= 0) {
|
||||||
|
logger.log(Level.WARNING, "Error getting fps or total frames for {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS
|
||||||
|
int[] framePositions = new int[]{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0};
|
||||||
|
thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
int[] framePositions = new int[]{
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0};
|
||||||
|
thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double duration = 1000 * (totalFrames / fps); //total milliseconds
|
||||||
|
|
||||||
|
int[] framePositions = new int[]{
|
||||||
|
(int) (duration * .01),
|
||||||
|
(int) (duration * .25),
|
||||||
|
(int) (duration * .5),
|
||||||
|
(int) (duration * .75),};
|
||||||
|
|
||||||
|
Mat imageMatrix = new Mat();
|
||||||
|
List<Image> videoThumbnails = new ArrayList<>();
|
||||||
|
if (cacheDirectory == null || file.getMd5Hash() == null) {
|
||||||
|
cacheDirectory = null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
FileUtils.forceMkdir(Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash()).toFile());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
cacheDirectory = null;
|
||||||
|
logger.log(Level.WARNING, "Unable to make video thumbnails directory, thumbnails will not be saved", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < framePositions.length; i++) {
|
||||||
|
if (!videoFile.set(0, framePositions[i])) {
|
||||||
|
logger.log(Level.WARNING, "Error seeking to " + framePositions[i] + "ms in {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS
|
||||||
|
// If we can't set the time, continue to the next frame position and try again.
|
||||||
|
|
||||||
|
videoThumbnails.add(VIDEO_DEFAULT_IMAGE);
|
||||||
|
if (cacheDirectory != null) {
|
||||||
|
try {
|
||||||
|
ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT,
|
||||||
|
Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS)
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Read the frame into the image/matrix.
|
||||||
|
if (!videoFile.read(imageMatrix)) {
|
||||||
|
logger.log(Level.WARNING, "Error reading frame at " + framePositions[i] + "ms from {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS
|
||||||
|
// If the image is bad for some reason, continue to the next frame position and try again.
|
||||||
|
videoThumbnails.add(VIDEO_DEFAULT_IMAGE);
|
||||||
|
if (cacheDirectory != null) {
|
||||||
|
try {
|
||||||
|
ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT,
|
||||||
|
Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS)
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If the image is empty, return since no buffered image can be created.
|
||||||
|
if (imageMatrix.empty()) {
|
||||||
|
videoThumbnails.add(VIDEO_DEFAULT_IMAGE);
|
||||||
|
if (cacheDirectory != null) {
|
||||||
|
try {
|
||||||
|
ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT,
|
||||||
|
Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS)
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int matrixColumns = imageMatrix.cols();
|
||||||
|
int matrixRows = imageMatrix.rows();
|
||||||
|
|
||||||
|
// Convert the matrix that contains the frame to a buffered image.
|
||||||
|
if (bufferedImage == null) {
|
||||||
|
bufferedImage = new BufferedImage(matrixColumns, matrixRows, BufferedImage.TYPE_3BYTE_BGR);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] data = new byte[matrixRows * matrixColumns * (int) (imageMatrix.elemSize())];
|
||||||
|
imageMatrix.get(0, 0, data); //copy the image to data
|
||||||
|
|
||||||
|
if (imageMatrix.channels() == 3) {
|
||||||
|
for (int k = 0; k < data.length; k += 3) {
|
||||||
|
byte temp = data[k];
|
||||||
|
data[k] = data[k + 2];
|
||||||
|
data[k + 2] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferedImage.getRaster().setDataElements(0, 0, matrixColumns, matrixRows, data);
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
thumbnailWrapper.setThumbnails(videoThumbnails, framePositions);
|
||||||
|
try {
|
||||||
|
FileUtils.forceDelete(Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash()).toFile());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to delete directory for cancelled video thumbnail process", ex);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BufferedImage thumbnail = ScalrWrapper.resize(bufferedImage, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_HEIGHT, ImageUtils.ICON_SIZE_LARGE, ImageUtils.ICON_SIZE_MEDIUM, Scalr.OP_ANTIALIAS);
|
||||||
|
//We are height limited here so it can be wider than it can be tall.Scalr maintains the aspect ratio.
|
||||||
|
videoThumbnails.add(thumbnail);
|
||||||
|
if (cacheDirectory != null) {
|
||||||
|
try {
|
||||||
|
ImageIO.write(thumbnail, THUMBNAIL_FORMAT,
|
||||||
|
Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS)
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to save video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thumbnailWrapper.setThumbnails(videoThumbnails, framePositions);
|
||||||
|
} finally {
|
||||||
|
videoFile.release(); // close the file}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadSavedThumbnails(cacheDirectory, thumbnailWrapper, VIDEO_DEFAULT_IMAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default image to display when a thumbnail is not available.
|
||||||
|
*
|
||||||
|
* @return The default video thumbnail.
|
||||||
|
*/
|
||||||
|
private static BufferedImage getDefaultVideoThumbnail() {
|
||||||
|
try {
|
||||||
|
return ImageIO.read(ImageUtils.class
|
||||||
|
.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to load 'failed to create video' placeholder.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the thumbnails that exist in the cache directory for the specified
|
||||||
|
* video file.
|
||||||
|
*
|
||||||
|
* @param cacheDirectory The directory which exists for the video
|
||||||
|
* thumbnails.
|
||||||
|
* @param thumbnailWrapper The VideoThumbnailWrapper object which contains
|
||||||
|
* information about the file and the thumbnails
|
||||||
|
* associated with it.
|
||||||
|
*/
|
||||||
|
private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper, BufferedImage failedVideoThumbImage) {
|
||||||
|
int[] framePositions = new int[4];
|
||||||
|
List<Image> videoThumbnails = new ArrayList<>();
|
||||||
|
int thumbnailNumber = 0;
|
||||||
|
String md5 = thumbnailWrapper.getResultFile().getFirstInstance().getMd5Hash();
|
||||||
|
for (String fileName : Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, md5).toFile().list()) {
|
||||||
|
try {
|
||||||
|
videoThumbnails.add(ImageIO.read(Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, md5, fileName).toFile()));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
videoThumbnails.add(failedVideoThumbImage);
|
||||||
|
logger.log(Level.WARNING, "Unable to read saved video thumbnail " + fileName + " for " + md5, ex);
|
||||||
|
}
|
||||||
|
int framePos = Integer.valueOf(FilenameUtils.getBaseName(fileName).substring(2));
|
||||||
|
framePositions[thumbnailNumber] = framePos;
|
||||||
|
thumbnailNumber++;
|
||||||
|
}
|
||||||
|
thumbnailWrapper.setThumbnails(videoThumbnails, framePositions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private helper method for creating video thumbnails, for use when no
|
||||||
|
* thumbnails are created.
|
||||||
|
*
|
||||||
|
* @return List containing the default thumbnail.
|
||||||
|
*/
|
||||||
|
private static List<Image> createDefaultThumbnailList(BufferedImage failedVideoThumbImage) {
|
||||||
|
List<Image> videoThumbnails = new ArrayList<>();
|
||||||
|
videoThumbnails.add(failedVideoThumbImage);
|
||||||
|
videoThumbnails.add(failedVideoThumbImage);
|
||||||
|
videoThumbnails.add(failedVideoThumbImage);
|
||||||
|
videoThumbnails.add(failedVideoThumbImage);
|
||||||
|
return videoThumbnails;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor for DiscoveryUiUtils utility class.
|
||||||
|
*/
|
||||||
|
private DiscoveryUiUtils() {
|
||||||
|
//private constructor in a utility class intentionally left blank
|
||||||
|
}
|
||||||
|
}
|
@ -58,14 +58,14 @@
|
|||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Container class="javax.swing.JSplitPane" name="documentsFiltersSplitPane">
|
<Container class="javax.swing.JSplitPane" name="documentsFiltersSplitPane">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Step 2: Filter which documents to show">
|
<TitledBorder title="Step 2: Filter which documents to show">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DocumentFilterPanel.documentsFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DocumentFilterPanel.documentsFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
@ -16,9 +16,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which displays all filters available for the Documents search type.
|
* Class which displays all filters available for the Documents search type.
|
@ -80,16 +80,16 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DocumentPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DocumentPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
@ -100,20 +100,20 @@
|
|||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="fileSizeLabel">
|
<Component class="javax.swing.JLabel" name="fileSizeLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DocumentPanel.fileSizeLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DocumentPanel.fileSizeLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
@ -29,6 +29,7 @@ import javax.swing.JList;
|
|||||||
import javax.swing.ListCellRenderer;
|
import javax.swing.ListCellRenderer;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane;
|
import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which displays a preview and details about a document.
|
* Class which displays a preview and details about a document.
|
||||||
@ -67,15 +68,15 @@ class DocumentPanel extends javax.swing.JPanel implements ListCellRenderer<Docum
|
|||||||
|
|
||||||
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
||||||
isDeletedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.isDeletedLabel.toolTipText")); // NOI18N
|
isDeletedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.isDeletedLabel.toolTipText")); // NOI18N
|
||||||
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
|
|
||||||
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
||||||
scoreLabel.setToolTipText("");
|
scoreLabel.setToolTipText("");
|
||||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
|
|
||||||
fileSizeLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.fileSizeLabel.toolTipText")); // NOI18N
|
fileSizeLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.fileSizeLabel.toolTipText")); // NOI18N
|
||||||
|
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
@ -16,9 +16,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
||||||
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||||
|
|
||||||
/**
|
/**
|
@ -66,13 +66,13 @@
|
|||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Step 2: Filter which domains to show">
|
<TitledBorder title="Step 2: Filter which domains to show">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DomainFilterPanel.domainFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DomainFilterPanel.domainFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="DomainFilterPanel.domainFiltersSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DomainFilterPanel.domainFiltersSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
@ -16,9 +16,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter panel for searching domain attributes with Discovery.
|
* Filter panel for searching domain attributes with Discovery.
|
@ -46,7 +46,7 @@
|
|||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Groups">
|
<TitledBorder title="Groups">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="GroupListPanel.groupKeyList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="GroupListPanel.groupKeyList.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -28,8 +29,12 @@ import javax.swing.JList;
|
|||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileType;
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileGroup;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearch;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to display the list of groups which are provided by a search.
|
* Panel to display the list of groups which are provided by a search.
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="hashSetCheckbox">
|
<Component class="javax.swing.JCheckBox" name="hashSetCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="HashSetFilterPanel.hashSetCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="HashSetFilterPanel.hashSetCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
@ -25,6 +26,7 @@ import javax.swing.JCheckBox;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
@ -61,13 +61,13 @@
|
|||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Step 2: Filter which images to show">
|
<TitledBorder title="Step 2: Filter which images to show">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ImageFilterPanel.imageFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ImageFilterPanel.imageFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ImageFilterPanel.imageFiltersSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ImageFilterPanel.imageFiltersSplitPane.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
@ -16,9 +16,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel for displaying all the filters associated with the Image type.
|
* Panel for displaying all the filters associated with the Image type.
|
@ -102,16 +102,16 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ImageThumbnailPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ImageThumbnailPanel.isDeletedLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
@ -122,13 +122,13 @@
|
|||||||
</Property>
|
</Property>
|
||||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
@ -76,15 +76,15 @@ final class ImageThumbnailPanel extends javax.swing.JPanel implements ListCellRe
|
|||||||
|
|
||||||
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
isDeletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
||||||
isDeletedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ImageThumbnailPanel.class, "ImageThumbnailPanel.isDeletedLabel.toolTipText")); // NOI18N
|
isDeletedLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ImageThumbnailPanel.class, "ImageThumbnailPanel.isDeletedLabel.toolTipText")); // NOI18N
|
||||||
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
isDeletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
isDeletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
isDeletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
|
|
||||||
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
||||||
scoreLabel.setToolTipText("");
|
scoreLabel.setToolTipText("");
|
||||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
@ -16,10 +16,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to wrap all the information necessary for an image thumbnail to be
|
* Class to wrap all the information necessary for an image thumbnail to be
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="interestingItemsCheckbox">
|
<Component class="javax.swing.JCheckBox" name="interestingItemsCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="InterestingItemsFilterPanel.interestingItemsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="InterestingItemsFilterPanel.interestingItemsCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
@ -25,6 +26,7 @@ import javax.swing.JCheckBox;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
@ -25,6 +26,7 @@ import javax.swing.JCheckBox;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
@ -16,16 +16,24 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileGroup;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearch;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchException;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SwingWorker to retrieve the contents of a page.
|
* SwingWorker to retrieve the contents of a page.
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="parentCheckbox">
|
<Component class="javax.swing.JCheckBox" name="parentCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.parentCheckbox.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.parentCheckbox.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="parentLabel">
|
<Component class="javax.swing.JLabel" name="parentLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.parentLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.parentLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
||||||
@ -160,7 +160,7 @@
|
|||||||
</Property>
|
</Property>
|
||||||
<Property name="selected" type="boolean" value="true"/>
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.fullRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.fullRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -172,7 +172,7 @@
|
|||||||
</Property>
|
</Property>
|
||||||
<Property name="selected" type="boolean" value="true"/>
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.includeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.includeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -183,7 +183,7 @@
|
|||||||
<ComponentRef name="pathTypeButtonGroup"/>
|
<ComponentRef name="pathTypeButtonGroup"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.substringRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.substringRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -194,7 +194,7 @@
|
|||||||
<ComponentRef name="includeButtonGroup"/>
|
<ComponentRef name="includeButtonGroup"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.excludeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.excludeRadioButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -202,7 +202,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="deleteButton">
|
<Component class="javax.swing.JButton" name="deleteButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.deleteButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.deleteButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
@ -222,7 +222,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="addButton">
|
<Component class="javax.swing.JButton" name="addButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ParentFolderFilterPanel.addButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ParentFolderFilterPanel.addButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
@ -16,15 +16,17 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.discovery.SearchFiltering.ParentSearchTerm;
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering.ParentSearchTerm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to allow configuration of the Parent Folder filter.
|
* Panel to allow configuration of the Parent Folder filter.
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="pastOccurrencesCheckbox">
|
<Component class="javax.swing.JCheckBox" name="pastOccurrencesCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
@ -16,15 +16,18 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency;
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import org.sleuthkit.autopsy.discovery.SearchData.ResultType;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.Frequency;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to allow configuration of the Past Occurrences filter.
|
* Panel to allow configuration of the Past Occurrences filter.
|
@ -79,7 +79,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="currentPageLabel">
|
<Component class="javax.swing.JLabel" name="currentPageLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsPanel.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[190, 23]"/>
|
<Dimension value="[190, 23]"/>
|
||||||
@ -127,7 +127,7 @@
|
|||||||
<Properties>
|
<Properties>
|
||||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.pageControlsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsPanel.pageControlsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[133, 23]"/>
|
<Dimension value="[133, 23]"/>
|
||||||
@ -153,7 +153,7 @@
|
|||||||
<Properties>
|
<Properties>
|
||||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.gotoPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsPanel.gotoPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[170, 23]"/>
|
<Dimension value="[170, 23]"/>
|
||||||
@ -199,7 +199,7 @@
|
|||||||
<Properties>
|
<Properties>
|
||||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsPanel.pageSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsPanel.pageSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[160, 23]"/>
|
<Dimension value="[160, 23]"/>
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
@ -35,9 +36,15 @@ import org.openide.util.NbBundle.Messages;
|
|||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileGroup;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearch;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
||||||
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
import org.sleuthkit.autopsy.textsummarizer.TextSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -646,7 +653,7 @@ final class ResultsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground() throws Exception {
|
protected Void doInBackground() throws Exception {
|
||||||
FileSearch.getVideoThumbnails(thumbnailWrapper);
|
DiscoveryUiUtils.getVideoThumbnails(thumbnailWrapper);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +24,7 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="detailsLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="detailsLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="251" max="32767" attributes="0"/>
|
<EmptySpace pref="199" max="32767" attributes="0"/>
|
||||||
<Component id="showButton" min="-2" max="-2" attributes="0"/>
|
<Component id="showButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="hideButton" min="-2" max="-2" attributes="0"/>
|
<Component id="hideButton" min="-2" max="-2" attributes="0"/>
|
||||||
@ -54,7 +54,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="detailsLabel">
|
<Component class="javax.swing.JLabel" name="detailsLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsSplitPaneDivider.detailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsSplitPaneDivider.detailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="focusable" type="boolean" value="false"/>
|
<Property name="focusable" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -66,10 +66,10 @@
|
|||||||
<Component class="javax.swing.JButton" name="hideButton">
|
<Component class="javax.swing.JButton" name="hideButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/discovery/arrow-down.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/discovery/ui/arrow-down.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsSplitPaneDivider.hideButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsSplitPaneDivider.hideButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="null"/>
|
<Border info="null"/>
|
||||||
@ -91,10 +91,10 @@
|
|||||||
<Component class="javax.swing.JButton" name="showButton">
|
<Component class="javax.swing.JButton" name="showButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/discovery/arrow-up.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/discovery/ui/arrow-up.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="ResultsSplitPaneDivider.showButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="ResultsSplitPaneDivider.showButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="null"/>
|
<Border info="null"/>
|
@ -16,9 +16,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel for separating the results list from the details area.
|
* Panel for separating the results list from the details area.
|
||||||
@ -54,7 +55,7 @@ final class ResultsSplitPaneDivider extends javax.swing.JPanel {
|
|||||||
org.openide.awt.Mnemonics.setLocalizedText(detailsLabel, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.detailsLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(detailsLabel, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.detailsLabel.text")); // NOI18N
|
||||||
detailsLabel.setFocusable(false);
|
detailsLabel.setFocusable(false);
|
||||||
|
|
||||||
hideButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/discovery/arrow-down.png"))); // NOI18N
|
hideButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/discovery/ui/arrow-down.png"))); // NOI18N
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(hideButton, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.hideButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(hideButton, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.hideButton.text")); // NOI18N
|
||||||
hideButton.setBorder(null);
|
hideButton.setBorder(null);
|
||||||
hideButton.setFocusable(false);
|
hideButton.setFocusable(false);
|
||||||
@ -66,7 +67,7 @@ final class ResultsSplitPaneDivider extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
showButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/discovery/arrow-up.png"))); // NOI18N
|
showButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/discovery/ui/arrow-up.png"))); // NOI18N
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(showButton, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.showButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(showButton, org.openide.util.NbBundle.getMessage(ResultsSplitPaneDivider.class, "ResultsSplitPaneDivider.showButton.text")); // NOI18N
|
||||||
showButton.setBorder(null);
|
showButton.setBorder(null);
|
||||||
showButton.setFocusable(false);
|
showButton.setFocusable(false);
|
||||||
@ -85,7 +86,7 @@ final class ResultsSplitPaneDivider extends javax.swing.JPanel {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addComponent(detailsLabel)
|
.addComponent(detailsLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 251, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 199, Short.MAX_VALUE)
|
||||||
.addComponent(showButton)
|
.addComponent(showButton)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(hideButton)
|
.addComponent(hideButton)
|
@ -16,8 +16,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -25,8 +26,13 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey;
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileGroup;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearch;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchException;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSorter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SwingWorker to perform search on a background thread.
|
* SwingWorker to perform search on a background thread.
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="sizeCheckbox">
|
<Component class="javax.swing.JCheckBox" name="sizeCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="SizeFilterPanel.sizeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="SizeFilterPanel.sizeCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
@ -16,15 +16,18 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize;
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileSize;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to allow configuration of the Size Filter.
|
* Panel to allow configuration of the Size Filter.
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
@ -5,7 +5,7 @@
|
|||||||
<Component class="javax.swing.JCheckBox" name="userCreatedCheckbox">
|
<Component class="javax.swing.JCheckBox" name="userCreatedCheckbox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="UserCreatedFilterPanel.userCreatedCheckbox.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="UserCreatedFilterPanel.userCreatedCheckbox.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[150, 25]"/>
|
<Dimension value="[150, 25]"/>
|
@ -16,11 +16,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to allow configuration of the User Created Filter.
|
* Panel to allow configuration of the User Created Filter.
|
@ -71,7 +71,7 @@
|
|||||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
<TitledBorder title="Step 2: Filter which videos to show">
|
<TitledBorder title="Step 2: Filter which videos to show">
|
||||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/Bundle.properties" key="VideoFilterPanel.videoFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="VideoFilterPanel.videoFiltersSplitPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</TitledBorder>
|
</TitledBorder>
|
||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
@ -16,9 +16,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.AttributeSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.FileSearchData;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.SearchData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel for displaying all filters available for the searches of type Video.
|
* Panel for displaying all filters available for the searches of type Video.
|
@ -78,13 +78,13 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/red-circle-exclamation.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/red-circle-exclamation.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
@ -94,13 +94,13 @@
|
|||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/images/file-icon-deleted.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())" type="code"/>
|
<Connection code="new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize())" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
@ -113,14 +113,14 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe
|
|||||||
imagePanel.setLayout(new java.awt.GridBagLayout());
|
imagePanel.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
|
||||||
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
|
|
||||||
deletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
deletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
|
||||||
deletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
deletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
deletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
deletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
deletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize()));
|
deletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
@ -35,11 +35,11 @@
|
|||||||
</Property>
|
</Property>
|
||||||
<Property name="selectionMode" type="int" value="0"/>
|
<Property name="selectionMode" type="int" value="0"/>
|
||||||
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
<Connection code="new org.sleuthkit.autopsy.discovery.VideoThumbnailPanel()" type="code"/>
|
<Connection code="new org.sleuthkit.autopsy.discovery.ui.VideoThumbnailPanel()" type="code"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.discovery.VideoThumbnailsWrapper>"/>
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.discovery.ui.VideoThumbnailsWrapper>"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -104,7 +104,7 @@ final class VideoThumbnailViewer extends javax.swing.JPanel {
|
|||||||
|
|
||||||
thumbnailList.setModel(thumbnailListModel);
|
thumbnailList.setModel(thumbnailListModel);
|
||||||
thumbnailList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
thumbnailList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||||
thumbnailList.setCellRenderer(new org.sleuthkit.autopsy.discovery.VideoThumbnailPanel());
|
thumbnailList.setCellRenderer(new org.sleuthkit.autopsy.discovery.ui.VideoThumbnailPanel());
|
||||||
thumbnailListScrollPane.setViewportView(thumbnailList);
|
thumbnailListScrollPane.setViewportView(thumbnailList);
|
||||||
|
|
||||||
add(thumbnailListScrollPane, java.awt.BorderLayout.CENTER);
|
add(thumbnailListScrollPane, java.awt.BorderLayout.CENTER);
|
||||||
@ -112,7 +112,7 @@ final class VideoThumbnailViewer extends javax.swing.JPanel {
|
|||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JList<org.sleuthkit.autopsy.discovery.VideoThumbnailsWrapper> thumbnailList;
|
private javax.swing.JList<org.sleuthkit.autopsy.discovery.ui.VideoThumbnailsWrapper> thumbnailList;
|
||||||
private javax.swing.JScrollPane thumbnailListScrollPane;
|
private javax.swing.JScrollPane thumbnailListScrollPane;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
@ -16,12 +16,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.discovery;
|
package org.sleuthkit.autopsy.discovery.ui;
|
||||||
|
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.sleuthkit.autopsy.discovery.search.ResultFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to wrap all the information necessary for video thumbnails to be
|
* Class to wrap all the information necessary for video thumbnails to be
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Loading…
x
Reference in New Issue
Block a user