From 99fe56539fbcaa6a80dee49115a26f95b3f3a837 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 17 Jul 2019 11:09:48 -0400 Subject: [PATCH] 5114 Clean up and add comments for file discovery ui --- .../autopsy/filequery/DiscoveryEvents.java | 62 ++++++++++++++++--- ...d.java => DiscoveryThumbnailChildren.java} | 20 +++--- .../filequery/FileDiscoveryDialog.java | 12 +++- .../filequery/FileDiscoveryTestAction.java | 1 + .../autopsy/filequery/FileSearchPanel.java | 2 +- .../autopsy/filequery/GroupListPanel.java | 26 +++++++- .../autopsy/filequery/SearchWorker.java | 40 ++++++------ 7 files changed, 116 insertions(+), 47 deletions(-) rename Core/src/org/sleuthkit/autopsy/filequery/{DiscoveryThumbnailChild.java => DiscoveryThumbnailChildren.java} (86%) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java index f5f50599c1..5db533f5d5 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryEvents.java @@ -21,14 +21,21 @@ package org.sleuthkit.autopsy.filequery; import com.google.common.eventbus.EventBus; import java.util.List; import java.util.ArrayList; -import org.openide.nodes.Node; import org.sleuthkit.autopsy.filequery.FileSearchData.FileType; import org.sleuthkit.datamodel.AbstractFile; +/** + * Class to handle envent bus and events for file discovery tool + */ final class DiscoveryEvents { private final static EventBus discoveryEventBus = new EventBus(); + /** + * Get the file discovery event bus + * + * @return the file discovery event bus + */ static EventBus getDiscoveryEventBus() { return discoveryEventBus; } @@ -36,53 +43,92 @@ final class DiscoveryEvents { private DiscoveryEvents() { } + /** + * Event to signal the start of a search being performed + */ static final class SearchStartedEvent { private final FileType fileType; + /** + * Construct a new SearchStartedEvent + * + * @param type the type of file the search event is for + */ SearchStartedEvent(FileType type) { this.fileType = type; } + /** + * Get the type of file the search is being performed for + * + * @return the type of files being searched for + */ FileType getType() { return fileType; } } + /** + * Event to signal the completion of a search being performed + */ static final class SearchCompleteEvent { private final SearchResults results; - private final FileType fileType; - SearchCompleteEvent(FileType type, SearchResults results) { - this.fileType = type; + /** + * Construct a new SearchCompleteEvent + * + * @param results the results which were found by the search + */ + SearchCompleteEvent(SearchResults results) { this.results = results; } + /** + * Get the results of the search + * + * @return the results of the search + */ SearchResults getSearchResults() { return results; } - FileType getType() { - return fileType; - } - } + /** + * Event to signal the the selection of a group from the search results + */ static final class GroupSelectedEvent { private final List files; private final FileType type; + /** + * Construct a new GroupSelectedEvent + * + * @param type the type of files which exist in the group + * @param files the files in the group + */ GroupSelectedEvent(FileType type, List files) { this.type = type; this.files = files; } + /** + * Get the type of files which exist in the group + * + * @return the type of files in the group + */ FileType getType() { return type; } + /** + * Get the files in the group selected + * + * @return the list of AbstractFiles in the group selected + */ List getFiles() { if (files != null && !files.isEmpty()) { return files; diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryThumbnailChild.java b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryThumbnailChildren.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/filequery/DiscoveryThumbnailChild.java rename to Core/src/org/sleuthkit/autopsy/filequery/DiscoveryThumbnailChildren.java index 6f78f0fa44..b39514840a 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryThumbnailChild.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryThumbnailChildren.java @@ -31,18 +31,18 @@ import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode; import org.sleuthkit.autopsy.datamodel.FileNode; import org.sleuthkit.datamodel.AbstractFile; -public class DiscoveryThumbnailChild extends Children.Keys { +/** + * Create a node containing the children for the to display in the + * DataResultViewerThumbnail + */ +class DiscoveryThumbnailChildren extends Children.Keys { private final List files; /* - * Creates the list of thumbnails from the given list of - * BlackboardArtifacts. - * - * The thumbnails will be initialls sorted by size, then name so that they - * appear sorted by size by default. + * Creates the list of thumbnails from the given list of AbstractFiles. */ - DiscoveryThumbnailChild(List files) { + DiscoveryThumbnailChildren(List files) { super(false); this.files = files; @@ -51,7 +51,7 @@ public class DiscoveryThumbnailChild extends Children.Keys { @Override protected Node[] createNodes(AbstractFile t) { - return new Node[]{new AttachementNode(t)}; + return new Node[]{new ThumbnailNode(t)}; } @Override @@ -73,9 +73,9 @@ public class DiscoveryThumbnailChild extends Children.Keys { /** * A node for representing a thumbnail. */ - static class AttachementNode extends FileNode { + static class ThumbnailNode extends FileNode { - AttachementNode(AbstractFile file) { + ThumbnailNode(AbstractFile file) { super(file, false); } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryDialog.java index cb57cd02e6..84806dc200 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryDialog.java @@ -33,6 +33,9 @@ import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; import org.sleuthkit.autopsy.filequery.FileSearchData.FileType; import org.sleuthkit.datamodel.SleuthkitCase; +/** + * Create a dialog for displaying the file discovery tool + */ class FileDiscoveryDialog extends javax.swing.JDialog { private static final long serialVersionUID = 1L; @@ -50,7 +53,6 @@ class FileDiscoveryDialog extends javax.swing.JDialog { super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.FileSearchPanel_dialogTitle_text(), modal); initComponents(); explorerManager = new ExplorerManager(); - //create results callback and pass it into the search panel fileSearchPanel = new FileSearchPanel(caseDb, centralRepoDb); groupListPanel = new GroupListPanel(); DiscoveryEvents.getDiscoveryEventBus().register(groupListPanel); @@ -86,17 +88,21 @@ class FileDiscoveryDialog extends javax.swing.JDialog { */ void display() { this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); -// runAnotherSearch = false; setVisible(true); } + /** + * Subscribe to GroupSelectedEvents and respond to them + * + * @param groupSelectedEvent the GroupSelectedEvent received + */ @Subscribe void handleGroupSelectedEvent(DiscoveryEvents.GroupSelectedEvent groupSelectedEvent) { thumbnailViewer.resetComponent(); if (groupSelectedEvent.getType() == FileType.IMAGE || groupSelectedEvent.getType() == FileType.VIDEO) { rightSplitPane.setTopComponent(thumbnailViewer); if (groupSelectedEvent.getFiles().size() > 0) { - thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new DiscoveryThumbnailChild(groupSelectedEvent.getFiles()))), true)); + thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new DiscoveryThumbnailChildren(groupSelectedEvent.getFiles()))), true)); } else { thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true)); } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryTestAction.java b/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryTestAction.java index a0b6b956ab..fa6cbade0e 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryTestAction.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileDiscoveryTestAction.java @@ -66,6 +66,7 @@ public final class FileDiscoveryTestAction extends CallableSystemAction { } FileDiscoveryDialog dialog = new FileDiscoveryDialog(WindowManager.getDefault().getMainWindow(), false, Case.getCurrentCase().getSleuthkitCase(), crDb); + //register the dialog with the event bus DiscoveryEvents.getDiscoveryEventBus().register(dialog); // Display the dialog dialog.display(); diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java index 4494abd462..28863e4178 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchPanel.java @@ -808,7 +808,7 @@ final class FileSearchPanel extends javax.swing.JPanel implements ActionListener // Get the file sorting method FileSorter.SortingMethod fileSort = getFileSortingMethod(); - SearchWorker searchWorker = new SearchWorker(centralRepoDb, searchButton, searchType, filters, groupingAttr, groupSortAlgorithm, fileSort); + SearchWorker searchWorker = new SearchWorker(centralRepoDb, searchButton, filters, groupingAttr, groupSortAlgorithm, fileSort); searchWorker.execute(); }//GEN-LAST:event_searchButtonActionPerformed diff --git a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java index 18b5950025..41d9460241 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/GroupListPanel.java @@ -22,12 +22,17 @@ import com.google.common.eventbus.Subscribe; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; -import org.openide.util.Exceptions; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.filequery.FileSearchData.FileType; import org.sleuthkit.datamodel.AbstractFile; +/** + * Panel to display the list of groups which are provided by a search + */ class GroupListPanel extends javax.swing.JPanel { + private final static Logger logger = Logger.getLogger(GroupListPanel.class.getName()); private static final long serialVersionUID = 1L; private LinkedHashMap> results = null; private FileType resultType = null; @@ -39,6 +44,11 @@ class GroupListPanel extends javax.swing.JPanel { initComponents(); } + /** + * Subscribe to and reset the panel in response to SearchStartedEvents + * + * @param searchStartedEvent the SearchStartedEvent which was received + */ @Subscribe void handleSearchStartedEvent(DiscoveryEvents.SearchStartedEvent searchStartedEvent) { resultType = searchStartedEvent.getType(); @@ -46,10 +56,15 @@ class GroupListPanel extends javax.swing.JPanel { groupList.setListData(new String[0]); } + /** + * Subscribe to and update list of groups in response to + * SearchCompleteEvents + * + * @param searchCompleteEvent the SearchCompleteEvent which was recieved + */ @Subscribe void handleSearchCompleteEvent(DiscoveryEvents.SearchCompleteEvent searchCompleteEvent) { try { - resultType = searchCompleteEvent.getType(); results = searchCompleteEvent.getSearchResults().toLinkedHashMap(); Set resultsKeySet = results.keySet(); groupList.setListData(resultsKeySet.toArray(new String[results.size()])); @@ -59,7 +74,7 @@ class GroupListPanel extends javax.swing.JPanel { validate(); repaint(); } catch (FileSearchException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.WARNING, "Error handling completed search results for file discovery, no results displayed", ex); groupList.setListData(new String[0]); } } @@ -100,6 +115,11 @@ class GroupListPanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents + /** + * Respond to a group being selected by sending a GroupSelectedEvent + * + * @param evt the event which indicates a selection occurs in the list + */ private void groupSelected(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_groupSelected if (!evt.getValueIsAdjusting() && results != null) { DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent(resultType, results.get(groupList.getSelectedValue()))); diff --git a/Core/src/org/sleuthkit/autopsy/filequery/SearchWorker.java b/Core/src/org/sleuthkit/autopsy/filequery/SearchWorker.java index 6a8b4a224a..f8c9baedc0 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/SearchWorker.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/SearchWorker.java @@ -26,24 +26,34 @@ import java.util.logging.Level; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.filequery.FileSearchData.FileType; +/** + * SwingWorker to perform search on a background thread + */ final class SearchWorker extends SwingWorker { private final static Logger logger = Logger.getLogger(SearchWorker.class.getName()); - private boolean runAnotherSearch = false; private final JButton searchButtonToEnable; private final List filters; private final FileSearch.AttributeType groupingAttr; private final FileSorter.SortingMethod fileSort; private final FileGroup.GroupSortingAlgorithm groupSortAlgorithm; private final EamDb centralRepoDb; - private final FileType fileType; - SearchWorker(EamDb centralRepo, JButton searchButton, FileType type, List searchfilters, FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod) { + /** + * Create a SwingWorker which performs a search + * + * @param centralRepo the central repository being used for the search + * @param searchButton the search button to renable when the search is + * complete + * @param searchfilters the FileFilters to use for the search + * @param groupingAttribute the AttributeType to group by + * @param groupSort the Algorithm to sort groups by + * @param fileSortMethod the SortingMethod to use for files + */ + SearchWorker(EamDb centralRepo, JButton searchButton, List searchfilters, FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod) { centralRepoDb = centralRepo; searchButtonToEnable = searchButton; - fileType = type; filters = searchfilters; groupingAttr = groupingAttribute; groupSortAlgorithm = groupSort; @@ -52,11 +62,6 @@ final class SearchWorker extends SwingWorker { @Override protected Void doInBackground() throws Exception { - runAnotherSearch = true; - // For testing, allow the user to run different searches in loop - if (searchCancelled()) { - return null; - } try { // Make a list of attributes that we want to add values for. This ensures the @@ -74,7 +79,7 @@ final class SearchWorker extends SwingWorker { fileSort, attrsForGroupingAndSorting, Case.getCurrentCase().getSleuthkitCase(), centralRepoDb); - DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.SearchCompleteEvent(fileType, results)); + DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.SearchCompleteEvent(results)); } catch (FileSearchException ex) { logger.log(Level.SEVERE, "Error running file search test", ex); } @@ -82,19 +87,10 @@ final class SearchWorker extends SwingWorker { } @Override - protected void done() { + protected void done() { + //If a search button was provided re-enable it if (searchButtonToEnable != null) { searchButtonToEnable.setEnabled(true); } } - - /** - * Check whether the user chose to run the search or cancel - * - * @return true if the search was cancelled, false otherwise - */ - boolean searchCancelled() { - return (!runAnotherSearch); - } - }