From c13f41f67cf2028c2d6942e86812f327f16245b0 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 28 Oct 2013 15:09:58 -0400 Subject: [PATCH] Changed plumbing for adding content to hash db actions --- .../ContextMenuActionsProvider.java | 37 +++++++++++ .../coreutils/ContextMenuExtensionPoint.java | 45 ++++++++++++++ .../autopsy/datamodel/DirectoryNode.java | 2 - .../sleuthkit/autopsy/datamodel/FileNode.java | 2 - .../autopsy/datamodel/LayoutFileNode.java | 2 - .../autopsy/datamodel/LocalFileNode.java | 2 - .../datamodel/VirtualDirectoryNode.java | 2 - .../directorytree/DataResultFilterNode.java | 5 -- .../ExplorerNodeActionVisitor.java | 5 -- .../AddContentToHashDbAction.java | 61 +++++++++++++------ .../autopsy/hashdatabase/HashDbXML.java | 1 - .../KeywordSearchFilterNode.java | 2 +- 12 files changed, 127 insertions(+), 39 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/ContextMenuActionsProvider.java create mode 100755 Core/src/org/sleuthkit/autopsy/coreutils/ContextMenuExtensionPoint.java rename {Core/src/org/sleuthkit/autopsy/directorytree => HashDatabase/src/org/sleuthkit/autopsy/hashdatabase}/AddContentToHashDbAction.java (58%) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/ContextMenuActionsProvider.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/ContextMenuActionsProvider.java new file mode 100755 index 0000000000..1d84ca2c6c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/ContextMenuActionsProvider.java @@ -0,0 +1,37 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 - 2013 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.corecomponentinterfaces; + +import java.util.List; +import javax.swing.Action; + +/** + * Implementers of this interface provide Actions that will be added to context + * menus in Autopsy. + */ +public interface ContextMenuActionsProvider { + /** + * Gets context menu Actions appropriate to the org.sleuthkit.datamodel + * objects in the NetBeans Lookup for the active TopComponent. + * Implementers can discover the data model objects by calling + * org.openide.util.Utilities.actionsGlobalContext().lookupAll(). + * @return A list, possibly empty, of Action objects. + */ + List getActions(); +} diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ContextMenuExtensionPoint.java b/Core/src/org/sleuthkit/autopsy/coreutils/ContextMenuExtensionPoint.java new file mode 100755 index 0000000000..f066d20de9 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ContextMenuExtensionPoint.java @@ -0,0 +1,45 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 - 2013 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.coreutils; + +import org.openide.util.Lookup; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.swing.Action; +import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider; + +/** + * This class implements the ContextMenuActionsProvider extension point. + */ +public class ContextMenuExtensionPoint { + /** + * Gets all of the Actions provided by registered implementers of the + * ContextMenuActionsProvider interface. + * @return A list, possibly empty, of Action objects. + */ + static public List getActions() { + ArrayList actions = new ArrayList<>(); + Collection actionProviders = Lookup.getDefault().lookupAll(ContextMenuActionsProvider.class); + for (ContextMenuActionsProvider provider : actionProviders) { + actions.addAll(provider.getActions()); + } + return actions; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java index a2828140ab..182a64c61d 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.datamodel; import java.util.ArrayList; import java.util.List; import javax.swing.Action; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction; @@ -78,7 +77,6 @@ public class DirectoryNode extends AbstractFsContentNode { actions.add(ExtractAction.getInstance()); actions.add(null); // creates a menu separator actions.add(TagAbstractFileAction.getInstance()); - actions.add(AddContentToHashDbAction.getInstance()); return actions.toArray(new Action[0]); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java index 614b34daff..04c0c1a078 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.datamodel; import java.util.ArrayList; import java.util.List; import javax.swing.Action; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction; @@ -86,7 +85,6 @@ public class FileNode extends AbstractFsContentNode { actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this)); actionsList.add(null); // creates a menu separator actionsList.add(TagAbstractFileAction.getInstance()); - actionsList.add(AddContentToHashDbAction.getInstance()); return actionsList.toArray(new Action[0]); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index d7384b05d8..5dd48d1ae1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Map; import javax.swing.Action; import org.openide.nodes.Sheet; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; @@ -110,7 +109,6 @@ public class LayoutFileNode extends AbstractAbstractFileNode { actionsList.add(ExtractAction.getInstance()); actionsList.add(null); // creates a menu separator actionsList.add(TagAbstractFileAction.getInstance()); - actionsList.add(AddContentToHashDbAction.getInstance()); return actionsList.toArray(new Action[0]); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index be3a93f602..af8ef7549f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -26,7 +26,6 @@ import java.util.Map; import javax.swing.Action; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode.TYPE; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction; @@ -94,7 +93,6 @@ public class LocalFileNode extends AbstractAbstractFileNode { actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this)); actionsList.add(null); // creates a menu separator actionsList.add(TagAbstractFileAction.getInstance()); - actionsList.add(AddContentToHashDbAction.getInstance()); return actionsList.toArray(new Action[0]); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index c0b9a6a841..76062876bc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -25,7 +25,6 @@ import java.util.Map; import javax.swing.Action; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction; @@ -83,7 +82,6 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode visit(final Directory d) { List actions = new ArrayList<>(); actions.add(TagAbstractFileAction.getInstance()); - actions.add(AddContentToHashDbAction.getInstance()); return actions; } @@ -111,7 +110,6 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default actions = new ArrayList<>(); actions.add(ExtractAction.getInstance()); actions.add(TagAbstractFileAction.getInstance()); - actions.add(AddContentToHashDbAction.getInstance()); return actions; } @@ -120,7 +118,6 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default actions = new ArrayList<>(); actions.add(ExtractAction.getInstance()); actions.add(TagAbstractFileAction.getInstance()); - actions.add(AddContentToHashDbAction.getInstance()); return actions; } @@ -129,7 +126,6 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default actions = new ArrayList<>(); actions.add(ExtractAction.getInstance()); actions.add(TagAbstractFileAction.getInstance()); - actions.add(AddContentToHashDbAction.getInstance()); return actions; } @@ -138,7 +134,6 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default actions = new ArrayList<>(); actions.add(ExtractAction.getInstance()); actions.add(TagAbstractFileAction.getInstance()); - actions.add(AddContentToHashDbAction.getInstance()); return actions; } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/AddContentToHashDbAction.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/AddContentToHashDbAction.java similarity index 58% rename from Core/src/org/sleuthkit/autopsy/directorytree/AddContentToHashDbAction.java rename to HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/AddContentToHashDbAction.java index 44999ef5c1..e7ee2e548d 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/AddContentToHashDbAction.java +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/AddContentToHashDbAction.java @@ -16,25 +16,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.directorytree; +package org.sleuthkit.autopsy.hashdatabase; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.util.Collection; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.JMenu; +import javax.swing.JMenuItem; import javax.swing.JOptionPane; import org.openide.util.Utilities; import org.openide.util.Lookup; -import org.sleuthkit.autopsy.coreutils.Logger; +import org.openide.util.actions.Presenter; import org.sleuthkit.autopsy.ingest.IngestConfigurator; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; /** * Instances of this Action allow users to content to a hash database. */ -public class AddContentToHashDbAction extends AbstractAction { +public class AddContentToHashDbAction extends AbstractAction implements Presenter.Popup { // This class is a singleton to support multi-selection of nodes, since // org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every // node in the array returns a reference to the same action object from Node.getActions(boolean). @@ -81,21 +85,44 @@ public class AddContentToHashDbAction extends AbstractAction { super(SINGLE_SELECTION_NAME); } + @Override + public JMenuItem getPopupPresenter() { + return new AddContentToHashDbMenu(); + } + @Override public void actionPerformed(ActionEvent event) { - Collection selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class); - for (AbstractFile file : selectedFiles) { - try { - // RJCTODO: Complete this method. - String md5Hash = file.getMd5Hash(); - if (null != md5Hash) { - throw new TskCoreException("RJCTODO"); - } + } + + private class AddContentToHashDbMenu extends JMenu { + AddContentToHashDbMenu() { + // RJCTODO: Need super call? + + // Get the current set of updateable hash databases and add each + // one as a menu item. + for (final HashDb database : HashDbXML.getCurrent().getKnownBadSets()) { + if (database.isUpdateable()) { + JMenuItem databaseItem = add(database.getName()); + databaseItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Collection selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class); + for (AbstractFile file : selectedFiles) { + String md5Hash = file.getMd5Hash(); + if (null != md5Hash) { + try { + database.addContentHash(file); + } + catch (TskCoreException ex) { + Logger.getLogger(AddContentToHashDbAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); + JOptionPane.showMessageDialog(null, "Unable to add " + file.getName() + "to hash database.", "Add to Hash Database Error", JOptionPane.ERROR_MESSAGE); + } + } + } + } + }); + } } - catch (TskCoreException ex) { - Logger.getLogger(AddContentToHashDbAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); - JOptionPane.showMessageDialog(null, "Unable to add " + file.getName() + "to hash database.", "Add to Hash Database Error", JOptionPane.ERROR_MESSAGE); - } - } - } + } + } } diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbXML.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbXML.java index 0ac5f8b31c..e8f0ff8bee 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbXML.java +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbXML.java @@ -32,7 +32,6 @@ import javax.xml.parsers.ParserConfigurationException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; import org.sleuthkit.autopsy.hashdatabase.HashDb.DBType; import org.sleuthkit.datamodel.SleuthkitJNI; import org.sleuthkit.datamodel.TskCoreException; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java index 006839fcc5..8f83110767 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java @@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; -import org.sleuthkit.autopsy.directorytree.AddContentToHashDbAction; +import org.sleuthkit.autopsy.hashdatabase.AddContentToHashDbAction; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.DerivedFile;