From 0ef55c7f6d8cfec7801df449cde936db2c46573f Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 11 Sep 2020 10:29:01 -0400 Subject: [PATCH] 6714 make grouping and sorting attrs based on search type --- .../discovery/search/DiscoveryAttributes.java | 17 ++- .../discovery/search/ResultsSorter.java | 24 ++-- .../discovery/ui/AbstractFiltersPanel.java | 49 ++++++++ .../autopsy/discovery/ui/DiscoveryDialog.java | 112 ++++++++++++------ .../discovery/ui/DomainFilterPanel.java | 4 + 5 files changed, 156 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java index 751b47e849..b5da230a10 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java @@ -658,12 +658,21 @@ public class DiscoveryAttributes { } /** - * Get the list of enums that are valid for grouping images. + * Get the list of enums that are valid for grouping files. * - * @return enums that can be used to group images + * @return Enums that can be used to group files. */ - public static List getOptionsForGrouping() { - return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET, FIRST_DATE, MOST_RECENT_DATE); + public static List getOptionsForGroupingForFiles() { + return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET); + } + + /** + * Get the list of enums that are valid for grouping files. + * + * @return Enums that can be used to group files. + */ + public static List getOptionsForGroupingForDomains() { + return Arrays.asList(MOST_RECENT_DATE, FIRST_DATE); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java index 27f0fcb202..d20bc4df30 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java @@ -229,16 +229,16 @@ public class ResultsSorter implements Comparator { return compareStrings(((ResultFile) result1).getFirstInstance().getName().toLowerCase(), (((ResultFile) result2).getFirstInstance().getName().toLowerCase())); }; } - + /** * Sorts domain names in lexographical order, ignoring case. */ private static Comparator getDomainNameComparator() { return (Result domain1, Result domain2) -> { - if(domain1.getType() != SearchData.Type.DOMAIN) { + if (domain1.getType() != SearchData.Type.DOMAIN) { return 0; } - + ResultDomain first = (ResultDomain) domain1; ResultDomain second = (ResultDomain) domain2; return compareStrings(first.getDomain().toLowerCase(), second.getDomain().toLowerCase()); @@ -312,7 +312,7 @@ public class ResultsSorter implements Comparator { BY_KEYWORD_LIST_NAMES(Arrays.asList(new DiscoveryAttributes.KeywordListAttribute()), Bundle.FileSorter_SortingMethod_keywordlist_displayName()), // Sort alphabetically by list of keyword list names found BY_FULL_PATH(new ArrayList<>(), - Bundle.FileSorter_SortingMethod_fullPath_displayName()), // Sort alphabetically by path + Bundle.FileSorter_SortingMethod_fullPath_displayName()), // Sort alphabetically by path BY_DOMAIN_NAME(new ArrayList<>(), Bundle.FileSorter_SortingMethod_domain_displayName()); @@ -334,12 +334,22 @@ public class ResultsSorter implements Comparator { } /** - * Get the list of enums that are valid for ordering images. + * Get the list of enums that are valid for ordering files. * - * @return enums that can be used to ordering images. + * @return Enums that can be used to ordering files. */ - public static List getOptionsForOrdering() { + public static List getOptionsForOrderingFiles() { return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE); } + + /** + * Get the list of enums that are valid for ordering files. + * + * @return Enums that can be used to ordering files. + */ + public static List getOptionsForOrderingDomains() { + return Arrays.asList(BY_DOMAIN_NAME, BY_DATA_SOURCE); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java index 0736708e9c..298789bf3b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java @@ -32,6 +32,9 @@ 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.search.DiscoveryAttributes.GroupingAttributeType; +import org.sleuthkit.autopsy.discovery.search.Group; +import org.sleuthkit.autopsy.discovery.search.ResultsSorter.SortingMethod; import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; @@ -55,6 +58,9 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li private final JPanel secondColumnPanel = new JPanel(); private int firstColumnY = 0; private int secondColumnY = 0; + private SortingMethod lastSortingMethod = SortingMethod.BY_FILE_NAME; + private GroupingAttributeType lastGroupingAttributeType = GroupingAttributeType.PARENT_PATH; + private Group.GroupSortingAlgorithm lastGroupSortingAlg = Group.GroupSortingAlgorithm.BY_GROUP_SIZE; /** * Setup necessary for implementations of this abstract class. @@ -64,6 +70,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li secondColumnPanel.setLayout(new GridBagLayout()); } + /** * Get the type of results this filters panel is for. * @@ -271,4 +278,46 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li } } + /** + * @return the lastSortingMethod + */ + SortingMethod getLastSortingMethod() { + return lastSortingMethod; + } + + /** + * @param lastSortingMethod the lastSortingMethod to set + */ + final void setLastSortingMethod(SortingMethod lastSortingMethod) { + this.lastSortingMethod = lastSortingMethod; + } + + /** + * @return the lastGroupingAttributeType + */ + GroupingAttributeType getLastGroupingAttributeType() { + return lastGroupingAttributeType; + } + + /** + * @param lastGroupingAttributeType the lastGroupingAttributeType to set + */ + final void setLastGroupingAttributeType(GroupingAttributeType lastGroupingAttributeType) { + this.lastGroupingAttributeType = lastGroupingAttributeType; + } + + /** + * @return the lastGroupSortingAlg + */ + Group.GroupSortingAlgorithm getLastGroupSortingAlg() { + return lastGroupSortingAlg; + } + + /** + * @param lastGroupSortingAlg the lastGroupSortingAlg to set + */ + final void setLastGroupSortingAlg(Group.GroupSortingAlgorithm lastGroupSortingAlg) { + this.lastGroupSortingAlg = lastGroupSortingAlg; + } + } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java index 474b766910..cc029c2218 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java @@ -21,6 +21,8 @@ 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.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; @@ -37,16 +39,12 @@ 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.search.DiscoveryAttributes; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.search.Group; import org.sleuthkit.autopsy.discovery.search.Group.GroupSortingAlgorithm; -import static org.sleuthkit.autopsy.discovery.search.Group.GroupSortingAlgorithm.BY_GROUP_SIZE; import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes.GroupingAttributeType; -import static org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes.GroupingAttributeType.PARENT_PATH; import org.sleuthkit.autopsy.discovery.search.ResultsSorter; import org.sleuthkit.autopsy.discovery.search.ResultsSorter.SortingMethod; -import static org.sleuthkit.autopsy.discovery.search.ResultsSorter.SortingMethod.BY_FILE_NAME; import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleDataEvent; @@ -111,12 +109,34 @@ final class DiscoveryDialog extends javax.swing.JDialog { } } }; - for (GroupSortingAlgorithm groupSortAlgorithm : GroupSortingAlgorithm.values()) { - groupSortingComboBox.addItem(groupSortAlgorithm); - } updateSearchSettings(); + groupByCombobox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (event.getStateChange() == ItemEvent.SELECTED) { + getSelectedFilterPanel().setLastGroupingAttributeType((GroupingAttributeType) groupByCombobox.getSelectedItem()); + } + } + }); + orderByCombobox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (event.getStateChange() == ItemEvent.SELECTED) { + getSelectedFilterPanel().setLastSortingMethod((SortingMethod) groupByCombobox.getSelectedItem()); + } + } + }); + groupSortingComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (event.getStateChange() == ItemEvent.SELECTED) { + getSelectedFilterPanel().setLastGroupSortingAlg((GroupSortingAlgorithm) groupByCombobox.getSelectedItem()); + } + } + }); Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener()); IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, this.new ModuleChangeListener()); + } /** @@ -140,7 +160,6 @@ final class DiscoveryDialog extends javax.swing.JDialog { add(imageFilterPanel, CENTER); imageFilterPanel.addPropertyChangeListener(listener); updateComboBoxes(); - groupSortingComboBox.setSelectedItem(BY_GROUP_SIZE); pack(); repaint(); } @@ -149,8 +168,8 @@ final class DiscoveryDialog extends javax.swing.JDialog { * Set the type buttons to a default state where none are selected. */ private void unselectAllButtons() { - imagesButton.setSelected(false); - imagesButton.setEnabled(true); + imagesButton.setSelected(false); + imagesButton.setEnabled(true); imagesButton.setBackground(UNSELECTED_COLOR); videosButton.setSelected(false); videosButton.setEnabled(true); @@ -167,20 +186,54 @@ final class DiscoveryDialog extends javax.swing.JDialog { * Private helper method to perform update of comboboxes update. */ private void updateComboBoxes() { - groupByCombobox.removeAllItems(); // Set up the grouping attributes - for (DiscoveryAttributes.GroupingAttributeType groupingType : DiscoveryAttributes.GroupingAttributeType.getOptionsForGrouping()) { + List groupingAttrs = new ArrayList<>(); + List sortingMethods = new ArrayList<>(); + groupByCombobox.removeAllItems(); + if (type == SearchData.Type.DOMAIN) { + groupingAttrs.addAll(GroupingAttributeType.getOptionsForGroupingForDomains()); + sortingMethods.addAll(SortingMethod.getOptionsForOrderingDomains()); + } else { + groupingAttrs.addAll(GroupingAttributeType.getOptionsForGroupingForFiles()); + sortingMethods.addAll(SortingMethod.getOptionsForOrderingFiles()); + } + for (GroupingAttributeType groupingType : groupingAttrs) { addTypeToGroupByComboBox(groupingType); } - groupByCombobox.setSelectedItem(PARENT_PATH); + groupByCombobox.setSelectedItem(getSelectedFilterPanel().getLastGroupingAttributeType()); orderByCombobox.removeAllItems(); // Set up the file order list - for (ResultsSorter.SortingMethod method : ResultsSorter.SortingMethod.getOptionsForOrdering()) { + for (SortingMethod method : sortingMethods) { if (method != SortingMethod.BY_FREQUENCY || CentralRepository.isEnabled()) { orderByCombobox.addItem(method); } } - orderByCombobox.setSelectedItem(BY_FILE_NAME); + orderByCombobox.setSelectedItem(getSelectedFilterPanel().getLastGroupSortingAlg()) + ); + for (GroupSortingAlgorithm groupSortAlgorithm : GroupSortingAlgorithm.values()) { + groupSortingComboBox.addItem(groupSortAlgorithm); + } + groupSortingComboBox.setSelectedItem(getSelectedFilterPanel().getLastGroupSortingAlg()); + } + + private AbstractFiltersPanel getSelectedFilterPanel() { + switch (type) { + case IMAGE: + return imageFilterPanel; + break; + case VIDEO: + return videoFilterPanel; + break; + case DOCUMENT: + return documentFilterPanel; + break; + case DOMAIN: + return domainFilterPanel; + break; + default: + return imageFilterPanel; + break; + } } /** @@ -221,29 +274,9 @@ final class DiscoveryDialog extends javax.swing.JDialog { * Validate the filter settings for File type filters. */ synchronized void validateDialog() { - switch (type) { - case IMAGE: - if (imageFilterPanel != null) { - imageFilterPanel.validateFields(); - } - break; - case VIDEO: - if (videoFilterPanel != null) { - videoFilterPanel.validateFields(); - } - break; - case DOCUMENT: - if (documentFilterPanel != null) { - documentFilterPanel.validateFields(); - } - break; - case DOMAIN: - if (domainFilterPanel != null) { - domainFilterPanel.validateFields(); - } - break; - default: - break; + AbstractFiltersPanel panel = getSelectedFilterPanel(); + if (panel != null) { + panel.validateFields(); } } @@ -554,7 +587,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.SearchStartedEvent(type)); // Get the grouping attribute and group sorting method - DiscoveryAttributes.AttributeType groupingAttr = groupByCombobox.getItemAt(groupByCombobox.getSelectedIndex()).getAttributeType(); + AttributeType groupingAttr = groupByCombobox.getItemAt(groupByCombobox.getSelectedIndex()).getAttributeType(); Group.GroupSortingAlgorithm groupSortAlgorithm = groupSortingComboBox.getItemAt(groupSortingComboBox.getSelectedIndex()); // Get the file sorting method @@ -585,6 +618,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { domainsButton.setForeground(Color.BLACK); type = SearchData.Type.DOMAIN; domainFilterPanel.addPropertyChangeListener(listener); + updateComboBoxes(); validateDialog(); pack(); repaint(); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java index 45ba72338c..cf3209146d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java @@ -19,6 +19,8 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes; +import org.sleuthkit.autopsy.discovery.search.ResultsSorter; import org.sleuthkit.autopsy.discovery.search.SearchData; /** @@ -44,6 +46,8 @@ public class DomainFilterPanel extends AbstractFiltersPanel { } addFilter(new PastOccurrencesFilterPanel(TYPE), true, pastOccurrencesIndices, 0); addPanelsToScrollPane(domainFiltersSplitPane); + setLastGroupingAttributeType(DiscoveryAttributes.GroupingAttributeType.MOST_RECENT_DATE); + setLastSortingMethod(ResultsSorter.SortingMethod.BY_DOMAIN_NAME); } /**