From 881b31bb60e76f1d783f5d6fdfd6ae5b7fee2b3f Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 11:43:21 -0400 Subject: [PATCH 01/10] 6610 move UI files --- .../autopsy/discovery/Bundle.properties | 51 ---------------- .../discovery/DiscoveryEventUtils.java | 1 + .../autopsy/discovery/FileSearch.java | 2 + .../autopsy/discovery/SearchFiltering.java | 1 + .../AbstractDiscoveryFilterPanel.java | 2 +- .../discovery/{ => ui}/AbstractFilter.java | 4 +- .../{ => ui}/AbstractFiltersPanel.java | 6 +- .../{ => ui}/ArtifactTypeFilterPanel.form | 2 +- .../{ => ui}/ArtifactTypeFilterPanel.java | 7 ++- .../autopsy/discovery/ui/Bundle.properties | 55 ++++++++++++++++++ .../{ => ui}/DataSourceFilterPanel.form | 2 +- .../{ => ui}/DataSourceFilterPanel.java | 3 +- .../{ => ui}/DataSourceModulesWrapper.java | 3 +- .../discovery/{ => ui}/DateFilterPanel.form | 10 ++-- .../discovery/{ => ui}/DateFilterPanel.java | 3 +- .../discovery/{ => ui}/DetailsPanel.form | 2 +- .../discovery/{ => ui}/DetailsPanel.java | 4 +- .../discovery/{ => ui}/DiscoveryDialog.form | 23 ++++---- .../discovery/{ => ui}/DiscoveryDialog.java | 11 +++- .../{ => ui}/DiscoveryExtractAction.java | 2 +- .../{ => ui}/DiscoveryThumbnailChildren.java | 2 +- .../{ => ui}/DiscoveryTopComponent.form | 0 .../{ => ui}/DiscoveryTopComponent.java | 4 +- .../discovery/{ => ui}/DiscoveryUiUtils.java | 4 +- .../{ => ui}/DocumentFilterPanel.form | 4 +- .../{ => ui}/DocumentFilterPanel.java | 5 +- .../discovery/{ => ui}/DocumentPanel.form | 16 ++--- .../discovery/{ => ui}/DocumentPanel.java | 16 ++--- .../{ => ui}/DocumentPreviewViewer.form | 0 .../{ => ui}/DocumentPreviewViewer.java | 2 +- .../discovery/{ => ui}/DocumentWrapper.java | 4 +- .../discovery/{ => ui}/DomainFilterPanel.form | 4 +- .../discovery/{ => ui}/DomainFilterPanel.java | 5 +- .../discovery/{ => ui}/GroupListPanel.form | 2 +- .../discovery/{ => ui}/GroupListPanel.java | 7 ++- .../{ => ui}/HashSetFilterPanel.form | 2 +- .../{ => ui}/HashSetFilterPanel.java | 3 +- .../discovery/{ => ui}/ImageFilterPanel.form | 4 +- .../discovery/{ => ui}/ImageFilterPanel.java | 5 +- .../{ => ui}/ImageThumbnailPanel.form | 14 ++--- .../{ => ui}/ImageThumbnailPanel.java | 15 ++--- .../{ => ui}/ImageThumbnailViewer.form | 0 .../{ => ui}/ImageThumbnailViewer.java | 2 +- .../{ => ui}/ImageThumbnailWrapper.java | 3 +- .../{ => ui}/InterestingItemsFilterPanel.form | 2 +- .../{ => ui}/InterestingItemsFilterPanel.java | 3 +- .../{ => ui}/ObjectDetectedFilterPanel.form | 0 .../{ => ui}/ObjectDetectedFilterPanel.java | 3 +- .../{ => ui}/OpenDiscoveryAction.java | 3 +- .../discovery/{ => ui}/PageWorker.java | 9 ++- .../{ => ui}/ParentFolderFilterPanel.form | 16 ++--- .../{ => ui}/ParentFolderFilterPanel.java | 3 +- .../{ => ui}/PastOccurrencesFilterPanel.form | 2 +- .../{ => ui}/PastOccurrencesFilterPanel.java | 4 +- .../discovery/{ => ui}/ResultsPanel.form | 8 +-- .../discovery/{ => ui}/ResultsPanel.java | 9 ++- .../{ => ui}/ResultsSplitPaneDivider.form | 6 +- .../{ => ui}/ResultsSplitPaneDivider.java | 3 +- .../discovery/{ => ui}/SearchWorker.java | 7 ++- .../discovery/{ => ui}/SizeFilterPanel.form | 2 +- .../discovery/{ => ui}/SizeFilterPanel.java | 4 +- .../discovery/{ => ui}/SwingAnimator.java | 2 +- .../{ => ui}/SwingAnimatorCallback.java | 2 +- .../{ => ui}/UserCreatedFilterPanel.form | 2 +- .../{ => ui}/UserCreatedFilterPanel.java | 3 +- .../discovery/{ => ui}/VideoFilterPanel.form | 2 +- .../discovery/{ => ui}/VideoFilterPanel.java | 5 +- .../{ => ui}/VideoThumbnailPanel.form | 12 ++-- .../{ => ui}/VideoThumbnailPanel.java | 15 ++--- .../{ => ui}/VideoThumbnailViewer.form | 4 +- .../{ => ui}/VideoThumbnailViewer.java | 6 +- .../{ => ui}/VideoThumbnailsWrapper.java | 3 +- .../autopsy/discovery/{ => ui}/arrow-down.png | Bin .../autopsy/discovery/{ => ui}/arrow-up.png | Bin 74 files changed, 270 insertions(+), 187 deletions(-) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/AbstractDiscoveryFilterPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/AbstractFilter.java (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/AbstractFiltersPanel.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ArtifactTypeFilterPanel.form (94%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ArtifactTypeFilterPanel.java (95%) create mode 100644 Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DataSourceFilterPanel.form (96%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DataSourceFilterPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DataSourceModulesWrapper.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DateFilterPanel.form (94%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DateFilterPanel.java (99%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DetailsPanel.form (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DetailsPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryDialog.form (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryDialog.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryExtractAction.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryThumbnailChildren.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryTopComponent.form (100%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryTopComponent.java (99%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DiscoveryUiUtils.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentFilterPanel.form (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentFilterPanel.java (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentPanel.form (88%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentPanel.java (92%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentPreviewViewer.form (100%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentPreviewViewer.java (99%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DocumentWrapper.java (94%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DomainFilterPanel.form (92%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/DomainFilterPanel.java (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/GroupListPanel.form (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/GroupListPanel.java (96%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/HashSetFilterPanel.form (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/HashSetFilterPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageFilterPanel.form (92%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageFilterPanel.java (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageThumbnailPanel.form (89%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageThumbnailPanel.java (91%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageThumbnailViewer.form (100%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageThumbnailViewer.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ImageThumbnailWrapper.java (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/InterestingItemsFilterPanel.form (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/InterestingItemsFilterPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ObjectDetectedFilterPanel.form (100%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ObjectDetectedFilterPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/OpenDiscoveryAction.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/PageWorker.java (91%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ParentFolderFilterPanel.form (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ParentFolderFilterPanel.java (99%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/PastOccurrencesFilterPanel.form (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/PastOccurrencesFilterPanel.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ResultsPanel.form (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ResultsPanel.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ResultsSplitPaneDivider.form (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/ResultsSplitPaneDivider.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/SearchWorker.java (91%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/SizeFilterPanel.form (96%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/SizeFilterPanel.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/SwingAnimator.java (98%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/SwingAnimatorCallback.java (96%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/UserCreatedFilterPanel.form (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/UserCreatedFilterPanel.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoFilterPanel.form (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoFilterPanel.java (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoThumbnailPanel.form (88%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoThumbnailPanel.java (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoThumbnailViewer.form (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoThumbnailViewer.java (95%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/VideoThumbnailsWrapper.java (96%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/arrow-down.png (100%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/arrow-up.png (100%) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties index 250df96f59..82c3178cef 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties @@ -44,33 +44,14 @@ 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 @@ -80,37 +61,5 @@ 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: diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java index 7951d6f175..4507d06f18 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery; +import org.sleuthkit.autopsy.discovery.ui.AbstractFilter; import com.google.common.eventbus.EventBus; import java.util.Collections; import java.util.List; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java index a2fad07be3..09dd98882c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.discovery; +import org.sleuthkit.autopsy.discovery.ui.VideoThumbnailsWrapper; +import org.sleuthkit.autopsy.discovery.ui.AbstractFilter; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.io.Files; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java b/Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java index beecf6c7d1..bf52e38563 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery; +import org.sleuthkit.autopsy.discovery.ui.AbstractFilter; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/AbstractDiscoveryFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/AbstractDiscoveryFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java index 36e0318a75..2be3071af6 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/AbstractDiscoveryFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.event.ActionListener; import javax.swing.JCheckBox; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/AbstractFilter.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFilter.java similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/AbstractFilter.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFilter.java index 4e0ecd2e79..1ac8ed925e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/AbstractFilter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFilter.java @@ -16,11 +16,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.ArrayList; import java.util.List; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.FileSearchException; +import org.sleuthkit.autopsy.discovery.ResultFile; import org.sleuthkit.datamodel.SleuthkitCase; /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/AbstractFiltersPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/AbstractFiltersPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java index d6ed042c18..eb7d0de8c8 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/AbstractFiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Component; import java.awt.GridBagConstraints; @@ -31,6 +31,10 @@ import javax.swing.JSplitPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.apache.commons.lang3.StringUtils; +import org.sleuthkit.autopsy.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.SearchData; +import org.sleuthkit.autopsy.discovery.SearchFiltering; /** * Abstract class extending JPanel for displaying all the filters associated diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ArtifactTypeFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form similarity index 94% rename from Core/src/org/sleuthkit/autopsy/discovery/ArtifactTypeFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form index 79cd9586a3..d269dc7d15 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ArtifactTypeFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ArtifactTypeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/ArtifactTypeFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java index f058b8d071..c7691cb2b0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ArtifactTypeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java @@ -16,12 +16,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; +import org.sleuthkit.autopsy.discovery.AttributeSearchData; import org.sleuthkit.datamodel.BlackboardArtifact; /** @@ -80,11 +81,11 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { this.setLayout(layout); layout.setHorizontalGroup( 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.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) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties new file mode 100644 index 0000000000..a2873c3d89 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties @@ -0,0 +1,55 @@ +# 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. + +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 +DetailsPanel.instancesList.border.title=Instances diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DataSourceFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form similarity index 96% rename from Core/src/org/sleuthkit/autopsy/discovery/DataSourceFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form index 44ea93cd5a..3f2a9d4a1d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DataSourceFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DataSourceFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/DataSourceFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java index 6afc8c6c69..6321afa357 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DataSourceFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.List; import java.util.logging.Level; @@ -27,6 +27,7 @@ import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.discovery.SearchFiltering; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DataSourceModulesWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/DataSourceModulesWrapper.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java index b1857c2413..170aec7acf 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DataSourceModulesWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java @@ -16,9 +16,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.discovery.Bundle; import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DateFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.form similarity index 94% rename from Core/src/org/sleuthkit/autopsy/discovery/DateFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.form index a07307e518..6801b3f579 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DateFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.form @@ -7,7 +7,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -123,7 +123,7 @@ - + @@ -134,7 +134,7 @@ - + @@ -167,7 +167,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DateFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java similarity index 99% rename from Core/src/org/sleuthkit/autopsy/discovery/DateFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java index 5c397ae038..1776e862d4 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DateFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import javax.swing.JCheckBox; import javax.swing.JLabel; @@ -24,6 +24,7 @@ import javax.swing.JList; import javax.swing.SpinnerNumberModel; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.communications.Utils; +import org.sleuthkit.autopsy.discovery.Bundle; /** * Filter panel for allowing the user to filter on date. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.form similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.form index 32f78a9645..bd3d8c5af9 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.form @@ -106,7 +106,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java index 6b0a37e276..9b30ef3383 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import com.google.common.eventbus.Subscribe; import java.awt.Component; @@ -39,6 +39,8 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; +import org.sleuthkit.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form index 93d2015fdb..522cd9b43e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form @@ -6,9 +6,6 @@ - - - @@ -94,7 +91,7 @@ - + @@ -121,7 +118,7 @@ - + @@ -151,7 +148,7 @@ - + @@ -168,7 +165,7 @@ - + @@ -200,7 +197,7 @@ - + @@ -263,7 +260,7 @@ - + @@ -282,7 +279,7 @@ - + @@ -361,7 +358,7 @@ - + @@ -372,7 +369,7 @@ - + @@ -383,7 +380,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java index 9fd4f1a00a..977a6fa046 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import static java.awt.BorderLayout.CENTER; import java.awt.Color; @@ -36,11 +36,19 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.FileGroup; import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm; +import org.sleuthkit.autopsy.discovery.FileSearch; import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE; import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.FileSorter; import static org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType.PARENT_PATH; import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod; +import org.sleuthkit.autopsy.discovery.SearchData; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -298,7 +306,6 @@ final class DiscoveryDialog extends javax.swing.JDialog { setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setMinimumSize(new java.awt.Dimension(600, 300)); - setPreferredSize(new java.awt.Dimension(1000, 650)); imagesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/pictures-icon.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(imagesButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.imagesButton.text")); // NOI18N diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryExtractAction.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryExtractAction.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryExtractAction.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryExtractAction.java index acaf0ccc99..7965878017 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryExtractAction.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryExtractAction.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.directorytree.actionhelpers.ExtractActionHelper; import java.awt.event.ActionEvent; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryThumbnailChildren.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryThumbnailChildren.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryThumbnailChildren.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryThumbnailChildren.java index bdcf2f876f..dce68e3a41 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryThumbnailChildren.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryThumbnailChildren.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.Arrays; import java.util.HashSet; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form similarity index 100% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java similarity index 99% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java index 5f47b2d694..010a086b30 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import com.google.common.eventbus.Subscribe; import java.awt.BorderLayout; @@ -36,6 +36,8 @@ import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.coreutils.ThreadConfined; +import org.sleuthkit.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.SearchData.ResultType; /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryUiUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryUiUtils.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java index 55392f54f2..72b0d5db3b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryUiUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Component; import java.awt.Dimension; @@ -37,6 +37,8 @@ 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.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.ResultFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.DataSource; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.form similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.form index a1c49c4c07..16b22c3672 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.form @@ -58,14 +58,14 @@ + - + - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java index e1635c4e50..29e29972bd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DocumentFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java @@ -16,9 +16,12 @@ * See the License for the specific language governing permissions and * 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.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.SearchData; /** * Class which displays all filters available for the Documents search type. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.form similarity index 88% rename from Core/src/org/sleuthkit/autopsy/discovery/DocumentPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.form index bb29cdb8b4..9329d6f976 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.form @@ -80,16 +80,16 @@ - + - + - + - + @@ -100,20 +100,20 @@ - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java similarity index 92% rename from Core/src/org/sleuthkit/autopsy/discovery/DocumentPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java index 2852c7579a..78d88e9cb7 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Color; import java.awt.Component; @@ -29,6 +29,8 @@ import javax.swing.JList; import javax.swing.ListCellRenderer; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane; +import org.sleuthkit.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.FileSearchData; /** * Class which displays a preview and details about a document. @@ -67,15 +69,15 @@ class DocumentPanel extends javax.swing.JPanel implements ListCellRenderer - + - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DomainFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/DomainFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java index b6f4a0c42b..05e0907935 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DomainFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java @@ -16,9 +16,12 @@ * See the License for the specific language governing permissions and * 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.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.SearchData; /** * Filter panel for searching domain attributes with Discovery. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/GroupListPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.form similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/GroupListPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.form index be51027b3a..47ead7ce0b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/GroupListPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.form @@ -46,7 +46,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/discovery/GroupListPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java index caaacd1d30..46de95137c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import com.google.common.eventbus.Subscribe; import java.awt.Cursor; @@ -28,8 +28,13 @@ import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.FileGroup; +import org.sleuthkit.autopsy.discovery.FileSearch; import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.autopsy.discovery.FileSearchData.FileType; +import org.sleuthkit.autopsy.discovery.FileSorter; /** * Panel to display the list of groups which are provided by a search. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/HashSetFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/HashSetFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form index 8f83bc0e77..56c033db74 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/HashSetFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/HashSetFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/HashSetFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java index 17673cfece..1703737c1c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/HashSetFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.List; import java.util.logging.Level; @@ -25,6 +25,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.discovery.SearchFiltering; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.form similarity index 92% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.form index 7a3374f5cb..0eab977a06 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.form @@ -61,13 +61,13 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java index b0d0d01287..8008b9a41f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java @@ -16,9 +16,12 @@ * See the License for the specific language governing permissions and * 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.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.SearchData; /** * Panel for displaying all the filters associated with the Image type. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.form similarity index 89% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.form index c3ae30091c..46c5d3601f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.form @@ -102,16 +102,16 @@ - + - + - + - + @@ -122,13 +122,13 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java index 8f7b90ad08..88c2eb9526 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Color; import java.awt.Component; @@ -28,6 +28,7 @@ import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.discovery.Bundle; /** * Class which displays a thumbnail and information for an image file. @@ -76,15 +77,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.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.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())); - isDeletedLabel.setPreferredSize(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.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.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.setToolTipText(""); - scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())); - scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())); - scoreLabel.setPreferredSize(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.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.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); this.setLayout(layout); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailViewer.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailViewer.form similarity index 100% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailViewer.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailViewer.form diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailViewer.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailViewer.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailViewer.java index b1f5ce97e7..273cca8023 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailViewer.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.ArrayList; import java.util.List; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailWrapper.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java index b4e7bb0b01..2dc072b175 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ImageThumbnailWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java @@ -16,10 +16,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Image; import org.sleuthkit.autopsy.coreutils.ImageUtils; +import org.sleuthkit.autopsy.discovery.ResultFile; /** * Class to wrap all the information necessary for an image thumbnail to be diff --git a/Core/src/org/sleuthkit/autopsy/discovery/InterestingItemsFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/InterestingItemsFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form index ff3b7cea10..c5a8660cdd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/InterestingItemsFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/InterestingItemsFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/InterestingItemsFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java index 1eea4a020b..1106391d9b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/InterestingItemsFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.List; import java.util.logging.Level; @@ -25,6 +25,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.discovery.SearchFiltering; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ObjectDetectedFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.form similarity index 100% rename from Core/src/org/sleuthkit/autopsy/discovery/ObjectDetectedFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.form diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ObjectDetectedFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/ObjectDetectedFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java index a87c826f33..4dacc11d55 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ObjectDetectedFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.List; import java.util.logging.Level; @@ -25,6 +25,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.discovery.SearchFiltering; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java index 04530f8ad2..d1982ab364 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Component; import javax.swing.ImageIcon; @@ -31,6 +31,7 @@ import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.Presenter; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.discovery.Bundle; /** * Class to open the Discovery dialog. Allows the user to run searches and see diff --git a/Core/src/org/sleuthkit/autopsy/discovery/PageWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/discovery/PageWorker.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java index 52418bef11..f9c5415294 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/PageWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.List; import java.util.ArrayList; @@ -26,6 +26,13 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.FileGroup; +import org.sleuthkit.autopsy.discovery.FileSearch; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchException; +import org.sleuthkit.autopsy.discovery.FileSorter; +import org.sleuthkit.autopsy.discovery.ResultFile; /** * SwingWorker to retrieve the contents of a page. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ParentFolderFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.form similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/ParentFolderFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.form index b350ab42b3..fe21dc8607 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ParentFolderFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.form @@ -5,7 +5,7 @@ - + @@ -24,7 +24,7 @@ - + @@ -160,7 +160,7 @@ - + @@ -172,7 +172,7 @@ - + @@ -183,7 +183,7 @@ - + @@ -194,7 +194,7 @@ - + @@ -202,7 +202,7 @@ - + @@ -222,7 +222,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ParentFolderFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java similarity index 99% rename from Core/src/org/sleuthkit/autopsy/discovery/ParentFolderFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java index 3df211b2d0..841dd910bc 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ParentFolderFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.ArrayList; import java.util.List; @@ -24,6 +24,7 @@ import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; +import org.sleuthkit.autopsy.discovery.SearchFiltering; import org.sleuthkit.autopsy.discovery.SearchFiltering.ParentSearchTerm; /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/PastOccurrencesFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/PastOccurrencesFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form index 37ea6de900..bfe666aee3 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/PastOccurrencesFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/PastOccurrencesFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/PastOccurrencesFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java index b6979fe9e4..20fead3473 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/PastOccurrencesFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java @@ -16,15 +16,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.FileSearchData; import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency; import org.sleuthkit.autopsy.discovery.SearchData.ResultType; +import org.sleuthkit.autopsy.discovery.SearchFiltering; /** * Panel to allow configuration of the Past Occurrences filter. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.form similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.form index cad2e006cd..d256c2374e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.form @@ -79,7 +79,7 @@ - + @@ -127,7 +127,7 @@ - + @@ -153,7 +153,7 @@ - + @@ -199,7 +199,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java index eb844a7a73..e2686c58eb 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import com.google.common.eventbus.Subscribe; import java.awt.Cursor; @@ -38,6 +38,13 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.Bundle; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.FileGroup; +import org.sleuthkit.autopsy.discovery.FileSearch; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.FileSorter; +import org.sleuthkit.autopsy.discovery.ResultFile; import org.sleuthkit.autopsy.textsummarizer.TextSummary; /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultsSplitPaneDivider.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/ResultsSplitPaneDivider.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form index 48ae94d8a9..a61f5a9c93 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultsSplitPaneDivider.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form @@ -54,7 +54,7 @@ - + @@ -69,7 +69,7 @@ - + @@ -94,7 +94,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultsSplitPaneDivider.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/ResultsSplitPaneDivider.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java index 0a89f28711..6243416325 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultsSplitPaneDivider.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java @@ -16,9 +16,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Cursor; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; /** * Panel for separating the results list from the details area. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SearchWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/discovery/SearchWorker.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java index c1877109b5..ea14294d95 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SearchWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.LinkedHashMap; import javax.swing.SwingWorker; @@ -27,6 +27,11 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.FileGroup; +import org.sleuthkit.autopsy.discovery.FileSearch; +import org.sleuthkit.autopsy.discovery.FileSearchException; +import org.sleuthkit.autopsy.discovery.FileSorter; /** * SwingWorker to perform search on a background thread. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SizeFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form similarity index 96% rename from Core/src/org/sleuthkit/autopsy/discovery/SizeFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form index 1b77a4329e..fd63ea077d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SizeFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SizeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/SizeFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java index c6f0478f38..8ca29f0018 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SizeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.ArrayList; import java.util.List; @@ -24,7 +24,9 @@ import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; +import org.sleuthkit.autopsy.discovery.FileSearchData; import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize; +import org.sleuthkit.autopsy.discovery.SearchFiltering; /** * Panel to allow configuration of the Size Filter. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SwingAnimator.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/SwingAnimator.java index 2dac8559bb..cb32183eb2 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimator.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SwingAnimator.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimatorCallback.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SwingAnimatorCallback.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/discovery/SwingAnimatorCallback.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/SwingAnimatorCallback.java index 86f7d2f7fb..2393f7957b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SwingAnimatorCallback.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SwingAnimatorCallback.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; /** * diff --git a/Core/src/org/sleuthkit/autopsy/discovery/UserCreatedFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.form similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/UserCreatedFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.form index 520bf47dc3..a6fc200308 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/UserCreatedFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.form @@ -5,7 +5,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/UserCreatedFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/UserCreatedFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java index 8f6be8b12b..5d421a0b0d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/UserCreatedFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java @@ -16,11 +16,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; +import org.sleuthkit.autopsy.discovery.SearchFiltering; /** * Panel to allow configuration of the User Created Filter. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.form similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.form index 1a853b425a..914d724f3d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.form @@ -71,7 +71,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java index 8d0d51ef34..d1388a45ba 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java @@ -16,9 +16,12 @@ * See the License for the specific language governing permissions and * 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.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.SearchData; /** * Panel for displaying all filters available for the searches of type Video. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.form similarity index 88% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailPanel.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.form index 522acb16c8..759e61c6d2 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.form @@ -78,13 +78,13 @@ - + - + - + @@ -94,13 +94,13 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailPanel.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java index d8845f565a..609904ee2a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Color; import java.awt.Component; @@ -32,6 +32,7 @@ import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.discovery.Bundle; /** * Class which displays thumbnails and information for a video file. @@ -113,14 +114,14 @@ final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRe imagePanel.setLayout(new java.awt.GridBagLayout()); 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.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())); - scoreLabel.setPreferredSize(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.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.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.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())); - deletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.DiscoveryUiUtils.getIconSize())); - deletedLabel.setPreferredSize(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.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.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); this.setLayout(layout); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailViewer.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailViewer.form similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailViewer.form rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailViewer.form index aa8875a52d..54c180973c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailViewer.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailViewer.form @@ -35,11 +35,11 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailViewer.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailViewer.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailViewer.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailViewer.java index bb3c5a30ea..8824e6f5d8 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailViewer.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailViewer.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.util.ArrayList; import java.util.List; @@ -104,7 +104,7 @@ final class VideoThumbnailViewer extends javax.swing.JPanel { thumbnailList.setModel(thumbnailListModel); 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); 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 - private javax.swing.JList thumbnailList; + private javax.swing.JList thumbnailList; private javax.swing.JScrollPane thumbnailListScrollPane; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailsWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailsWrapper.java rename to Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java index 52c188ac80..429b26d926 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/VideoThumbnailsWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java @@ -16,12 +16,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.ui; import java.awt.Image; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.sleuthkit.autopsy.discovery.ResultFile; /** * Class to wrap all the information necessary for video thumbnails to be diff --git a/Core/src/org/sleuthkit/autopsy/discovery/arrow-down.png b/Core/src/org/sleuthkit/autopsy/discovery/ui/arrow-down.png similarity index 100% rename from Core/src/org/sleuthkit/autopsy/discovery/arrow-down.png rename to Core/src/org/sleuthkit/autopsy/discovery/ui/arrow-down.png diff --git a/Core/src/org/sleuthkit/autopsy/discovery/arrow-up.png b/Core/src/org/sleuthkit/autopsy/discovery/ui/arrow-up.png similarity index 100% rename from Core/src/org/sleuthkit/autopsy/discovery/arrow-up.png rename to Core/src/org/sleuthkit/autopsy/discovery/ui/arrow-up.png From 3eee575d66621e09f837adb19dc4f77bc87a2f1b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 13:42:39 -0400 Subject: [PATCH 02/10] 6610 refactor and move search related discovery files --- .../autopsy/discovery/Bundle.properties | 65 -- .../{ui => search}/AbstractFilter.java | 14 +- .../{ => search}/AttributeSearchData.java | 16 +- .../{ => search}/DiscoveryEventUtils.java | 91 +- .../discovery/search/DiscoveryKeyUtils.java | 341 +++++++ .../discovery/{ => search}/FileGroup.java | 19 +- .../discovery/{ => search}/FileSearch.java | 857 +----------------- .../{ => search}/FileSearchData.java | 52 +- .../{ => search}/FileSearchException.java | 2 +- .../discovery/{ => search}/FileSorter.java | 12 +- .../discovery/{ => search}/ResultFile.java | 46 +- .../discovery/{ => search}/SearchData.java | 8 +- .../{ => search}/SearchFiltering.java | 155 ++-- .../discovery/{ => search}/SearchResults.java | 8 +- .../discovery/search/SummaryHelpers.java | 236 +++++ .../ui/AbstractDiscoveryFilterPanel.java | 1 + .../discovery/ui/AbstractFiltersPanel.java | 9 +- .../discovery/ui/ArtifactTypeFilterPanel.java | 3 +- .../{ => ui}/Bundle.properties-MERGED | 0 .../discovery/ui/DataSourceFilterPanel.java | 3 +- .../ui/DataSourceModulesWrapper.java | 1 - .../autopsy/discovery/ui/DateFilterPanel.java | 2 +- .../autopsy/discovery/ui/DetailsPanel.java | 2 +- .../autopsy/discovery/ui/DiscoveryDialog.java | 28 +- .../discovery/ui/DiscoveryTopComponent.form | 2 +- .../discovery/ui/DiscoveryTopComponent.java | 6 +- .../discovery/ui/DiscoveryUiUtils.java | 292 +++++- .../discovery/ui/DocumentFilterPanel.java | 6 +- .../autopsy/discovery/ui/DocumentPanel.java | 3 +- .../autopsy/discovery/ui/DocumentWrapper.java | 3 +- .../discovery/ui/DomainFilterPanel.java | 6 +- .../autopsy/discovery/ui/GroupListPanel.java | 14 +- .../discovery/ui/HashSetFilterPanel.java | 3 +- .../discovery/ui/ImageFilterPanel.java | 6 +- .../discovery/ui/ImageThumbnailPanel.java | 1 - .../discovery/ui/ImageThumbnailWrapper.java | 2 +- .../ui/InterestingItemsFilterPanel.java | 3 +- .../ui/ObjectDetectedFilterPanel.java | 3 +- .../discovery/ui/OpenDiscoveryAction.java | 1 - .../autopsy/discovery/ui/PageWorker.java | 17 +- .../discovery/ui/ParentFolderFilterPanel.java | 5 +- .../ui/PastOccurrencesFilterPanel.java | 4 - .../autopsy/discovery/ui/ResultsPanel.java | 18 +- .../discovery/ui/ResultsSplitPaneDivider.java | 2 +- .../autopsy/discovery/ui/SearchWorker.java | 13 +- .../autopsy/discovery/ui/SizeFilterPanel.java | 7 +- .../discovery/ui/UserCreatedFilterPanel.java | 3 +- .../discovery/ui/VideoFilterPanel.java | 6 +- .../discovery/ui/VideoThumbnailPanel.java | 1 - .../discovery/ui/VideoThumbnailsWrapper.java | 2 +- 50 files changed, 1203 insertions(+), 1197 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties rename Core/src/org/sleuthkit/autopsy/discovery/{ui => search}/AbstractFilter.java (84%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/AttributeSearchData.java (87%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/DiscoveryEventUtils.java (81%) create mode 100644 Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/FileGroup.java (91%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/FileSearch.java (62%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/FileSearchData.java (93%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/FileSearchException.java (96%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/FileSorter.java (97%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/ResultFile.java (91%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/SearchData.java (85%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/SearchFiltering.java (89%) rename Core/src/org/sleuthkit/autopsy/discovery/{ => search}/SearchResults.java (95%) create mode 100644 Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java rename Core/src/org/sleuthkit/autopsy/discovery/{ => ui}/Bundle.properties-MERGED (100%) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties deleted file mode 100644 index 82c3178cef..0000000000 --- a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties +++ /dev/null @@ -1,65 +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: -DiscoveryExtractAction.title.extractFiles.text=Extract File -FileSearchPanel.includeRadioButton.text=Include -FileSearchPanel.excludeRadioButton.text=Exclude -FileSearchPanel.knownFilesCheckbox.toolTipText= -FileSearchPanel.knownFilesCheckbox.text=Hide known files -FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings -FileSearchPanel.userCreatedCheckbox.text=Possibly User Created -UserCreatedFilterPanel.userCreatedCheckbox.text=Possibly User Created -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 -ObjectDetectedFilterPanel.text=Object Detected: -DomainUniquenessFilterPanel.domainUniquenessCheckbox.text=Domain Uniqueness: diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFilter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java similarity index 84% rename from Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFilter.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java index 1ac8ed925e..7ed3d54edd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFilter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java @@ -16,19 +16,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery.ui; +package org.sleuthkit.autopsy.discovery.search; import java.util.ArrayList; import java.util.List; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.FileSearchException; -import org.sleuthkit.autopsy.discovery.ResultFile; import org.sleuthkit.datamodel.SleuthkitCase; /** * 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 @@ -37,7 +35,7 @@ abstract class AbstractFilter { * @return the SQL query or an empty string if there is no SQL query for * this filter. */ - abstract String getWhereClause(); + public abstract String getWhereClause(); /** * Indicates whether this filter needs to use the secondary, non-SQL method @@ -45,7 +43,7 @@ abstract class AbstractFilter { * * @return false by default */ - boolean useAlternateFilter() { + public boolean useAlternateFilter() { return false; } @@ -63,7 +61,7 @@ abstract class AbstractFilter { * * @throws FileSearchException */ - List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, + public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { return new ArrayList<>(); } @@ -73,5 +71,5 @@ abstract class AbstractFilter { * * @return A description of the filter */ - abstract String getDesc(); + public abstract String getDesc(); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/AttributeSearchData.java b/Core/src/org/sleuthkit/autopsy/discovery/search/AttributeSearchData.java similarity index 87% rename from Core/src/org/sleuthkit/autopsy/discovery/AttributeSearchData.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/AttributeSearchData.java index 922817a654..322a11867c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/AttributeSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/AttributeSearchData.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; import java.util.Collection; import java.util.Collections; @@ -29,22 +29,22 @@ import org.sleuthkit.datamodel.BlackboardArtifact; /** * Utility enums for searches made for attributes with Discovery. */ -public class AttributeSearchData extends SearchData { +public class AttributeSearchData implements SearchData { private static final Set 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 - ResultType getResultType() { + public ResultType getResultType() { return ResultType.ATTRIBUTE; } /** - * Enum representing the attribute type. + * Enum representing the attribute type. */ @NbBundle.Messages({ "AttributeSearchData.AttributeType.Domain.displayName=Domain", "AttributeSearchData.AttributeType.Other.displayName=Other"}) - enum AttributeType { + public enum AttributeType { DOMAIN(0, Bundle.AttributeSearchData_AttributeType_Domain_displayName(), DOMAIN_ARTIFACT_TYPES), OTHER(1, Bundle.AttributeSearchData_AttributeType_Other_displayName(), new HashSet<>()); @@ -64,7 +64,7 @@ public class AttributeSearchData extends SearchData { * * @return Collection of BlackboardArtifact types. */ - Collection getBlackboardTypes() { + public Collection getBlackboardTypes() { return Collections.unmodifiableCollection(artifactTypes); } @@ -78,11 +78,11 @@ public class AttributeSearchData extends SearchData { * * @return the rank (lower should be displayed first) */ - int getRanking() { + public int getRanking() { return ranking; } - static AttributeType fromBlackboardArtifact(final BlackboardArtifact.ARTIFACT_TYPE type) { + public static AttributeType fromBlackboardArtifact(final BlackboardArtifact.ARTIFACT_TYPE type) { switch (type) { case TSK_WEB_BOOKMARK: return DOMAIN; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java similarity index 81% rename from Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java index 4507d06f18..01b2606b42 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java @@ -16,23 +16,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; -import org.sleuthkit.autopsy.discovery.ui.AbstractFilter; import com.google.common.eventbus.EventBus; import java.util.Collections; import java.util.List; import java.util.Map; -import org.sleuthkit.autopsy.discovery.AttributeSearchData.AttributeType; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; -import org.sleuthkit.autopsy.discovery.FileSearchData.FileType; -import org.sleuthkit.autopsy.discovery.SearchData.ResultType; +import org.sleuthkit.autopsy.discovery.search.AttributeSearchData.AttributeType; +import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType; +import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType; import org.sleuthkit.datamodel.AbstractFile; /** * Class to handle event bus and events for discovery tool. */ -final class DiscoveryEventUtils { +public final class DiscoveryEventUtils { private final static EventBus discoveryEventBus = new EventBus(); @@ -41,7 +40,7 @@ final class DiscoveryEventUtils { * * @return The discovery event bus. */ - static EventBus getDiscoveryEventBus() { + public static EventBus getDiscoveryEventBus() { return discoveryEventBus; } @@ -55,7 +54,7 @@ final class DiscoveryEventUtils { /** * 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 FileType fileType; @@ -66,7 +65,7 @@ final class DiscoveryEventUtils { * * @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.fileType = fileType; this.attributeType = attributeType; @@ -77,7 +76,7 @@ final class DiscoveryEventUtils { * * @return The result type, either FILES, or ATTRIBUTES. */ - ResultType getResultType() { + public ResultType getResultType() { return resultType; } @@ -86,7 +85,7 @@ final class DiscoveryEventUtils { * * @return The type of files being searched for. */ - FileType getFileType() { + public FileType getFileType() { return fileType; } @@ -95,7 +94,7 @@ final class DiscoveryEventUtils { * * @return The type of attribute being searched for. */ - AttributeType getAttributeType() { + public AttributeType getAttributeType() { return attributeType; } } @@ -103,12 +102,12 @@ final class DiscoveryEventUtils { /** * Event to signal that the Instances list should have selection cleared. */ - static final class ClearInstanceSelectionEvent { + public static final class ClearInstanceSelectionEvent { /** * Construct a new ClearInstanceSelectionEvent. */ - ClearInstanceSelectionEvent() { + public ClearInstanceSelectionEvent() { //no arg constructor } } @@ -116,21 +115,21 @@ final class DiscoveryEventUtils { /** * Event to signal that the Instances list should be populated. */ - static final class PopulateInstancesListEvent { + public static final class PopulateInstancesListEvent { private final List instances; /** * Construct a new PopulateInstancesListEvent. */ - PopulateInstancesListEvent(List files) { + public PopulateInstancesListEvent(List files) { instances = files; } /** * @return the instances */ - List getInstances() { + public List getInstances() { return Collections.unmodifiableList(instances); } } @@ -138,7 +137,7 @@ final class DiscoveryEventUtils { /** * Event to signal the completion of a search being performed. */ - static final class SearchCompleteEvent { + public static final class SearchCompleteEvent { private final Map groupMap; private final List searchFilters; @@ -157,7 +156,7 @@ final class DiscoveryEventUtils { * @param groupSort The sorting algorithm used for groups. * @param fileSortMethod The sorting method used for files. */ - SearchCompleteEvent(Map groupMap, List searchfilters, + public SearchCompleteEvent(Map groupMap, List searchfilters, FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod) { this.groupMap = groupMap; @@ -172,7 +171,7 @@ final class DiscoveryEventUtils { * * @return The map of groups which were found by the search. */ - Map getGroupMap() { + public Map getGroupMap() { return Collections.unmodifiableMap(groupMap); } @@ -181,7 +180,7 @@ final class DiscoveryEventUtils { * * @return The search filters which were used by the search. */ - List getFilters() { + public List getFilters() { return Collections.unmodifiableList(searchFilters); } @@ -190,7 +189,7 @@ final class DiscoveryEventUtils { * * @return The grouping attribute used by the search. */ - FileSearch.AttributeType getGroupingAttr() { + public FileSearch.AttributeType getGroupingAttr() { return groupingAttribute; } @@ -199,7 +198,7 @@ final class DiscoveryEventUtils { * * @return The sorting algorithm used for groups. */ - FileGroup.GroupSortingAlgorithm getGroupSort() { + public FileGroup.GroupSortingAlgorithm getGroupSort() { return groupSort; } @@ -208,7 +207,7 @@ final class DiscoveryEventUtils { * * @return The sorting method used for files. */ - FileSorter.SortingMethod getFileSort() { + public FileSorter.SortingMethod getFileSort() { return fileSortMethod; } @@ -218,7 +217,7 @@ final class DiscoveryEventUtils { * Event to signal the completion of page retrieval and include the page * contents. */ - static final class PageRetrievedEvent { + public static final class PageRetrievedEvent { private final List results; private final int page; @@ -231,7 +230,7 @@ final class DiscoveryEventUtils { * @param page The number of the page which was retrieved. * @param results The list of files in the page retrieved. */ - PageRetrievedEvent(FileType resultType, int page, List results) { + public PageRetrievedEvent(FileType resultType, int page, List results) { this.results = results; this.page = page; this.resultType = resultType; @@ -242,7 +241,7 @@ final class DiscoveryEventUtils { * * @return The list of files in the page retrieved. */ - List getSearchResults() { + public List getSearchResults() { return Collections.unmodifiableList(results); } @@ -251,7 +250,7 @@ final class DiscoveryEventUtils { * * @return The number of the page which was retrieved. */ - int getPageNumber() { + public int getPageNumber() { return page; } @@ -260,7 +259,7 @@ final class DiscoveryEventUtils { * * @return The type of files which exist in the page. */ - FileType getType() { + public FileType getType() { return resultType; } } @@ -268,12 +267,12 @@ final class DiscoveryEventUtils { /** * Event to signal that there were no results for the search. */ - static final class NoResultsEvent { + public static final class NoResultsEvent { /** * Construct a new NoResultsEvent. */ - NoResultsEvent() { + public NoResultsEvent() { //no arg constructor } } @@ -281,12 +280,12 @@ final class DiscoveryEventUtils { /** * Event to signal that a search has been cancelled */ - static final class SearchCancelledEvent { + public static final class SearchCancelledEvent { /** * Construct a new SearchCancelledEvent. */ - SearchCancelledEvent() { + public SearchCancelledEvent() { //no arg constructor } @@ -295,7 +294,7 @@ final class DiscoveryEventUtils { /** * Event to signal that a group has been selected. */ - static final class GroupSelectedEvent { + public static final class GroupSelectedEvent { private final FileType resultType; private final GroupKey groupKey; @@ -319,7 +318,7 @@ final class DiscoveryEventUtils { * selected. * @param resultType The type of files which exist in the group. */ - GroupSelectedEvent(List searchfilters, + public GroupSelectedEvent(List searchfilters, FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, FileType resultType) { this.searchfilters = searchfilters; @@ -336,7 +335,7 @@ final class DiscoveryEventUtils { * * @return The type of files which exist in the group. */ - FileType getResultType() { + public FileType getResultType() { return resultType; } @@ -347,7 +346,7 @@ final class DiscoveryEventUtils { * @return The group key which is used to uniquely identify the group * selected. */ - GroupKey getGroupKey() { + public GroupKey getGroupKey() { return groupKey; } @@ -356,7 +355,7 @@ final class DiscoveryEventUtils { * * @return The number of files in the group which was selected. */ - int getGroupSize() { + public int getGroupSize() { return groupSize; } @@ -365,7 +364,7 @@ final class DiscoveryEventUtils { * * @return The sorting algorithm used for groups. */ - FileGroup.GroupSortingAlgorithm getGroupSort() { + public FileGroup.GroupSortingAlgorithm getGroupSort() { return groupSort; } @@ -374,7 +373,7 @@ final class DiscoveryEventUtils { * * @return The sorting method used for files. */ - FileSorter.SortingMethod getFileSort() { + public FileSorter.SortingMethod getFileSort() { return fileSortMethod; } @@ -383,7 +382,7 @@ final class DiscoveryEventUtils { * * @return The search filters which were used by the search. */ - List getFilters() { + public List getFilters() { return Collections.unmodifiableList(searchfilters); } @@ -392,7 +391,7 @@ final class DiscoveryEventUtils { * * @return The grouping attribute used by the search. */ - FileSearch.AttributeType getGroupingAttr() { + public FileSearch.AttributeType getGroupingAttr() { return groupingAttribute; } @@ -401,7 +400,7 @@ final class DiscoveryEventUtils { /** * Event to signal that the visibility of the Details area should change. */ - static class DetailsVisibleEvent { + public static class DetailsVisibleEvent { private final boolean showDetailsArea; @@ -411,7 +410,7 @@ final class DiscoveryEventUtils { * @param isVisible True if the details area should be visible, false * otherwise. */ - DetailsVisibleEvent(boolean isVisible) { + public DetailsVisibleEvent(boolean isVisible) { showDetailsArea = isVisible; } @@ -420,7 +419,7 @@ final class DiscoveryEventUtils { * * @return True if the details area should be visible, false otherwise. */ - boolean isShowDetailsArea() { + public boolean isShowDetailsArea() { return showDetailsArea; } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java new file mode 100644 index 0000000000..d009ef0133 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java @@ -0,0 +1,341 @@ +/* + * Autopsy + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit 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 org.openide.util.NbBundle; + +/** + * Utility class for constructing keys for groups and searches. + */ +public class DiscoveryKeyUtils { + + /** + * The key used for grouping for each attribute type. + */ + public abstract static class GroupKey implements Comparable { + + /** + * 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 tag group + */ + static class FileTagGroupKey extends GroupKey { + + private final List 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 getTagNames() { + return Collections.unmodifiableList(tagNames); + } + + /** + * @return the tagNamesString + */ + String getTagNamesString() { + return tagNamesString; + } + } + + /** + * Default attribute used to make one group + */ + static class NoGroupingAttribute extends FileSearch.AttributeType { + + @Override + public GroupKey getGroupKey(ResultFile file) { + return new NoGroupingGroupKey(); + } + } + + /** + * 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; + } + } + + /** + * Represents a key for a specific search for a specific user. + */ + static class SearchKey implements Comparable { + + 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 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; + } + } + + /** + * Private constructor for GroupKeyUtils utility class. + */ + private DiscoveryKeyUtils() { + //private constructor in a utility class intentionally left blank + } +} diff --git a/Core/src/org/sleuthkit/autopsy/discovery/FileGroup.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileGroup.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/discovery/FileGroup.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/FileGroup.java index ad88550df6..173e9c63d1 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/FileGroup.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileGroup.java @@ -16,21 +16,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; /** * Class for storing files that belong to a particular group. */ -class FileGroup implements Comparable { +public class FileGroup implements Comparable { private final FileGroup.GroupSortingAlgorithm groupSortingType; - private final GroupKey groupKey; + private final DiscoveryKeyUtils.GroupKey groupKey; private final List files; private final String displayName; @@ -40,7 +39,7 @@ class FileGroup implements Comparable { * @param groupSortingType The method for sorting the 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.groupKey = groupKey; files = new ArrayList<>(); @@ -66,7 +65,7 @@ class FileGroup implements Comparable { * * @return The display name of the group. */ - String getDisplayName() { + public String getDisplayName() { return displayName; // NON-NLS } @@ -75,14 +74,14 @@ class FileGroup implements Comparable { * * @return The unique key for the group. */ - GroupKey getGroupKey() { + public DiscoveryKeyUtils.GroupKey getGroupKey() { return groupKey; } /** * Sort all the files in the group */ - void sortFiles(FileSorter sorter) { + public void sortFiles(FileSorter sorter) { Collections.sort(files, sorter); } @@ -142,7 +141,7 @@ class FileGroup implements Comparable { */ @Messages({"FileGroup.groupSortingAlgorithm.groupSize.text=Group Size", "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_SIZE(Bundle.FileGroup_groupSortingAlgorithm_groupSize_text()); // Sort from largest to smallest group @@ -169,7 +168,7 @@ class FileGroup implements Comparable { * * @return List of ResultFile objects */ - List getFiles() { + public List getFiles() { return Collections.unmodifiableList(files); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java similarity index 62% rename from Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java index 09dd98882c..aaac8304fb 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java @@ -16,27 +16,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; -import org.sleuthkit.autopsy.discovery.ui.VideoThumbnailsWrapper; -import org.sleuthkit.autopsy.discovery.ui.AbstractFilter; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.google.common.io.Files; -import java.awt.Image; -import java.awt.image.BufferedImage; -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.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -47,30 +35,15 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.logging.Level; -import javax.imageio.ImageIO; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; -import org.imgscalr.Scalr; -import org.netbeans.api.progress.ProgressHandle; -import org.opencv.core.Mat; -import org.opencv.highgui.VideoCapture; -import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; 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.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.FileSearchData.FileSize; -import org.sleuthkit.autopsy.discovery.FileSearchData.FileType; -import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.Frequency; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -81,29 +54,22 @@ 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.textextractors.TextExtractor; -import org.sleuthkit.autopsy.textextractors.TextExtractorFactory; +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; -import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; -import org.sleuthkit.autopsy.texttranslation.TextTranslationService; -import org.sleuthkit.autopsy.texttranslation.TranslationException; /** * Main class to perform the file search. */ -class FileSearch { +public class FileSearch { private final static Logger logger = Logger.getLogger(FileSearch.class.getName()); private static final int MAXIMUM_CACHE_SIZE = 10; - private static final String THUMBNAIL_FORMAT = "png"; //NON-NLS - private static final String VIDEO_THUMBNAIL_DIR = "video-thumbnails"; //NON-NLS private static final Cache>> searchCache = CacheBuilder.newBuilder() .maximumSize(MAXIMUM_CACHE_SIZE) .build(); - private static final int PREVIEW_SIZE = 256; - private static volatile TextSummarizer summarizerToUse = null; - private static final BufferedImage VIDEO_DEFAULT_IMAGE = getDefaultVideoThumbnail(); + /** * Run the file search and returns the SearchResults object for debugging. @@ -175,7 +141,7 @@ class FileSearch { * * @throws FileSearchException */ - static Map getGroupSizes(String userName, + public static Map getGroupSizes(String userName, List filters, AttributeType groupAttributeType, FileGroup.GroupSortingAlgorithm groupSortingType, @@ -212,7 +178,7 @@ class FileSearch { * * @throws FileSearchException */ - static List getFilesInGroup(String userName, + public static List getFilesInGroup(String userName, List filters, AttributeType groupAttributeType, FileGroup.GroupSortingAlgorithm groupSortingType, @@ -269,15 +235,12 @@ class FileSearch { */ @NbBundle.Messages({"FileSearch.documentSummary.noPreview=No preview available.", "FileSearch.documentSummary.noBytes=No bytes read for document, unable to display preview."}) - static TextSummary summarize(AbstractFile file) { + public static TextSummary summarize(AbstractFile file) { TextSummary summary = null; - TextSummarizer localSummarizer = summarizerToUse; - if (localSummarizer == null) { - synchronized (searchCache) { - if (localSummarizer == null) { - localSummarizer = getLocalSummarizer(); - } - } + TextSummarizer localSummarizer; + synchronized (searchCache) { + localSummarizer = SummaryHelpers.getLocalSummarizer(); + } if (localSummarizer != null) { try { @@ -289,184 +252,11 @@ class FileSearch { } if (summary == null || StringUtils.isBlank(summary.getSummaryText())) { //summary text was empty grab the beginning of the file - summary = getDefaultSummary(file); + summary = SummaryHelpers.getDefaultSummary(file); } return summary; } - private 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. - */ - private 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. - */ - private 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(); - 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. - */ - private 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. - */ - private 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 - */ - private static TextSummarizer getLocalSummarizer() { - Collection summarizers - = Lookup.getDefault().lookupAll(TextSummarizer.class - ); - if (!summarizers.isEmpty()) { - summarizerToUse = summarizers.iterator().next(); - return summarizerToUse; - } - return null; - } - /** * Run the file search. Caching new results for access at later time. * @@ -593,271 +383,6 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } - /** - * 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; - } - - /** - * 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", - "FileSearch.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.FileSearch_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 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); - } - } - - /** - * 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 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 createDefaultThumbnailList(BufferedImage failedVideoThumbImage) { - List videoThumbnails = new ArrayList<>(); - videoThumbnails.add(failedVideoThumbImage); - videoThumbnails.add(failedVideoThumbImage); - videoThumbnails.add(failedVideoThumbImage); - videoThumbnails.add(failedVideoThumbImage); - return videoThumbnails; - } - private FileSearch() { // Class should not be instantiated } @@ -865,7 +390,7 @@ class FileSearch { /** * Base class for the grouping attributes. */ - abstract static class AttributeType { + public abstract static class AttributeType { /** * For a given file, return the key for the group it belongs to for this @@ -875,7 +400,7 @@ class FileSearch { * * @return the key for the group this file goes in */ - abstract GroupKey getGroupKey(ResultFile file); + public abstract GroupKey getGroupKey(ResultFile file); /** * Add any extra data to the ResultFile object from this attribute. @@ -887,60 +412,12 @@ class FileSearch { * * @throws FileSearchException */ - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { + public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { // Default is to do nothing } } - /** - * The key used for grouping for each attribute type. - */ - abstract static class GroupKey implements Comparable { - - /** - * 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(); - } - } + /** * Attribute for grouping/sorting by file size @@ -948,75 +425,18 @@ class FileSearch { static class FileSizeAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new FileSizeGroupKey(file); } } - /** - * Key representing a file size group - */ - private static class FileSizeGroupKey extends GroupKey { - - private final FileSize fileSize; - - FileSizeGroupKey(ResultFile file) { - if (file.getFileType() == FileType.VIDEO) { - fileSize = FileSize.fromVideoSize(file.getFirstInstance().getSize()); - } else { - fileSize = 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 - */ - FileSize getFileSize() { - return fileSize; - } - } - /** * Attribute for grouping/sorting by parent path */ - static class ParentPathAttribute extends AttributeType { + public static class ParentPathAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new ParentPathGroupKey(file); } } @@ -1135,7 +555,7 @@ class FileSearch { static class DataSourceAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new DataSourceGroupKey(file); } } @@ -1215,7 +635,7 @@ class FileSearch { static class FileTypeAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new FileTypeGroupKey(file); } } @@ -1279,12 +699,12 @@ class FileSearch { static class KeywordListAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new KeywordListGroupKey(file); } @Override - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List 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 @@ -1434,12 +854,12 @@ class FileSearch { static final int BATCH_SIZE = 50; // Number of hashes to look up at one time @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new FrequencyGroupKey(file); } @Override - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { if (centralRepoDb == null) { for (ResultFile file : files) { @@ -1582,12 +1002,12 @@ class FileSearch { static class HashHitsAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new HashHitsGroupKey(file); } @Override - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List 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 @@ -1734,12 +1154,12 @@ class FileSearch { static class InterestingItemAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new InterestingItemGroupKey(file); } @Override - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List 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 @@ -1888,12 +1308,12 @@ class FileSearch { static class ObjectDetectedAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { + public GroupKey getGroupKey(ResultFile file) { return new ObjectDetectedGroupKey(file); } @Override - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List 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 @@ -2041,12 +1461,12 @@ class FileSearch { static class FileTagAttribute extends AttributeType { @Override - GroupKey getGroupKey(ResultFile file) { - return new FileTagGroupKey(file); + public GroupKey getGroupKey(ResultFile file) { + return new DiscoveryKeyUtils.FileTagGroupKey(file); } @Override - void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { try { @@ -2063,202 +1483,7 @@ class FileSearch { } } - /** - * Represents a key for a specific search for a specific user. - */ - private static class SearchKey implements Comparable { - 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 filters, - 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; - } - } - - /** - * Key representing a file tag group - */ - private static class FileTagGroupKey extends GroupKey { - - private final List tagNames; - private final String tagNamesString; - - @NbBundle.Messages({ - "FileSearch.FileTagGroupKey.noSets=None"}) - FileTagGroupKey(ResultFile file) { - tagNames = file.getTagNames(); - - if (tagNames.isEmpty()) { - tagNamesString = Bundle.FileSearch_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 getTagNames() { - return Collections.unmodifiableList(tagNames); - } - - /** - * @return the tagNamesString - */ - String getTagNamesString() { - return tagNamesString; - } - } - - /** - * Default attribute used to make one group - */ - static class NoGroupingAttribute extends AttributeType { - - @Override - GroupKey getGroupKey(ResultFile file) { - return new NoGroupingGroupKey(); - } - } - - /** - * Dummy key for when there is no grouping. All files will have the same - * key. - */ - private static class NoGroupingGroupKey extends GroupKey { - - NoGroupingGroupKey() { - // Nothing to save - all files will get the same GroupKey - } - - @NbBundle.Messages({ - "FileSearch.NoGroupingGroupKey.allFiles=All Files"}) - @Override - String getDisplayName() { - return Bundle.FileSearch_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; - } - } /** * Enum for the attribute types that can be used for grouping. @@ -2275,7 +1500,7 @@ class FileSearch { "FileSearch.GroupingAttributeType.tag.displayName=Tag", "FileSearch.GroupingAttributeType.object.displayName=Object Detected", "FileSearch.GroupingAttributeType.none.displayName=None"}) - enum GroupingAttributeType { + 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()), @@ -2285,7 +1510,7 @@ class FileSearch { 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()); + NO_GROUPING(new DiscoveryKeyUtils.NoGroupingAttribute(), Bundle.FileSearch_GroupingAttributeType_none_displayName()); private final AttributeType attributeType; private final String displayName; @@ -2300,7 +1525,7 @@ class FileSearch { return displayName; } - AttributeType getAttributeType() { + public AttributeType getAttributeType() { return attributeType; } @@ -2309,7 +1534,7 @@ class FileSearch { * * @return enums that can be used to group images */ - static List getOptionsForGrouping() { + public static List getOptionsForGrouping() { return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/FileSearchData.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearchData.java similarity index 93% rename from Core/src/org/sleuthkit/autopsy/discovery/FileSearchData.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/FileSearchData.java index a672930966..acd8fae2ea 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/FileSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearchData.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; import com.google.common.collect.ImmutableSet; import java.util.ArrayList; @@ -30,12 +30,12 @@ import org.sleuthkit.autopsy.coreutils.FileTypeUtils; /** * 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; @Override - ResultType getResultType() { + public ResultType getResultType() { return ResultType.FILE; } @@ -49,7 +49,7 @@ final class FileSearchData extends SearchData { "FileSearchData.Frequency.verycommon.displayName=Very Common (100+)", "FileSearchData.Frequency.known.displayName=Known (NSRL)", "FileSearchData.Frequency.unknown.displayName=Unknown",}) - enum Frequency { + public enum Frequency { UNIQUE(0, 1, Bundle.FileSearchData_Frequency_unique_displayName()), RARE(1, 10, Bundle.FileSearchData_Frequency_rare_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) */ - int getRanking() { + public int getRanking() { return ranking; } @@ -83,7 +83,7 @@ final class FileSearchData extends SearchData { * * @return the corresponding enum */ - static Frequency fromCount(long count) { + public static Frequency fromCount(long count) { if (count <= UNIQUE.getMaxOccur()) { return UNIQUE; } 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. */ - static List getOptionsForFilteringWithCr() { + public static List getOptionsForFilteringWithCr() { 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. */ - static List getOptionsForFilteringWithoutCr() { + public static List getOptionsForFilteringWithoutCr() { return Arrays.asList(KNOWN, UNKNOWN); } @@ -122,7 +122,7 @@ final class FileSearchData extends SearchData { /** * @return the maxOccur */ - int getMaxOccur() { + public int getMaxOccur() { return maxOccur; } } @@ -149,7 +149,7 @@ final class FileSearchData extends SearchData { "FileSearchData.FileSize.16kbto100kb=: 16-100KB", "FileSearchData.FileSize.upTo500kb=: 0-500KB", "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()), 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()), @@ -190,7 +190,7 @@ final class FileSearchData extends SearchData { * * @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()) { return XXLARGE_IMAGE; } else if (size > XLARGE_IMAGE.getMinBytes()) { @@ -214,7 +214,7 @@ final class FileSearchData extends SearchData { * * @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()) { return XXLARGE_VIDEO; } 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. */ - long getMaxBytes() { + public long getMaxBytes() { return maxBytes; } @@ -244,7 +244,7 @@ final class FileSearchData extends SearchData { * * @return the maximum file size that is not part of this range */ - long getMinBytes() { + public long getMinBytes() { return minBytes; } @@ -253,7 +253,7 @@ final class FileSearchData extends SearchData { * * @return the rank (lower should be displayed first) */ - int getRanking() { + public int getRanking() { return ranking; } @@ -262,7 +262,7 @@ final class FileSearchData extends SearchData { return sizeGroup + displaySize; } - String getSizeGroup() { + public String getSizeGroup() { return sizeGroup; } @@ -272,7 +272,7 @@ final class FileSearchData extends SearchData { * @return Enums that can be used to filter most file including images * by size. */ - static List getDefaultSizeOptions() { + public static List getDefaultSizeOptions() { 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. */ - static List getOptionsForVideos() { + public static List getOptionsForVideos() { 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 "application/xhtml+xml").build(); //NON-NLS - static Collection getDocTypesWithoutImageExtraction() { + public static Collection getDocTypesWithoutImageExtraction() { return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES); } @@ -331,7 +331,7 @@ final class FileSearchData extends SearchData { "FileSearchData.FileType.Documents.displayName=Documents", "FileSearchData.FileType.Executables.displayName=Executables", "FileSearchData.FileType.Other.displayName=Other/Unknown"}) - enum FileType { + public enum FileType { IMAGE(0, Bundle.FileSearchData_FileType_Image_displayName(), FileTypeUtils.FileTypeCategory.IMAGE.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 */ - Collection getMediaTypes() { + public Collection getMediaTypes() { return Collections.unmodifiableCollection(mediaTypes); } @@ -369,7 +369,7 @@ final class FileSearchData extends SearchData { * * @return the rank (lower should be displayed first) */ - int getRanking() { + public int getRanking() { return ranking; } @@ -380,7 +380,7 @@ final class FileSearchData extends SearchData { * * @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()) { if (type.getMediaTypes().contains(mimeType)) { return type; @@ -398,7 +398,7 @@ final class FileSearchData extends SearchData { "FileSearchData.Score.notable.displayName=Notable", "FileSearchData.Score.interesting.displayName=Interesting", "FileSearchData.Score.unknown.displayName=Unknown",}) - enum Score { + public enum Score { NOTABLE(0, Bundle.FileSearchData_Score_notable_displayName()), INTERESTING(1, Bundle.FileSearchData_Score_interesting_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) */ - int getRanking() { + public int getRanking() { return ranking; } @@ -425,7 +425,7 @@ final class FileSearchData extends SearchData { * * @return enums that can be used to filter */ - static List getOptionsForFiltering() { + public static List getOptionsForFiltering() { return Arrays.asList(NOTABLE, INTERESTING); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/FileSearchException.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearchException.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/discovery/FileSearchException.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/FileSearchException.java index df22e26488..a637bf43eb 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/FileSearchException.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearchException.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; /** * Exception type used for FileSearch. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/FileSorter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/discovery/FileSorter.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java index fc74dd5713..30064b5ce9 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/FileSorter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; import java.util.ArrayList; import java.util.Arrays; @@ -29,7 +29,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Class used to sort ResultFiles using the supplied method. */ -class FileSorter implements Comparator { +public class FileSorter implements Comparator { private final List> comparators = new ArrayList<>(); @@ -40,7 +40,7 @@ class FileSorter implements Comparator { * * @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 switch (method) { @@ -247,7 +247,7 @@ class FileSorter implements Comparator { "FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency", "FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names", "FileSorter.SortingMethod.fullPath.displayName=Full Path"}) - enum SortingMethod { + public enum SortingMethod { BY_FILE_NAME(new ArrayList<>(), Bundle.FileSorter_SortingMethod_filename_displayName()), // Sort alphabetically by file name BY_DATA_SOURCE(new ArrayList<>(), @@ -276,7 +276,7 @@ class FileSorter implements Comparator { return displayName; } - List getRequiredAttributes() { + public List getRequiredAttributes() { return Collections.unmodifiableList(requiredAttributes); } @@ -285,7 +285,7 @@ class FileSorter implements Comparator { * * @return enums that can be used to ordering images. */ - static List getOptionsForOrdering() { + public static List getOptionsForOrdering() { return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultFile.java b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/discovery/ResultFile.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java index 73d57ccf37..5d87a3cf07 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultFile.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java @@ -16,9 +16,9 @@ * See the License for the specific language governing permissions and * 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 java.util.ArrayList; 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. */ -class ResultFile { +public class ResultFile { private final static Logger logger = Logger.getLogger(ResultFile.class.getName()); private FileSearchData.Frequency frequency; @@ -59,7 +59,7 @@ class ResultFile { * * @param abstractFile */ - ResultFile(AbstractFile abstractFile) { + public ResultFile(AbstractFile abstractFile) { try { //call get uniquePath to cache the path abstractFile.getUniquePath(); @@ -86,7 +86,7 @@ class ResultFile { * * @return The Frequency enum */ - FileSearchData.Frequency getFrequency() { + public FileSearchData.Frequency getFrequency() { return frequency; } @@ -95,7 +95,7 @@ class ResultFile { * * @param frequency The frequency of the file as an enum */ - void setFrequency(FileSearchData.Frequency frequency) { + public void setFrequency(FileSearchData.Frequency frequency) { this.frequency = frequency; } @@ -105,7 +105,7 @@ class ResultFile { * * @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)) { deleted = false; } @@ -128,7 +128,7 @@ class ResultFile { * * @return The score of this ResultFile. */ - DataResultViewerTable.Score getScore() { + public DataResultViewerTable.Score getScore() { return currentScore; } @@ -137,7 +137,7 @@ class ResultFile { * * @return The score description of this ResultFile. */ - String getScoreDescription() { + public String getScoreDescription() { return scoreDescription; } @@ -147,7 +147,7 @@ class ResultFile { * * @return The deleted status of this ResultFile. */ - boolean isDeleted() { + public boolean isDeleted() { return deleted; } @@ -158,7 +158,7 @@ class ResultFile { * @return The list of AbstractFiles which have been identified as instances * of this file. */ - List getAllInstances() { + public List getAllInstances() { return Collections.unmodifiableList(instances); } @@ -167,7 +167,7 @@ class ResultFile { * * @return The FileType enum. */ - FileType getFileType() { + public FileType getFileType() { return fileType; } @@ -176,7 +176,7 @@ class ResultFile { * * @param keywordListName */ - void addKeywordListName(String keywordListName) { + public void addKeywordListName(String keywordListName) { if (!keywordListNames.contains(keywordListName)) { keywordListNames.add(keywordListName); } @@ -190,7 +190,7 @@ class ResultFile { * * @return the keyword list names that matched this file. */ - List getKeywordListNames() { + public List getKeywordListNames() { return Collections.unmodifiableList(keywordListNames); } @@ -199,7 +199,7 @@ class ResultFile { * * @param hashSetName */ - void addHashSetName(String hashSetName) { + public void addHashSetName(String hashSetName) { if (!hashSetNames.contains(hashSetName)) { hashSetNames.add(hashSetName); } @@ -213,7 +213,7 @@ class ResultFile { * * @return The hash set names that matched this file. */ - List getHashSetNames() { + public List getHashSetNames() { return Collections.unmodifiableList(hashSetNames); } @@ -222,7 +222,7 @@ class ResultFile { * * @param tagName */ - void addTagName(String tagName) { + public void addTagName(String tagName) { if (!tagNames.contains(tagName)) { tagNames.add(tagName); } @@ -236,7 +236,7 @@ class ResultFile { * * @return the tag names that matched this file. */ - List getTagNames() { + public List getTagNames() { return Collections.unmodifiableList(tagNames); } @@ -245,7 +245,7 @@ class ResultFile { * * @param interestingSetName */ - void addInterestingSetName(String interestingSetName) { + public void addInterestingSetName(String interestingSetName) { if (!interestingSetNames.contains(interestingSetName)) { interestingSetNames.add(interestingSetName); } @@ -259,7 +259,7 @@ class ResultFile { * * @return the interesting item set names that matched this file. */ - List getInterestingSetNames() { + public List getInterestingSetNames() { return Collections.unmodifiableList(interestingSetNames); } @@ -268,7 +268,7 @@ class ResultFile { * * @param objectDetectedName */ - void addObjectDetectedName(String objectDetectedName) { + public void addObjectDetectedName(String objectDetectedName) { if (!objectDetectedNames.contains(objectDetectedName)) { objectDetectedNames.add(objectDetectedName); } @@ -282,7 +282,7 @@ class ResultFile { * * @return the objects detected in this file. */ - List getObjectDetectedNames() { + public List getObjectDetectedNames() { return Collections.unmodifiableList(objectDetectedNames); } @@ -291,7 +291,7 @@ class ResultFile { * * @return the AbstractFile object */ - AbstractFile getFirstInstance() { + public AbstractFile getFirstInstance() { return instances.get(0); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SearchData.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/discovery/SearchData.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java index 4368de669b..6807e334dd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SearchData.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java @@ -16,17 +16,17 @@ * See the License for the specific language governing permissions and * 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 SearchData { +public interface SearchData { /** * Enum of the broad result type categories. */ - enum ResultType { + public enum ResultType { FILE, ATTRIBUTE; } @@ -34,6 +34,6 @@ abstract class SearchData { /** * Get the broad result type. */ - abstract ResultType getResultType(); + public abstract ResultType getResultType(); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java similarity index 89% rename from Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java index bf52e38563..fa2dd972fd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SearchFiltering.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java @@ -16,16 +16,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; -import org.sleuthkit.autopsy.discovery.ui.AbstractFilter; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; -import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize; -import org.sleuthkit.autopsy.discovery.FileSearchData.FileType; -import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency; -import org.sleuthkit.autopsy.discovery.FileSearchData.Score; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileSize; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.FileType; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.Frequency; +import org.sleuthkit.autopsy.discovery.search.FileSearchData.Score; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.SleuthkitCase; @@ -43,7 +42,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** * 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. @@ -126,7 +125,7 @@ class SearchFiltering { /** * A filter for specifying the file size */ - static class SizeFilter extends AbstractFilter { + public static class SizeFilter extends AbstractFilter { private final List fileSizes; @@ -135,12 +134,12 @@ class SearchFiltering { * * @param fileSizes the file sizes that should match */ - SizeFilter(List fileSizes) { + public SizeFilter(List fileSizes) { this.fileSizes = fileSizes; } @Override - String getWhereClause() { + public String getWhereClause() { String queryStr = ""; // NON-NLS for (FileSize size : fileSizes) { if (!queryStr.isEmpty()) { @@ -160,7 +159,7 @@ class SearchFiltering { "SearchFiltering.SizeFilter.desc=Size(s): {0}", "SearchFiltering.SizeFilter.or=, "}) @Override - String getDesc() { + public String getDesc() { String desc = ""; // NON-NLS for (FileSize size : fileSizes) { if (!desc.isEmpty()) { @@ -177,7 +176,7 @@ class SearchFiltering { * A utility class for the ParentFilter to store the search string and * whether it is a full path or a substring. */ - static class ParentSearchTerm { + public static class ParentSearchTerm { private final String searchStr; private final boolean fullPath; @@ -192,7 +191,7 @@ class SearchFiltering { * @param isIncluded True if the results must include the path, false if * 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.fullPath = isFullPath; this.included = isIncluded; @@ -203,7 +202,7 @@ class SearchFiltering { * * @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 if (isIncluded()) { if (isFullPath()) { @@ -244,21 +243,21 @@ class SearchFiltering { /** * @return the fullPath */ - boolean isFullPath() { + public boolean isFullPath() { return fullPath; } /** * @return the included */ - boolean isIncluded() { + public boolean isIncluded() { return included; } /** * @return the searchStr */ - String getSearchStr() { + public String getSearchStr() { return searchStr; } } @@ -266,7 +265,7 @@ class SearchFiltering { /** * 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 parentSearchTerms; @@ -275,12 +274,12 @@ class SearchFiltering { * * @param parentSearchTerms Full paths or substrings to filter on */ - ParentFilter(List parentSearchTerms) { + public ParentFilter(List parentSearchTerms) { this.parentSearchTerms = parentSearchTerms; } @Override - String getWhereClause() { + public String getWhereClause() { String includeQueryStr = ""; // NON-NLS String excludeQueryStr = ""; for (ParentSearchTerm searchTerm : parentSearchTerms) { @@ -318,7 +317,7 @@ class SearchFiltering { "SearchFiltering.ParentFilter.included=(included)", "SearchFiltering.ParentFilter.excluded=(excluded)"}) @Override - String getDesc() { + public String getDesc() { String desc = ""; // NON-NLS for (ParentSearchTerm searchTerm : parentSearchTerms) { if (!desc.isEmpty()) { @@ -343,7 +342,7 @@ class SearchFiltering { /** * A filter for specifying data sources */ - static class DataSourceFilter extends AbstractFilter { + public static class DataSourceFilter extends AbstractFilter { private final List dataSources; @@ -352,12 +351,12 @@ class SearchFiltering { * * @param dataSources the data sources to filter on */ - DataSourceFilter(List dataSources) { + public DataSourceFilter(List dataSources) { this.dataSources = dataSources; } @Override - String getWhereClause() { + public String getWhereClause() { String queryStr = ""; // NON-NLS for (DataSource ds : dataSources) { if (!queryStr.isEmpty()) { @@ -377,7 +376,7 @@ class SearchFiltering { "# {1} - Data source ID", "SearchFiltering.DataSourceFilter.datasource={0}({1})",}) @Override - String getDesc() { + public String getDesc() { String desc = ""; // NON-NLS for (DataSource ds : dataSources) { if (!desc.isEmpty()) { @@ -394,7 +393,7 @@ class SearchFiltering { * A filter for specifying keyword list names. A file must contain a keyword * from one of the given lists to pass. */ - static class KeywordListFilter extends AbstractFilter { + public static class KeywordListFilter extends AbstractFilter { private final List listNames; @@ -403,12 +402,12 @@ class SearchFiltering { * * @param listNames */ - KeywordListFilter(List listNames) { + public KeywordListFilter(List listNames) { this.listNames = listNames; } @Override - String getWhereClause() { + public String getWhereClause() { String keywordListPart = concatenateNamesForSQL(listNames); String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN " @@ -422,7 +421,7 @@ class SearchFiltering { "# {0} - filters", "SearchFiltering.KeywordListFilter.desc=Keywords in list(s): {0}",}) @Override - String getDesc() { + public String getDesc() { return Bundle.SearchFiltering_KeywordListFilter_desc(concatenateSetNamesForDisplay(listNames)); } } @@ -430,7 +429,7 @@ class SearchFiltering { /** * A filter for specifying file types. */ - static class FileTypeFilter extends AbstractFilter { + public static class FileTypeFilter extends AbstractFilter { private final List categories; @@ -439,7 +438,7 @@ class SearchFiltering { * * @param categories List of file types to filter on */ - FileTypeFilter(List categories) { + public FileTypeFilter(List categories) { this.categories = categories; } @@ -448,13 +447,13 @@ class SearchFiltering { * * @param category the file type to filter on */ - FileTypeFilter(FileType category) { + public FileTypeFilter(FileType category) { this.categories = new ArrayList<>(); this.categories.add(category); } @Override - String getWhereClause() { + public String getWhereClause() { String queryStr = ""; // NON-NLS for (FileType cat : categories) { for (String type : cat.getMediaTypes()) { @@ -473,7 +472,7 @@ class SearchFiltering { "SearchFiltering.FileTypeFilter.desc=Type: {0}", "SearchFiltering.FileTypeFilter.or=, ",}) @Override - String getDesc() { + public String getDesc() { String desc = ""; for (FileType cat : categories) { if (!desc.isEmpty()) { @@ -489,7 +488,7 @@ class SearchFiltering { /** * A filter for specifying frequency in the central repository. */ - static class FrequencyFilter extends AbstractFilter { + public static class FrequencyFilter extends AbstractFilter { private final List frequencies; @@ -498,24 +497,24 @@ class SearchFiltering { * * @param frequencies List of frequencies that will pass the filter */ - FrequencyFilter(List frequencies) { + public FrequencyFilter(List frequencies) { this.frequencies = frequencies; } @Override - String getWhereClause() { + public String getWhereClause() { // Since this relies on the central repository database, there is no // query on the case database. return ""; // NON-NLS } @Override - boolean useAlternateFilter() { + public boolean useAlternateFilter() { return true; } @Override - List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, + public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { // We have to have run some kind of SQL filter before getting to this point, @@ -543,7 +542,7 @@ class SearchFiltering { "SearchFiltering.FrequencyFilter.desc=Past occurrences: {0}", "SearchFiltering.FrequencyFilter.or=, ",}) @Override - String getDesc() { + public String getDesc() { String desc = ""; // NON-NLS for (Frequency freq : frequencies) { if (!desc.isEmpty()) { @@ -559,7 +558,7 @@ class SearchFiltering { * A filter for specifying hash set names. A file must match one of the * given sets to pass. */ - static class HashSetFilter extends AbstractFilter { + public static class HashSetFilter extends AbstractFilter { private final List setNames; @@ -568,12 +567,12 @@ class SearchFiltering { * * @param setNames */ - HashSetFilter(List setNames) { + public HashSetFilter(List setNames) { this.setNames = setNames; } @Override - String getWhereClause() { + public String getWhereClause() { String hashSetPart = concatenateNamesForSQL(setNames); String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN " @@ -588,7 +587,7 @@ class SearchFiltering { "# {0} - filters", "FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}",}) @Override - String getDesc() { + public String getDesc() { return Bundle.FileSearchFiltering_HashSetFilter_desc(concatenateSetNamesForDisplay(setNames)); } } @@ -597,7 +596,7 @@ class SearchFiltering { * A filter for specifying interesting file set names. A file must match one * of the given sets to pass. */ - static class InterestingFileSetFilter extends AbstractFilter { + public static class InterestingFileSetFilter extends AbstractFilter { private final List setNames; @@ -606,12 +605,12 @@ class SearchFiltering { * * @param setNames */ - InterestingFileSetFilter(List setNames) { + public InterestingFileSetFilter(List setNames) { this.setNames = setNames; } @Override - String getWhereClause() { + public String getWhereClause() { String intItemSetPart = concatenateNamesForSQL(setNames); String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN " @@ -626,7 +625,7 @@ class SearchFiltering { "# {0} - filters", "SearchFiltering.InterestingItemSetFilter.desc=Interesting item hits in set(s): {0}",}) @Override - String getDesc() { + public String getDesc() { return Bundle.SearchFiltering_InterestingItemSetFilter_desc(concatenateSetNamesForDisplay(setNames)); } } @@ -635,7 +634,7 @@ class SearchFiltering { * A filter for specifying object types detected. A file must match one of * the given types to pass. */ - static class ObjectDetectionFilter extends AbstractFilter { + public static class ObjectDetectionFilter extends AbstractFilter { private final List typeNames; @@ -644,12 +643,12 @@ class SearchFiltering { * * @param typeNames */ - ObjectDetectionFilter(List typeNames) { + public ObjectDetectionFilter(List typeNames) { this.typeNames = typeNames; } @Override - String getWhereClause() { + public String getWhereClause() { String objTypePart = concatenateNamesForSQL(typeNames); String queryStr = "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN " @@ -664,7 +663,7 @@ class SearchFiltering { "# {0} - filters", "SearchFiltering.ObjectDetectionFilter.desc=Objects detected in set(s): {0}",}) @Override - String getDesc() { + public String getDesc() { return Bundle.SearchFiltering_ObjectDetectionFilter_desc(concatenateSetNamesForDisplay(typeNames)); } } @@ -673,7 +672,7 @@ class SearchFiltering { * A filter for specifying the score. A file must have one of the given * scores to pass */ - static class ScoreFilter extends AbstractFilter { + public static class ScoreFilter extends AbstractFilter { private final List scores; @@ -682,12 +681,12 @@ class SearchFiltering { * * @param typeNames */ - ScoreFilter(List scores) { + public ScoreFilter(List scores) { this.scores = scores; } @Override - String getWhereClause() { + public String getWhereClause() { // Current algorithm: // "Notable" if the file is a match for a notable hashset or has been tagged with a notable tag. @@ -740,7 +739,7 @@ class SearchFiltering { "# {0} - filters", "SearchFiltering.ScoreFilter.desc=Score(s) of : {0}",}) @Override - String getDesc() { + public String getDesc() { return Bundle.SearchFiltering_ScoreFilter_desc( concatenateSetNamesForDisplay(scores.stream().map(p -> p.toString()).collect(Collectors.toList()))); } @@ -750,7 +749,7 @@ class SearchFiltering { * A filter for specifying tag names. A file must contain one of the given * tags to pass. */ - static class TagsFilter extends AbstractFilter { + public static class TagsFilter extends AbstractFilter { private final List tagNames; @@ -759,12 +758,12 @@ class SearchFiltering { * * @param tagNames */ - TagsFilter(List tagNames) { + public TagsFilter(List tagNames) { this.tagNames = tagNames; } @Override - String getWhereClause() { + public String getWhereClause() { String tagIDs = ""; // NON-NLS for (TagName tagName : tagNames) { if (!tagIDs.isEmpty()) { @@ -783,7 +782,7 @@ class SearchFiltering { "FileSearchFiltering.TagsFilter.desc=Tagged {0}", "FileSearchFiltering.TagsFilter.or=, ",}) @Override - String getDesc() { + public String getDesc() { String desc = ""; // NON-NLS for (TagName name : tagNames) { if (!desc.isEmpty()) { @@ -799,17 +798,10 @@ class SearchFiltering { * A filter for specifying that the file must have user content suspected * data. */ - static class UserCreatedFilter extends AbstractFilter { - - /** - * Create the ExifFilter - */ - UserCreatedFilter() { - // Nothing to save - } + public static class UserCreatedFilter extends AbstractFilter { @Override - String getWhereClause() { + public String getWhereClause() { return "(obj_id IN (SELECT obj_id from blackboard_artifacts WHERE artifact_id IN " + "(SELECT artifact_id FROM blackboard_attributes WHERE artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() + ")))"; @@ -818,7 +810,7 @@ class SearchFiltering { @NbBundle.Messages({ "FileSearchFiltering.UserCreatedFilter.desc=that contain EXIF data",}) @Override - String getDesc() { + public String getDesc() { return Bundle.FileSearchFiltering_UserCreatedFilter_desc(); } } @@ -827,29 +819,22 @@ class SearchFiltering { * A filter for specifying that the file must have been marked as notable in * the CR. */ - static class NotableFilter extends AbstractFilter { - - /** - * Create the NotableFilter - */ - NotableFilter() { - // Nothing to save - } + public static class NotableFilter extends AbstractFilter { @Override - String getWhereClause() { + public String getWhereClause() { // Since this relies on the central repository database, there is no // query on the case database. return ""; // NON-NLS } @Override - boolean useAlternateFilter() { + public boolean useAlternateFilter() { return true; } @Override - List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, + public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws FileSearchException { if (centralRepoDb == null) { @@ -887,7 +872,7 @@ class SearchFiltering { @NbBundle.Messages({ "FileSearchFiltering.PreviouslyNotableFilter.desc=that were previously marked as notable",}) @Override - String getDesc() { + public String getDesc() { return Bundle.FileSearchFiltering_PreviouslyNotableFilter_desc(); } } @@ -895,17 +880,17 @@ class SearchFiltering { /** * A filter for specifying if known files should be included. */ - static class KnownFilter extends AbstractFilter { + public static class KnownFilter extends AbstractFilter { @Override - String getWhereClause() { + public String getWhereClause() { return "known!=" + TskData.FileKnown.KNOWN.getFileKnownValue(); // NON-NLS } @NbBundle.Messages({ "FileSearchFiltering.KnownFilter.desc=which are not known"}) @Override - String getDesc() { + public String getDesc() { return Bundle.FileSearchFiltering_KnownFilter_desc(); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/SearchResults.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/discovery/SearchResults.java rename to Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java index 29e6eb924d..6484fbf5ae 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/SearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.discovery; +package org.sleuthkit.autopsy.discovery.search; import java.util.ArrayList; import java.util.Collections; @@ -25,7 +25,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; 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. @@ -36,7 +36,7 @@ class SearchResults { private final FileSearch.AttributeType attrType; private final FileSorter fileSorter; - private final Map groupMap = new HashMap<>(); + private final Map groupMap = new HashMap<>(); private List groupList = new ArrayList<>(); 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 files) { for (ResultFile file : files) { // 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)) { groupMap.put(groupKey, new FileGroup(groupSortingType, groupKey)); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java new file mode 100644 index 0000000000..60e7e171ca --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java @@ -0,0 +1,236 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit 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 summarizers + = Lookup.getDefault().lookupAll(TextSummarizer.class + ); + if (!summarizers.isEmpty()) { + summarizerToUse = summarizers.iterator().next(); + } + } + return summarizerToUse; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java index 2be3071af6..d3770ef5ac 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.awt.event.ActionListener; import javax.swing.JCheckBox; import javax.swing.JLabel; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java index eb7d0de8c8..20273e6ae7 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -31,10 +32,10 @@ import javax.swing.JSplitPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.apache.commons.lang3.StringUtils; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.SearchData; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +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 diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java index c7691cb2b0..4430d793ab 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java @@ -18,11 +18,12 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.search.AttributeSearchData; import org.sleuthkit.datamodel.BlackboardArtifact; /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED similarity index 100% rename from Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties-MERGED rename to Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java index 6321afa357..f9b4ab9d27 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; import java.util.stream.Collectors; @@ -27,7 +28,7 @@ import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java index 170aec7acf..b1981d22aa 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceModulesWrapper.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.discovery.ui; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.discovery.Bundle; import org.sleuthkit.autopsy.modules.exif.ExifParserModuleFactory; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory; import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupModuleFactory; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java index 1776e862d4..cf78c5fe7d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java @@ -18,13 +18,13 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.SpinnerNumberModel; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.communications.Utils; -import org.sleuthkit.autopsy.discovery.Bundle; /** * Filter panel for allowing the user to filter on date. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java index 9b30ef3383..1ec4cd26a1 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java @@ -40,7 +40,7 @@ import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java index 977a6fa046..0135ad651c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import static java.awt.BorderLayout.CENTER; import java.awt.Color; import java.beans.PropertyChangeEvent; @@ -36,25 +37,24 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; -import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; -import org.sleuthkit.autopsy.discovery.FileGroup; -import org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm; -import org.sleuthkit.autopsy.discovery.FileSearch; -import static org.sleuthkit.autopsy.discovery.FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.FileSorter; -import static org.sleuthkit.autopsy.discovery.FileSearch.GroupingAttributeType.PARENT_PATH; -import org.sleuthkit.autopsy.discovery.FileSorter.SortingMethod; -import org.sleuthkit.autopsy.discovery.SearchData; +import org.sleuthkit.autopsy.discovery.search.AttributeSearchData; +import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.search.FileGroup; +import org.sleuthkit.autopsy.discovery.search.FileGroup.GroupSortingAlgorithm; +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.ModuleDataEvent; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; 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 diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form index 4a1f471190..7917b19a1e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form @@ -106,7 +106,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java index 010a086b30..30a6a3a49a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import com.google.common.eventbus.Subscribe; import java.awt.BorderLayout; import java.awt.Color; @@ -36,9 +37,8 @@ import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.coreutils.ThreadConfined; -import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; -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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java index 72b0d5db3b..1e27e4e939 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java @@ -18,27 +18,43 @@ */ 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 org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.ResultFile; +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; @@ -62,6 +78,9 @@ final class DiscoveryUiUtils { 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", @@ -166,10 +185,11 @@ final class DiscoveryUiUtils { * 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.ImageThumbnailPanel_isDeleted_text()); + isDeletedLabel.setToolTipText(Bundle.DiscoveryUiUtils_isDeleted_text()); } else { isDeletedLabel.setIcon(null); isDeletedLabel.setToolTipText(null); @@ -246,6 +266,272 @@ final class DiscoveryUiUtils { 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 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 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 createDefaultThumbnailList(BufferedImage failedVideoThumbImage) { + List videoThumbnails = new ArrayList<>(); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + return videoThumbnails; + } + /** * Private constructor for DiscoveryUiUtils utility class. */ diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java index 29e29972bd..9c2e5565a1 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentFilterPanel.java @@ -19,9 +19,9 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.SearchData; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java index 78d88e9cb7..68c15ce260 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentPanel.java @@ -29,8 +29,7 @@ import javax.swing.JList; import javax.swing.ListCellRenderer; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane; -import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.search.FileSearchData; /** * Class which displays a preview and details about a document. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentWrapper.java index fb93cc9bd1..1ea0df4ba4 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DocumentWrapper.java @@ -19,8 +19,7 @@ package org.sleuthkit.autopsy.discovery.ui; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.ResultFile; +import org.sleuthkit.autopsy.discovery.search.ResultFile; import org.sleuthkit.autopsy.textsummarizer.TextSummary; /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java index 05e0907935..086a249305 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java @@ -19,9 +19,9 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.SearchData; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java index 46de95137c..dad5c1e819 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import com.google.common.eventbus.Subscribe; import java.awt.Cursor; import java.util.List; @@ -28,13 +29,12 @@ import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; -import org.sleuthkit.autopsy.discovery.FileGroup; -import org.sleuthkit.autopsy.discovery.FileSearch; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; -import org.sleuthkit.autopsy.discovery.FileSearchData.FileType; -import org.sleuthkit.autopsy.discovery.FileSorter; +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.FileType; +import org.sleuthkit.autopsy.discovery.search.FileSorter; /** * Panel to display the list of groups which are provided by a search. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java index 1703737c1c..a890edcd4e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; import javax.swing.DefaultListModel; @@ -25,7 +26,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java index 8008b9a41f..be0419bbd8 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageFilterPanel.java @@ -19,9 +19,9 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.SearchData; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java index 88c2eb9526..d294fa866d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailPanel.java @@ -28,7 +28,6 @@ import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.discovery.Bundle; /** * Class which displays a thumbnail and information for an image file. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java index 2dc072b175..67b7e2dab0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ImageThumbnailWrapper.java @@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.discovery.ui; import java.awt.Image; import org.sleuthkit.autopsy.coreutils.ImageUtils; -import org.sleuthkit.autopsy.discovery.ResultFile; +import org.sleuthkit.autopsy.discovery.search.ResultFile; /** * Class to wrap all the information necessary for an image thumbnail to be diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java index 1106391d9b..0d102141f0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; import javax.swing.DefaultListModel; @@ -25,7 +26,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java index 4dacc11d55..09cc912e69 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; import javax.swing.DefaultListModel; @@ -25,7 +26,7 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java index d1982ab364..74fb716425 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java @@ -31,7 +31,6 @@ import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.Presenter; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.discovery.Bundle; /** * Class to open the Discovery dialog. Allows the user to run searches and see diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java index f9c5415294..2372f01788 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java @@ -18,21 +18,22 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.ArrayList; import java.util.logging.Level; import javax.swing.SwingWorker; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; -import org.sleuthkit.autopsy.discovery.FileGroup; -import org.sleuthkit.autopsy.discovery.FileSearch; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchException; -import org.sleuthkit.autopsy.discovery.FileSorter; -import org.sleuthkit.autopsy.discovery.ResultFile; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java index 841dd910bc..97015abc92 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java @@ -18,14 +18,15 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.ArrayList; import java.util.List; import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; -import org.sleuthkit.autopsy.discovery.SearchFiltering; -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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java index 20fead3473..53a2c48407 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java @@ -23,10 +23,6 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency; -import org.sleuthkit.autopsy.discovery.SearchData.ResultType; -import org.sleuthkit.autopsy.discovery.SearchFiltering; /** * Panel to allow configuration of the Past Occurrences filter. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java index e2686c58eb..9cd9cbd78a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import com.google.common.eventbus.Subscribe; import java.awt.Cursor; import java.awt.Image; @@ -35,16 +36,15 @@ import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.Bundle; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; -import org.sleuthkit.autopsy.discovery.FileGroup; -import org.sleuthkit.autopsy.discovery.FileSearch; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.FileSorter; -import org.sleuthkit.autopsy.discovery.ResultFile; +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; /** @@ -653,7 +653,7 @@ final class ResultsPanel extends javax.swing.JPanel { @Override protected Void doInBackground() throws Exception { - FileSearch.getVideoThumbnails(thumbnailWrapper); + DiscoveryUiUtils.getVideoThumbnails(thumbnailWrapper); return null; } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java index 6243416325..251ed4cb94 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.discovery.ui; import java.awt.Cursor; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; +import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; /** * Panel for separating the results list from the details area. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java index ea14294d95..0013d610dd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SearchWorker.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.LinkedHashMap; import javax.swing.SwingWorker; import java.util.List; @@ -25,13 +26,13 @@ import java.util.Map; import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.DiscoveryEventUtils; -import org.sleuthkit.autopsy.discovery.FileGroup; -import org.sleuthkit.autopsy.discovery.FileSearch; -import org.sleuthkit.autopsy.discovery.FileSearchException; -import org.sleuthkit.autopsy.discovery.FileSorter; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java index 8ca29f0018..65c5330da5 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java @@ -18,15 +18,16 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.ArrayList; import java.util.List; import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData.FileSize; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java index 5d421a0b0d..d65596633a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java @@ -18,10 +18,11 @@ */ package org.sleuthkit.autopsy.discovery.ui; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +import org.sleuthkit.autopsy.discovery.search.SearchFiltering; /** * Panel to allow configuration of the User Created Filter. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java index d1388a45ba..c002fe322f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoFilterPanel.java @@ -19,9 +19,9 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.AttributeSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.SearchData; +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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java index 609904ee2a..7a62937582 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailPanel.java @@ -32,7 +32,6 @@ import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.discovery.Bundle; /** * Class which displays thumbnails and information for a video file. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java index 429b26d926..6b312bab36 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/VideoThumbnailsWrapper.java @@ -22,7 +22,7 @@ import java.awt.Image; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.sleuthkit.autopsy.discovery.ResultFile; +import org.sleuthkit.autopsy.discovery.search.ResultFile; /** * Class to wrap all the information necessary for video thumbnails to be From 1b25df8973a6867552f39a333da6c17cceeafef7 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 13:43:30 -0400 Subject: [PATCH 03/10] 6610 update casemodule import for discovery --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 8ada5fa596..275e502b8c 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -107,7 +107,7 @@ import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEventException; 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.IngestManager; import org.sleuthkit.autopsy.ingest.IngestServices; From 991de39fbfdca1bb48197c3cee536367409c1736 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 13:50:12 -0400 Subject: [PATCH 04/10] 6610 fix imports and typo --- .../autopsy/discovery/ui/ArtifactTypeFilterPanel.java | 2 +- Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java | 1 - .../autopsy/discovery/ui/PastOccurrencesFilterPanel.java | 4 ++++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java index 4430d793ab..9771c8ab81 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java @@ -27,7 +27,7 @@ import org.sleuthkit.autopsy.discovery.search.AttributeSearchData; 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 { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java index 1ec4cd26a1..e302669278 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DetailsPanel.java @@ -39,7 +39,6 @@ import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; -import org.sleuthkit.autopsy.discovery.Bundle; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java index 53a2c48407..20fead3473 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java @@ -23,6 +23,10 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.FileSearchData; +import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency; +import org.sleuthkit.autopsy.discovery.SearchData.ResultType; +import org.sleuthkit.autopsy.discovery.SearchFiltering; /** * Panel to allow configuration of the Past Occurrences filter. From 8b6fef749733752457cc2b60412aa05a4b8448e6 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 14:15:12 -0400 Subject: [PATCH 05/10] 6610 move additional group keys out of filesearch class --- .../discovery/search/Bundle.properties-MERGED | 115 +++ .../discovery/search/DiscoveryKeyUtils.java | 683 +++++++++++++++++- .../autopsy/discovery/search/FileSearch.java | 635 +--------------- .../discovery/ui/Bundle.properties-MERGED | 265 ++----- .../ui/PastOccurrencesFilterPanel.java | 9 +- 5 files changed, 823 insertions(+), 884 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/discovery/search/Bundle.properties-MERGED diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle.properties-MERGED new file mode 100644 index 0000000000..9924fbae02 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/Bundle.properties-MERGED @@ -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=, diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java index d009ef0133..118dd6e815 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java @@ -21,13 +21,83 @@ 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 { + + 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 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. */ @@ -78,7 +148,7 @@ public class DiscoveryKeyUtils { } } - /** + /** * Key representing a file size group */ static class FileSizeGroupKey extends GroupKey { @@ -134,7 +204,141 @@ public class DiscoveryKeyUtils { 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 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 getKeywordListNames() { + return Collections.unmodifiableList(keywordListNames); + } + + /** + * @return the keywordListNamesString + */ + String getKeywordListNamesString() { + return keywordListNamesString; + } + } + /** * Key representing a file tag group */ @@ -217,13 +421,179 @@ public class DiscoveryKeyUtils { } /** - * Default attribute used to make one group + * Key representing a parent path group */ - static class NoGroupingAttribute extends FileSearch.AttributeType { + 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 - public GroupKey getGroupKey(ResultFile file) { - return new NoGroupingGroupKey(); + 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; } } @@ -270,37 +640,29 @@ public class DiscoveryKeyUtils { } /** - * Represents a key for a specific search for a specific user. + * Key representing a central repository frequency group */ - static class SearchKey implements Comparable { + static class FrequencyGroupKey extends GroupKey { - private final String keyString; + private final FileSearchData.Frequency frequency; - /** - * 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 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(); + FrequencyGroupKey(ResultFile file) { + frequency = file.getFrequency(); } @Override - public int compareTo(SearchKey otherSearchKey) { - return getKeyString().compareTo(otherSearchKey.getKeyString()); + 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 @@ -309,26 +671,267 @@ public class DiscoveryKeyUtils { return true; } - if (!(otherKey instanceof SearchKey)) { + if (!(otherKey instanceof FrequencyGroupKey)) { return false; } - SearchKey otherSearchKey = (SearchKey) otherKey; - return getKeyString().equals(otherSearchKey.getKeyString()); + FrequencyGroupKey otherFrequencyGroupKey = (FrequencyGroupKey) otherKey; + return getFrequency().equals(otherFrequencyGroupKey.getFrequency()); } @Override public int hashCode() { - int hash = 5; - hash = 79 * hash + Objects.hashCode(getKeyString()); - return hash; + return Objects.hash(getFrequency().getRanking()); } /** - * @return the keyString + * @return the frequency */ - String getKeyString() { - return keyString; + FileSearchData.Frequency getFrequency() { + return frequency; + } + } + + /** + * Key representing a hash hits group + */ + static class HashHitsGroupKey extends GroupKey { + + private final List 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 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 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 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 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 getObjectDetectedNames() { + return Collections.unmodifiableList(objectDetectedNames); + } + + /** + * @return the objectDetectedNamesString + */ + String getObjectDetectedNamesString() { + return objectDetectedNamesString; } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java index aaac8304fb..1ba77545de 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java @@ -25,14 +25,12 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; 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.Objects; import java.util.Set; import java.util.logging.Level; import org.apache.commons.lang.StringUtils; @@ -42,13 +40,11 @@ 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.FileType; 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.Content; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; @@ -70,7 +66,6 @@ public class FileSearch { .maximumSize(MAXIMUM_CACHE_SIZE) .build(); - /** * Run the file search and returns the SearchResults object for debugging. * Caching new results for access at later time. @@ -237,7 +232,7 @@ public class FileSearch { "FileSearch.documentSummary.noBytes=No bytes read for document, unable to display preview."}) public static TextSummary summarize(AbstractFile file) { TextSummary summary = null; - TextSummarizer localSummarizer; + TextSummarizer localSummarizer; synchronized (searchCache) { localSummarizer = SummaryHelpers.getLocalSummarizer(); @@ -417,16 +412,14 @@ public class FileSearch { } } - - /** * Attribute for grouping/sorting by file size */ - static class FileSizeAttribute extends AttributeType { + public static class FileSizeAttribute extends AttributeType { @Override public GroupKey getGroupKey(ResultFile file) { - return new FileSizeGroupKey(file); + return new DiscoveryKeyUtils.FileSizeGroupKey(file); } } @@ -437,115 +430,18 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new ParentPathGroupKey(file); + return new DiscoveryKeyUtils.ParentPathGroupKey(file); } } /** - * Key representing a parent path group + * Default attribute used to make one group */ - private 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; - } - } + static class NoGroupingAttribute extends FileSearch.AttributeType { @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; + public GroupKey getGroupKey(ResultFile file) { + return new DiscoveryKeyUtils.NoGroupingGroupKey(); } } @@ -556,76 +452,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new DataSourceGroupKey(file); - } - } - - /** - * Key representing a data source group - */ - private 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; + return new DiscoveryKeyUtils.DataSourceGroupKey(file); } } @@ -636,60 +463,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new FileTypeGroupKey(file); - } - } - - /** - * Key representing a file type group - */ - private static class FileTypeGroupKey extends GroupKey { - - private final 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 - */ - FileType getFileType() { - return fileType; + return new DiscoveryKeyUtils.FileTypeGroupKey(file); } } @@ -700,7 +474,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new KeywordListGroupKey(file); + return new DiscoveryKeyUtils.KeywordListGroupKey(file); } @Override @@ -765,87 +539,6 @@ public class FileSearch { } } - /** - * Key representing a keyword list group - */ - private static class KeywordListGroupKey extends GroupKey { - - private final List 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 getKeywordListNames() { - return Collections.unmodifiableList(keywordListNames); - } - - /** - * @return the keywordListNamesString - */ - String getKeywordListNamesString() { - return keywordListNamesString; - } - } - /** * Attribute for grouping/sorting by frequency in the central repository */ @@ -855,7 +548,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new FrequencyGroupKey(file); + return new DiscoveryKeyUtils.FrequencyGroupKey(file); } @Override @@ -943,59 +636,6 @@ public class FileSearch { } } - /** - * Key representing a central repository frequency group - */ - private static class FrequencyGroupKey extends GroupKey { - - private final 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 - */ - Frequency getFrequency() { - return frequency; - } - } - /** * Attribute for grouping/sorting by hash set lists */ @@ -1003,7 +643,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new HashHitsGroupKey(file); + return new DiscoveryKeyUtils.HashHitsGroupKey(file); } @Override @@ -1067,87 +707,6 @@ public class FileSearch { } } - /** - * Key representing a hash hits group - */ - private static class HashHitsGroupKey extends GroupKey { - - private final List 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 getHashSetNames() { - return Collections.unmodifiableList(hashSetNames); - } - - /** - * @return the hashSetNamesString - */ - String getHashSetNamesString() { - return hashSetNamesString; - } - } - /** * Attribute for grouping/sorting by interesting item set lists */ @@ -1155,7 +714,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new InterestingItemGroupKey(file); + return new DiscoveryKeyUtils.InterestingItemGroupKey(file); } @Override @@ -1221,87 +780,6 @@ public class FileSearch { } } - /** - * Key representing a interesting item set group - */ - private static class InterestingItemGroupKey extends GroupKey { - - private final List 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 getInterestingItemSetNames() { - return Collections.unmodifiableList(interestingItemSetNames); - } - - /** - * @return the interestingItemSetNamesString - */ - String getInterestingItemSetNamesString() { - return interestingItemSetNamesString; - } - } - /** * Attribute for grouping/sorting by objects detected */ @@ -1309,7 +787,7 @@ public class FileSearch { @Override public GroupKey getGroupKey(ResultFile file) { - return new ObjectDetectedGroupKey(file); + return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file); } @Override @@ -1374,87 +852,6 @@ public class FileSearch { } } - /** - * Key representing an object detected group - */ - private static class ObjectDetectedGroupKey extends GroupKey { - - private final List 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 getObjectDetectedNames() { - return Collections.unmodifiableList(objectDetectedNames); - } - - /** - * @return the objectDetectedNamesString - */ - String getObjectDetectedNamesString() { - return objectDetectedNamesString; - } - } - /** * Attribute for grouping/sorting by tag name */ @@ -1483,8 +880,6 @@ public class FileSearch { } } - - /** * Enum for the attribute types that can be used for grouping. */ diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED index 39b573d24f..2de9ea3e1f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED @@ -1,5 +1,7 @@ -AttributeSearchData.AttributeType.Domain.displayName=Domain -AttributeSearchData.AttributeType.Other.displayName=Other +# 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. + CTL_OpenDiscoveryAction=Discovery # {0} - dataSourceName DataSourceModuleWrapper.exifModule.text=Exif Parser module was not run on data source: {0}\n @@ -10,6 +12,16 @@ DataSourceModuleWrapper.hashModule.text=Hash Lookup module was not run on data s # {0} - timeZone DateFilterPanel.dateRange.text=Date Range ({0}): DiscoveryDialog.name.text=Discovery +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 DiscoveryTopComponent.cancelButton.text=Cancel Search DiscoveryTopComponent.name=\ Discovery DiscoveryTopComponent.newSearch.text=New Search @@ -27,6 +39,9 @@ DiscoveryUiUtility.megaBytes.text=MB # {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 @@ -34,220 +49,26 @@ 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: +VideoFilterPanel.videoFiltersSplitPane.border.title=Step 2: Filter which videos to show 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.parentLabel.text_1=(All will be used) ParentFolderFilterPanel.parentCheckbox.text_1=Parent Folder: ParentFolderFilterPanel.addButton.text_1=Add ParentFolderFilterPanel.deleteButton.text_1=Delete @@ -255,33 +76,37 @@ 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= +GroupListPanel.groupKeyList.border.title=Groups 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: +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: -DomainUniquenessFilterPanel.domainUniquenessCheckbox.text=Domain Uniqueness: -DateFilterPanel.mostRecentButton.text=Only last: -DateFilterPanel.daysLabel.text=days of activity +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 +DetailsPanel.instancesList.border.title=Instances VideoThumbnailPanel.bytes.text=bytes VideoThumbnailPanel.deleted.text=All instances of file are deleted. VideoThumbnailPanel.gigaBytes.text=GB diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java index 20fead3473..26de95c390 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java @@ -23,10 +23,11 @@ import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JList; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.discovery.FileSearchData; -import org.sleuthkit.autopsy.discovery.FileSearchData.Frequency; -import org.sleuthkit.autopsy.discovery.SearchData.ResultType; -import org.sleuthkit.autopsy.discovery.SearchFiltering; +import org.sleuthkit.autopsy.discovery.search.AbstractFilter; +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. From 8a55650f2f60dbc88799f9ad94cd50c886604777 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 14:16:53 -0400 Subject: [PATCH 06/10] 6610 fix refactoring bug with attribute location --- Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java index 1ba77545de..9df5bd91b7 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java @@ -905,7 +905,7 @@ public class FileSearch { 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 DiscoveryKeyUtils.NoGroupingAttribute(), Bundle.FileSearch_GroupingAttributeType_none_displayName()); + NO_GROUPING(new NoGroupingAttribute(), Bundle.FileSearch_GroupingAttributeType_none_displayName()); private final AttributeType attributeType; private final String displayName; From c6f9d946175a3f687c1e0306fa418cfd49ead55e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 14:40:02 -0400 Subject: [PATCH 07/10] 6610 attempt to fix moved top component --- .../autopsy/discovery/ui/Bundle.properties | 3 +- .../discovery/ui/Bundle.properties-MERGED | 29 ++++++++++--------- .../discovery/ui/DiscoveryTopComponent.java | 4 +-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties index a2873c3d89..faa0025da5 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties @@ -1,7 +1,7 @@ # 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 @@ -52,4 +52,5 @@ ResultsPanel.gotoPageLabel.text=Go to Page: 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 diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED index 2de9ea3e1f..57cbd4cf00 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED @@ -1,7 +1,3 @@ -# 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. - CTL_OpenDiscoveryAction=Discovery # {0} - dataSourceName DataSourceModuleWrapper.exifModule.text=Exif Parser module was not run on data source: {0}\n @@ -12,16 +8,6 @@ DataSourceModuleWrapper.hashModule.text=Hash Lookup module was not run on data s # {0} - timeZone DateFilterPanel.dateRange.text=Date Range ({0}): DiscoveryDialog.name.text=Discovery -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 DiscoveryTopComponent.cancelButton.text=Cancel Search DiscoveryTopComponent.name=\ Discovery DiscoveryTopComponent.newSearch.text=New Search @@ -58,6 +44,20 @@ 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 @@ -106,6 +106,7 @@ ResultsPanel.gotoPageLabel.text=Go to Page: 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. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java index 30a6a3a49a..a264019067 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java @@ -43,14 +43,14 @@ import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType; /** * 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) @RetainLocation("discovery") @NbBundle.Messages("DiscoveryTopComponent.name= Discovery") public final class DiscoveryTopComponent extends TopComponent { 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 volatile static int resultsAreaSize = 250; private final GroupListPanel groupListPanel; From 744cb3dea6d444cff1eafb02996d4943861e6789 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 16:30:56 -0400 Subject: [PATCH 08/10] 6610 fix topcomponent not found --- .../autopsy/discovery/ui/DiscoveryTopComponent.form | 4 ++-- .../autopsy/discovery/ui/DiscoveryTopComponent.java | 6 +++--- .../autopsy/discovery/ui/ResultsSplitPaneDivider.form | 6 +++--- .../autopsy/discovery/ui/ResultsSplitPaneDivider.java | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form index 7917b19a1e..54630599ec 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.form @@ -105,8 +105,8 @@ - - + + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java index a264019067..be6edc83ea 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java @@ -43,14 +43,14 @@ import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType; /** * Create a dialog for displaying the Discovery results. */ -@TopComponent.Description(preferredID = "Discoverytc", persistenceType = TopComponent.PERSISTENCE_NEVER) +@TopComponent.Description(preferredID = "Discovery", persistenceType = TopComponent.PERSISTENCE_NEVER) @TopComponent.Registration(mode = "discovery", openAtStartup = false) @RetainLocation("discovery") @NbBundle.Messages("DiscoveryTopComponent.name= Discovery") public final class DiscoveryTopComponent extends TopComponent { private static final long serialVersionUID = 1L; - private static final String PREFERRED_ID = "Discoverytc"; // NON-NLS + private static final String PREFERRED_ID = "Discovery"; // NON-NLS private static final int ANIMATION_INCREMENT = 30; private volatile static int resultsAreaSize = 250; private final GroupListPanel groupListPanel; @@ -184,7 +184,7 @@ public final class DiscoveryTopComponent extends TopComponent { 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.setMinimumSize(new java.awt.Dimension(110, 26)); newSearchButton.setPreferredSize(new java.awt.Dimension(110, 26)); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form index a61f5a9c93..864e5d198c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.form @@ -24,7 +24,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -91,7 +91,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java index 251ed4cb94..6a08f681e4 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsSplitPaneDivider.java @@ -55,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 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 hideButton.setBorder(null); hideButton.setFocusable(false); @@ -67,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 showButton.setBorder(null); showButton.setFocusable(false); @@ -86,7 +86,7 @@ final class ResultsSplitPaneDivider extends javax.swing.JPanel { .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(detailsLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 251, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 199, Short.MAX_VALUE) .addComponent(showButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(hideButton) From 0ffabe2a6cda8e239acf729a52352b5a4c670576 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 17 Aug 2020 16:50:12 -0400 Subject: [PATCH 09/10] 6610 get top component working again --- .../sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java index be6edc83ea..96bcea63d6 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java @@ -43,14 +43,14 @@ import org.sleuthkit.autopsy.discovery.search.SearchData.ResultType; /** * 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) @RetainLocation("discovery") @NbBundle.Messages("DiscoveryTopComponent.name= Discovery") public final class DiscoveryTopComponent extends TopComponent { 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 volatile static int resultsAreaSize = 250; private final GroupListPanel groupListPanel; From 9e9d9c7b9fb0e52eb5a35501d69046e1a6812dcf Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 18 Aug 2020 10:18:02 -0400 Subject: [PATCH 10/10] 6610 fix size of discoverydialog --- .../org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form | 3 +++ .../org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java | 1 + 2 files changed, 4 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form index 522cd9b43e..e24e6f6a3b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form @@ -6,6 +6,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java index 0135ad651c..face0f1c97 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java @@ -306,6 +306,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setMinimumSize(new java.awt.Dimension(600, 300)); + setPreferredSize(new java.awt.Dimension(1000, 650)); imagesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/pictures-icon.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(imagesButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.imagesButton.text")); // NOI18N