Merge branch 'master' of git://github.com/rcordovano/autopsy into rcordovano-master

This commit is contained in:
Brian Carrier 2013-08-12 11:32:56 -04:00
commit ff009c368d
29 changed files with 1937 additions and 2036 deletions

View File

@ -109,7 +109,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
Logger.noteAction(AddImageAction.class); Logger.noteAction(AddImageAction.class);
final IngestConfigurator ingestConfig = Lookup.getDefault().lookup(IngestConfigurator.class); final IngestConfigurator ingestConfig = Lookup.getDefault().lookup(IngestConfigurator.class);
if (ingestConfig.isIngestRunning()) { if (null != ingestConfig && ingestConfig.isIngestRunning()) {
final String msg = "<html>Ingest is ongoing on another data source. Adding a new source now might slow down the current ingest.<br />Do you want to proceed and add a new data source now?</html>"; final String msg = "<html>Ingest is ongoing on another data source. Adding a new source now might slow down the current ingest.<br />Do you want to proceed and add a new data source now?</html>";
if (JOptionPane.showConfirmDialog(null, msg, "Ingest in progress", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) { if (JOptionPane.showConfirmDialog(null, msg, "Ingest in progress", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
return; return;
@ -128,7 +128,6 @@ public final class AddImageAction extends CallableSystemAction implements Presen
dialog.setVisible(true); dialog.setVisible(true);
dialog.toFront(); dialog.toFront();
// Do any cleanup that needs to happen (potentially: stopping the // Do any cleanup that needs to happen (potentially: stopping the
//add-image process, reverting an image) //add-image process, reverting an image)
runCleanupTasks(); runCleanupTasks();

View File

@ -0,0 +1,151 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.ingest.IngestDialogPanel;
import static org.sleuthkit.autopsy.ingest.IngestDialogPanel.DISABLED_MOD;
import static org.sleuthkit.autopsy.ingest.IngestDialogPanel.PARSE_UNALLOC;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract;
import org.sleuthkit.datamodel.Content;
@ServiceProvider(service = IngestConfigurator.class)
public class GeneralIngestConfigurator implements IngestConfigurator {
private List<Content> contentToIngest;
private IngestManager manager;
private IngestDialogPanel ingestDialogPanel;
private String moduleContext;
public GeneralIngestConfigurator() {
this.moduleContext = IngestManager.MODULE_PROPERTIES; // Hard-code this for now.
ingestDialogPanel = new IngestDialogPanel();
manager = IngestManager.getDefault();
loadSettings();
}
@Override
public JPanel getIngestConfigPanel() {
return ingestDialogPanel;
}
@Override
public void setContent(List<Content> inputContent) {
this.contentToIngest = inputContent;
}
@Override
public void start() {
// Get the list of ingest modules selected by the user.
List<IngestModuleAbstract> modulesToStart = ingestDialogPanel.getModulesToStart();
// Get the user's selection of whether or not to process unallocated space.
manager.setProcessUnallocSpace(ingestDialogPanel.processUnallocSpaceEnabled());
// Start the ingest.
if (!modulesToStart.isEmpty()) {
manager.execute(modulesToStart, contentToIngest);
}
}
@Override
public void save() {
// Save the user's configuration of the currently selected module.
IngestModuleAbstract currentModule = ingestDialogPanel.getCurrentIngestModule();
if (currentModule != null && currentModule.hasSimpleConfiguration()) {
currentModule.saveSimpleConfiguration();
}
// Create a list of the modules the user wants to be disabled.
List<IngestModuleAbstract> disabledModules = IngestManager.getDefault().enumerateAllModules();
disabledModules.removeAll(ingestDialogPanel.getModulesToStart());
String disabledModulesCsv = moduleListToCsv(disabledModules);
// Save the user's general ingest configuration.
ModuleSettings.setConfigSetting(moduleContext, DISABLED_MOD, disabledModulesCsv);
String processUnalloc = Boolean.toString(ingestDialogPanel.processUnallocSpaceEnabled());
ModuleSettings.setConfigSetting(moduleContext, PARSE_UNALLOC, processUnalloc);
}
@Override
public void reload() {
loadSettings();
}
@Override
public boolean isIngestRunning() {
return manager.isIngestRunning();
}
private static String moduleListToCsv(List<IngestModuleAbstract> lst) {
if (lst == null || lst.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lst.size() - 1; ++i) {
sb.append(lst.get(i).getName()).append(", ");
}
// and the last one
sb.append(lst.get(lst.size() - 1).getName());
return sb.toString();
}
private static List<IngestModuleAbstract> csvToModuleList(String csv) {
List<IngestModuleAbstract> modules = new ArrayList<>();
if (csv == null || csv.isEmpty()) {
return modules;
}
String[] moduleNames = csv.split(", ");
List<IngestModuleAbstract> allModules = IngestManager.getDefault().enumerateAllModules();
for (String moduleName : moduleNames) {
for (IngestModuleAbstract module : allModules) {
if (moduleName.equals(module.getName())) {
modules.add(module);
break;
}
}
}
return modules;
}
private void loadSettings() {
// get the csv list of disabled modules
String disabledModulesCsv = ModuleSettings.getConfigSetting(moduleContext, DISABLED_MOD);
// create a list of modules from it
List<IngestModuleAbstract> disabledModules = csvToModuleList(disabledModulesCsv);
// tell the ingestDialogPanel to unselect these modules
ingestDialogPanel.setDisabledModules(disabledModules);
boolean processUnalloc = Boolean.parseBoolean(ModuleSettings.getConfigSetting(moduleContext, PARSE_UNALLOC));
ingestDialogPanel.setProcessUnallocSpaceEnabled(processUnalloc);
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -81,21 +81,17 @@ public abstract class AbstractDataResultViewer extends JPanel implements
// change the cursor to "waiting cursor" for this operation // change the cursor to "waiting cursor" for this operation
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try { try {
Node selectedNode = getSelectedNode(); Node[] selectedNodes = getExplorerManager().getSelectedNodes();
if (selectedNodes.length == 1) {
nodeSelected(selectedNodes[0]);
nodeSelected(selectedNode);
if (selectedNode != null) {
// there's a new/changed node to display // there's a new/changed node to display
Node newSelectedNode = selectedNode; // get the selected Node on the table
// push the node to default "DataContent" // push the node to default "DataContent"
//TODO only the active viewer should be calling setNode //TODO only the active viewer should be calling setNode
//not all of them, otherwise it results in multiple setNode() invocations //not all of them, otherwise it results in multiple setNode() invocations
//alternative is to use a single instance of the event listener //alternative is to use a single instance of the event listener
//, per top component and not the tab perhaps //, per top component and not the tab perhaps
contentViewer.setNode(newSelectedNode); contentViewer.setNode(selectedNodes[0]);
} else { } else {
// clear the node viewer // clear the node viewer
contentViewer.setNode(null); contentViewer.setNode(null);
@ -131,6 +127,7 @@ public abstract class AbstractDataResultViewer extends JPanel implements
} }
} }
@Deprecated
public Node getSelectedNode() { public Node getSelectedNode() {
Node result = null; Node result = null;
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes(); Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();

View File

@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.explorer.ExplorerUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.windows.TopComponent; import org.openide.windows.TopComponent;
import org.openide.nodes.Node; import org.openide.nodes.Node;
@ -260,6 +261,14 @@ public class DataResultTopComponent extends TopComponent implements DataResult {
super.componentOpened(); super.componentOpened();
this.dataResultPanel.open(); this.dataResultPanel.open();
List <DataResultViewer> resultViewers = this.dataResultPanel.getViewers();
for (DataResultViewer viewer : resultViewers) {
if (viewer instanceof DataResultViewerTable) {
associateLookup(ExplorerUtils.createLookup(((DataResultViewerTable)viewer).getExplorerManager(), getActionMap()));
break;
}
}
} }

View File

@ -62,7 +62,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
ov.setAllowedDropActions(DnDConstants.ACTION_NONE); ov.setAllowedDropActions(DnDConstants.ACTION_NONE);
// only allow one item to be selected at a time // only allow one item to be selected at a time
ov.getOutline().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); ov.getOutline().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// don't show the root node // don't show the root node
ov.getOutline().setRootVisible(false); ov.getOutline().setRootVisible(false);

View File

@ -19,12 +19,17 @@
package org.sleuthkit.autopsy.coreutils; package org.sleuthkit.autopsy.coreutils;
import java.io.*; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
/** /**
* This class contains the framework to read, add, update, and remove * This class contains the framework to read, add, update, and remove
* from the property files located at %USERDIR%/Config/x.properties * from the property files located at %USERDIR%/Config/x.properties
@ -35,12 +40,8 @@ public class ModuleSettings {
private final static String moduleDirPath = PlatformUtil.getUserConfigDirectory(); private final static String moduleDirPath = PlatformUtil.getUserConfigDirectory();
public static final String MAIN_SETTINGS = "Case"; public static final String MAIN_SETTINGS = "Case";
/** the constructor */ /** the constructor */
private ModuleSettings() { private ModuleSettings() {}
}
/** /**
* Makes a new config file of the specified name. Do not include the extension. * Makes a new config file of the specified name. Do not include the extension.
@ -162,8 +163,6 @@ public class ModuleSettings {
} }
} }
/** /**
* Sets the given properties file to the given setting map. * Sets the given properties file to the given setting map.
* @param moduleName - The name of the module to be written to. * @param moduleName - The name of the module to be written to.
@ -216,13 +215,11 @@ public class ModuleSettings {
} }
} }
/** /**
* Removes the given key from the given properties file. * Removes the given key from the given properties file.
* @param moduleName - The name of the properties file to be modified. * @param moduleName - The name of the properties file to be modified.
* @param key - the name of the key to remove. * @param key - the name of the key to remove.
*/ */
public static synchronized void removeProperty(String moduleName, String key){ public static synchronized void removeProperty(String moduleName, String key){
try{ try{
if(getConfigSetting(moduleName, key) != null){ if(getConfigSetting(moduleName, key) != null){
@ -268,5 +265,4 @@ public class ModuleSettings {
return new File(getPropertyPath(moduleName)); return new File(getPropertyPath(moduleName));
} }
} }
} }

View File

@ -23,7 +23,7 @@ import java.util.List;
import javax.swing.Action; import javax.swing.Action;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.TagAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.Directory;
@ -67,16 +67,16 @@ public class DirectoryNode extends AbstractFsContentNode<AbstractFile> {
*/ */
@Override @Override
public Action[] getActions(boolean popup) { public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<>();
if (!getDirectoryBrowseMode()) { if (!getDirectoryBrowseMode()) {
actions.add(new ViewContextAction("View File in Directory", this)); actions.add(new ViewContextAction("View File in Directory", this));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
} }
actions.add(new NewWindowViewAction("View in New Window", this)); actions.add(new NewWindowViewAction("View in New Window", this));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract Directory", this)); actions.add(ExtractAction.getInstance());
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(this)); actions.add(TagAbstractFileAction.getInstance());
return actions.toArray(new Action[0]); return actions.toArray(new Action[0]);
} }

9
Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java Normal file → Executable file
View File

@ -25,10 +25,9 @@ import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.TagAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM; import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM; import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
@ -74,7 +73,7 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
*/ */
@Override @Override
public Action[] getActions(boolean popup) { public Action[] getActions(boolean popup) {
List<Action> actionsList = new ArrayList<Action>(); List<Action> actionsList = new ArrayList<>();
if (!this.getDirectoryBrowseMode()) { if (!this.getDirectoryBrowseMode()) {
actionsList.add(new ViewContextAction("View File in Directory", this)); actionsList.add(new ViewContextAction("View File in Directory", this));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
@ -82,10 +81,10 @@ public class FileNode extends AbstractFsContentNode<AbstractFile> {
actionsList.add(new NewWindowViewAction("View in New Window", this)); actionsList.add(new NewWindowViewAction("View in New Window", this));
actionsList.add(new ExternalViewerAction("Open in External Viewer", this)); actionsList.add(new ExternalViewerAction("Open in External Viewer", this));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(new ExtractAction("Extract File", this)); actionsList.add(ExtractAction.getInstance());
actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this)); actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(new TagAction(this)); actionsList.add(TagAbstractFileAction.getInstance());
return actionsList.toArray(new Action[0]); return actionsList.toArray(new Action[0]);
} }

View File

@ -24,11 +24,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.swing.Action; import javax.swing.Action;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.TagAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction;
import org.sleuthkit.datamodel.LayoutFile; import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -104,14 +103,12 @@ public class LayoutFileNode extends AbstractAbstractFileNode<LayoutFile> {
@Override @Override
public Action[] getActions(boolean context) { public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<Action>(); List<Action> actionsList = new ArrayList<Action>();
actionsList.add(new NewWindowViewAction("View in New Window", this)); actionsList.add(new NewWindowViewAction("View in New Window", this));
actionsList.add(new ExternalViewerAction("Open in External Viewer", this)); actionsList.add(new ExternalViewerAction("Open in External Viewer", this));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(new ExtractAction("Extract File", content)); actionsList.add(ExtractAction.getInstance());
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(new TagAction(content)); actionsList.add(TagAbstractFileAction.getInstance());
return actionsList.toArray(new Action[0]); return actionsList.toArray(new Action[0]);
} }

View File

@ -30,9 +30,8 @@ import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.TagAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.LocalFile;
/** /**
* A Node for a LocalFile or DerivedFile content object. * A Node for a LocalFile or DerivedFile content object.
@ -86,16 +85,14 @@ public class LocalFileNode extends AbstractAbstractFileNode<AbstractFile> {
@Override @Override
public Action[] getActions(boolean context) { public Action[] getActions(boolean context) {
List<Action> actionsList = new ArrayList<Action>(); List<Action> actionsList = new ArrayList<>();
actionsList.add(new NewWindowViewAction("View in New Window", this)); actionsList.add(new NewWindowViewAction("View in New Window", this));
actionsList.add(new ExternalViewerAction("Open in External Viewer", this)); actionsList.add(new ExternalViewerAction("Open in External Viewer", this));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(new ExtractAction("Extract", content)); //might not need this actions - already local file actionsList.add(ExtractAction.getInstance());
actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this)); actionsList.add(new HashSearchAction("Search for files with the same MD5 hash", this));
actionsList.add(null); // creates a menu separator actionsList.add(null); // creates a menu separator
actionsList.add(new TagAction(content)); actionsList.add(TagAbstractFileAction.getInstance());
return actionsList.toArray(new Action[0]); return actionsList.toArray(new Action[0]);
} }

View File

@ -22,7 +22,6 @@ import java.awt.event.ActionEvent;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -656,36 +655,4 @@ public class Tags implements AutopsyVisitableItem {
return tagNames; return tagNames;
} }
public interface Taggable {
void createTag(String name, String comment);
}
public static class TaggableFile implements Taggable {
private AbstractFile file;
public TaggableFile(AbstractFile file) {
this.file = file;
}
@Override
public void createTag(String name, String comment) {
Tags.createTag(file, name, comment);
}
}
public static class TaggableBlackboardArtifact implements Taggable {
private BlackboardArtifact bba;
public TaggableBlackboardArtifact(BlackboardArtifact bba) {
this.bba = bba;
}
@Override
public void createTag(String name, String comment) {
Tags.createTag(bba, name, comment);
}
}
} }

View File

@ -27,7 +27,7 @@ import org.openide.nodes.Sheet;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.TagAction; import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction;
import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.datamodel.VirtualDirectory;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -76,13 +76,12 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode<VirtualDirect
*/ */
@Override @Override
public Action[] getActions(boolean popup) { public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<>();
actions.add(new NewWindowViewAction("View in New Window", this)); actions.add(new NewWindowViewAction("View in New Window", this));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract Directory", this)); actions.add(ExtractAction.getInstance());
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(this)); actions.add(TagAbstractFileAction.getInstance());
return actions.toArray(new Action[0]); return actions.toArray(new Action[0]);
} }

View File

@ -105,7 +105,7 @@ public class DataResultFilterNode extends FilterNode {
@Override @Override
public Action[] getActions(boolean popup) { public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<>();
final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal(); final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
actions.addAll(originalNode.accept(getActionsDIV)); actions.addAll(originalNode.accept(getActionsDIV));
@ -167,7 +167,7 @@ public class DataResultFilterNode extends FilterNode {
//TODO all actions need to be consolidated in single place! //TODO all actions need to be consolidated in single place!
//they should be set in individual Node subclass and using a utility to get Actions per Content sub-type //they should be set in individual Node subclass and using a utility to get Actions per Content sub-type
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<>();
//merge predefined specific node actions if bban subclasses have their own //merge predefined specific node actions if bban subclasses have their own
for (Action a : ban.getActions(true)) { for (Action a : ban.getActions(true)) {
@ -197,15 +197,15 @@ public class DataResultFilterNode extends FilterNode {
actions.add(new NewWindowViewAction("View in New Window", fn)); actions.add(new NewWindowViewAction("View in New Window", fn));
actions.add(new ExternalViewerAction("Open in External Viewer", fn)); actions.add(new ExternalViewerAction("Open in External Viewer", fn));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract File", new FileNode(f))); actions.add(ExtractAction.getInstance());
actions.add(new HashSearchAction("Search for files with the same MD5 hash", fn)); actions.add(new HashSearchAction("Search for files with the same MD5 hash", fn));
//add file/result tag if itself is not a tag //add file/result tag if itself is not a tag
if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
&& artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) { && artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) {
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(f)); actions.add(TagAbstractFileAction.getInstance());
actions.add(new TagAction(ba)); actions.add(TagBlackboardArtifactAction.getInstance());
} }
} }
if ((d = ban.getLookup().lookup(Directory.class)) != null) { if ((d = ban.getLookup().lookup(Directory.class)) != null) {
@ -214,14 +214,14 @@ public class DataResultFilterNode extends FilterNode {
actions.add(new NewWindowViewAction("View in New Window", dn)); actions.add(new NewWindowViewAction("View in New Window", dn));
actions.add(new ExternalViewerAction("Open in External Viewer", dn)); actions.add(new ExternalViewerAction("Open in External Viewer", dn));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract Directory", dn)); actions.add(ExtractAction.getInstance());
//add file/result tag if itself is not a tag //add file/result tag if itself is not a tag
if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
&& artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) { && artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) {
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(d)); actions.add(TagAbstractFileAction.getInstance());
actions.add(new TagAction(ba)); actions.add(TagBlackboardArtifactAction.getInstance());
} }
} }
if ((vd = ban.getLookup().lookup(VirtualDirectory.class)) != null) { if ((vd = ban.getLookup().lookup(VirtualDirectory.class)) != null) {
@ -230,14 +230,14 @@ public class DataResultFilterNode extends FilterNode {
actions.add(new NewWindowViewAction("View in New Window", dn)); actions.add(new NewWindowViewAction("View in New Window", dn));
actions.add(new ExternalViewerAction("Open in External Viewer", dn)); actions.add(new ExternalViewerAction("Open in External Viewer", dn));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract Directory", dn)); actions.add(ExtractAction.getInstance());
//add file/result tag if itself is not a tag //add file/result tag if itself is not a tag
if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
&& artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) { && artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) {
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(d)); actions.add(TagAbstractFileAction.getInstance());
actions.add(new TagAction(ba)); actions.add(TagBlackboardArtifactAction.getInstance());
} }
} else if ((lf = ban.getLookup().lookup(LayoutFile.class)) != null) { } else if ((lf = ban.getLookup().lookup(LayoutFile.class)) != null) {
LayoutFileNode lfn = new LayoutFileNode(lf); LayoutFileNode lfn = new LayoutFileNode(lf);
@ -245,14 +245,14 @@ public class DataResultFilterNode extends FilterNode {
actions.add(new NewWindowViewAction("View in New Window", lfn)); actions.add(new NewWindowViewAction("View in New Window", lfn));
actions.add(new ExternalViewerAction("Open in External Viewer", lfn)); actions.add(new ExternalViewerAction("Open in External Viewer", lfn));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract File", lfn)); actions.add(ExtractAction.getInstance());
//add tag if itself is not a tag //add tag if itself is not a tag
if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
&& artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) { && artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) {
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(lf)); actions.add(TagAbstractFileAction.getInstance());
actions.add(new TagAction(ba)); actions.add(TagBlackboardArtifactAction.getInstance());
} }
} else if ((locF = ban.getLookup().lookup(LocalFile.class)) != null } else if ((locF = ban.getLookup().lookup(LocalFile.class)) != null
|| (locF = ban.getLookup().lookup(DerivedFile.class)) != null) { || (locF = ban.getLookup().lookup(DerivedFile.class)) != null) {
@ -261,14 +261,14 @@ public class DataResultFilterNode extends FilterNode {
actions.add(new NewWindowViewAction("View in New Window", locfn)); actions.add(new NewWindowViewAction("View in New Window", locfn));
actions.add(new ExternalViewerAction("Open in External Viewer", locfn)); actions.add(new ExternalViewerAction("Open in External Viewer", locfn));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new ExtractAction("Extract File", locfn)); actions.add(ExtractAction.getInstance());
//add tag if itself is not a tag //add tag if itself is not a tag
if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() if (artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
&& artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) { && artifactTypeID != BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()) {
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(lf)); actions.add(TagAbstractFileAction.getInstance());
actions.add(new TagAction(ba)); actions.add(TagBlackboardArtifactAction.getInstance());
} }
} }
@ -278,7 +278,7 @@ public class DataResultFilterNode extends FilterNode {
@Override @Override
protected List<Action> defaultVisit(DisplayableItemNode ditem) { protected List<Action> defaultVisit(DisplayableItemNode ditem) {
//preserve the default node's actions //preserve the default node's actions
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<>();
for (Action action : ditem.getActions(true)) { for (Action action : ditem.getActions(true)) {
actions.add(action); actions.add(action);

View File

@ -99,8 +99,7 @@ class DirectoryTreeFilterNode extends FilterNode {
//extract dir action //extract dir action
Directory dir = this.getLookup().lookup(Directory.class); Directory dir = this.getLookup().lookup(Directory.class);
if (dir != null) { if (dir != null) {
actions.add(new ExtractAction("Extract Directory", actions.add(ExtractAction.getInstance());
getOriginal()));
} }
// file search action // file search action

View File

@ -101,39 +101,39 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default<List<? ext
@Override @Override
public List<? extends Action> visit(final Directory d) { public List<? extends Action> visit(final Directory d) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
actions.add(new TagAction(d)); actions.add(TagAbstractFileAction.getInstance());
return actions; return actions;
} }
@Override @Override
public List<? extends Action> visit(final VirtualDirectory d) { public List<? extends Action> visit(final VirtualDirectory d) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
actions.add(new TagAction(d)); actions.add(ExtractAction.getInstance());
actions.add(new ExtractAction("Extract Directory", d)); actions.add(TagAbstractFileAction.getInstance());
return actions; return actions;
} }
@Override @Override
public List<? extends Action> visit(final DerivedFile d) { public List<? extends Action> visit(final DerivedFile d) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
actions.add(new ExtractAction("Extract File", d)); actions.add(ExtractAction.getInstance());
actions.add(new TagAction(d)); actions.add(TagAbstractFileAction.getInstance());
return actions; return actions;
} }
@Override @Override
public List<? extends Action> visit(final LocalFile d) { public List<? extends Action> visit(final LocalFile d) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
actions.add(new ExtractAction("Extract File", d)); actions.add(ExtractAction.getInstance());
actions.add(new TagAction(d)); actions.add(TagAbstractFileAction.getInstance());
return actions; return actions;
} }
@Override @Override
public List<? extends Action> visit(final org.sleuthkit.datamodel.File d) { public List<? extends Action> visit(final org.sleuthkit.datamodel.File d) {
List<Action> actions = new ArrayList<Action>(); List<Action> actions = new ArrayList<Action>();
actions.add(new ExtractAction("Extract File", d)); actions.add(ExtractAction.getInstance());
actions.add(new TagAction(d)); actions.add(TagAbstractFileAction.getInstance());
return actions; return actions;
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.directorytree;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.io.File; import java.io.File;
import java.util.Collection;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
@ -30,81 +31,35 @@ import javax.swing.JOptionPane;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.nodes.Node;
import org.openide.util.Cancellable; import org.openide.util.Cancellable;
import org.openide.util.Utilities;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.FileUtil; import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor; import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory;
/** /**
* Exports files and folders * Exports files and folders
*/ */
public final class ExtractAction extends AbstractAction { public final class ExtractAction extends AbstractAction {
private static final InitializeContentVisitor initializeCV = new InitializeContentVisitor();
private AbstractFile content;
private Logger logger = Logger.getLogger(ExtractAction.class.getName()); private Logger logger = Logger.getLogger(ExtractAction.class.getName());
public ExtractAction(String title, Node contentNode) { // This class is a singleton to support multi-selection of nodes, since
super(title); // org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
Content tempContent = contentNode.getLookup().lookup(Content.class); // node in the array returns a reference to the same action object from Node.getActions(boolean).
private static ExtractAction instance;
this.content = tempContent.accept(initializeCV); public static synchronized ExtractAction getInstance() {
this.setEnabled(content != null); if (null == instance) {
instance = new ExtractAction();
} }
public ExtractAction(String title, Content content) { return instance;
super(title);
this.content = content.accept(initializeCV);
this.setEnabled(this.content != null);
} }
/** private ExtractAction() {
* Returns the FsContent if it is supported, otherwise null super("Extract");
*/
private static class InitializeContentVisitor extends ContentVisitor.Default<AbstractFile> {
@Override
public AbstractFile visit(org.sleuthkit.datamodel.File f) {
return f;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.LayoutFile lf) {
return lf;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.DerivedFile df) {
return df;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.LocalFile lf) {
return lf;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.VirtualDirectory vd) {
return vd;
}
@Override
public AbstractFile visit(Directory dir) {
return ContentUtils.isDotDirectory(dir) ? null : dir;
}
@Override
protected AbstractFile defaultVisit(Content cntnt) {
return null;
}
} }
/** /**
@ -114,10 +69,17 @@ public final class ExtractAction extends AbstractAction {
*/ */
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
for (AbstractFile file : selectedFiles) {
extractFile(e, file);
}
}
private void extractFile(ActionEvent e, AbstractFile file) {
// Get content and check that it's okay to overwrite existing content // Get content and check that it's okay to overwrite existing content
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File(Case.getCurrentCase().getCaseDirectory())); fc.setCurrentDirectory(new File(Case.getCurrentCase().getCaseDirectory()));
fc.setSelectedFile(new File(this.content.getName())); fc.setSelectedFile(new File(file.getName()));
int returnValue = fc.showSaveDialog((Component) e.getSource()); int returnValue = fc.showSaveDialog((Component) e.getSource());
if (returnValue == JFileChooser.APPROVE_OPTION) { if (returnValue == JFileChooser.APPROVE_OPTION) {
@ -144,7 +106,7 @@ public final class ExtractAction extends AbstractAction {
try { try {
ExtractFileThread extract = new ExtractFileThread(); ExtractFileThread extract = new ExtractFileThread();
extract.init(this.content, e, destination); extract.init(file, e, destination);
extract.execute(); extract.execute();
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.WARNING, "Unable to start background thread.", ex); logger.log(Level.WARNING, "Unable to start background thread.", ex);
@ -231,5 +193,4 @@ public final class ExtractAction extends AbstractAction {
} }
} }
} }
} }

View File

@ -0,0 +1,70 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent;
import java.util.Collection;
import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import org.openide.util.Utilities;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.datamodel.AbstractFile;
public class TagAbstractFileAction 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).
private static TagAbstractFileAction instance;
public static synchronized TagAbstractFileAction getInstance() {
if (null == instance) {
instance = new TagAbstractFileAction();
}
return instance;
}
private TagAbstractFileAction() {
}
@Override
public JMenuItem getPopupPresenter() {
return new TagAbstractFileMenu();
}
@Override
public void actionPerformed(ActionEvent e) {
// Do nothing - this action should never be performed.
// Submenu actions are invoked instead.
}
private static class TagAbstractFileMenu extends TagMenu {
public TagAbstractFileMenu() {
super(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class).size() > 1 ? "Tag Files" : "Tag File");
}
@Override
protected void applyTag(String tagName, String comment) {
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
for (AbstractFile file : selectedFiles) {
Tags.createTag(file, tagName, comment);
}
}
}
}

View File

@ -1,125 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import org.openide.nodes.Node;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.Directory;
/**
* Action on a file or artifact that adds a tag and
* reloads the directory tree. Supports tagging of AbstractFiles and
* BlackboardArtifacts.
*
* TODO add use enters description and hierarchy (TSK_TAG_NAME with slashes)
*/
public class TagAction extends AbstractAction implements Presenter.Popup {
private static final Logger logger = Logger.getLogger(TagAction.class.getName());
private JMenu tagMenu;
private final InitializeBookmarkFileV initializer = new InitializeBookmarkFileV();
public TagAction(Node contentNode) {
AbstractFile file = contentNode.getLookup().lookup(AbstractFile.class);
if (file != null) {
tagMenu = new TagMenu(file);
return;
}
BlackboardArtifact bba = contentNode.getLookup().lookup(BlackboardArtifact.class);
if (bba != null) {
tagMenu = new TagMenu(bba);
return;
}
logger.log(Level.SEVERE, "Tried to create a " + TagAction.class.getName()
+ " using a Node whose lookup did not contain an AbstractFile or a BlackboardArtifact.");
}
public TagAction(AbstractFile file) {
tagMenu = new TagMenu(file);
}
public TagAction(BlackboardArtifact bba) {
tagMenu = new TagMenu(bba);
}
@Override
public JMenuItem getPopupPresenter() {
return tagMenu;
}
/**
* Returns the FsContent if it is supported, otherwise null
*/
private static class InitializeBookmarkFileV extends ContentVisitor.Default<AbstractFile> {
@Override
public AbstractFile visit(org.sleuthkit.datamodel.File f) {
return f;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.LayoutFile lf) {
return lf;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.DerivedFile lf) {
return lf;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.LocalFile lf) {
return lf;
}
@Override
public AbstractFile visit(org.sleuthkit.datamodel.VirtualDirectory ld) {
return ld;
}
@Override
public AbstractFile visit(Directory dir) {
return ContentUtils.isDotDirectory(dir) ? null : dir;
}
@Override
protected AbstractFile defaultVisit(Content cntnt) {
return null;
}
}
@Override
public void actionPerformed(ActionEvent e) {
// Do nothing - this action should never be performed
// Submenu actions are invoked instead
}
}

View File

@ -30,28 +30,50 @@ import javax.swing.JFrame;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.datamodel.Tags; import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.autopsy.datamodel.Tags.Taggable;
import org.sleuthkit.datamodel.BlackboardArtifact;
/** /**
* Tag dialog for tagging files and results. User enters an optional comment. * Tag dialog for tagging files and results. User enters an optional comment.
*/ */
public class TagAndCommentDialog extends JDialog { public class TagAndCommentDialog extends JDialog {
private static final String TAG_ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png";
private static final String BOOKMARK_ICON_PATH = "org/sleuthkit/autopsy/images/star-bookmark-icon-16.png";
private static final String NO_TAG_MESSAGE = "No Tags"; private static final String NO_TAG_MESSAGE = "No Tags";
private String tagName = "";
private String comment = "";
private Taggable taggable; public static class CommentedTag {
private String name;
private String comment;
CommentedTag(String name, String comment) {
this.name = name;
this.comment = comment;
}
public String getName() {
return name;
}
public String getComment() {
return comment;
}
}
public static CommentedTag doDialog() {
TagAndCommentDialog dialog = new TagAndCommentDialog();
if (!dialog.tagName.isEmpty()) {
return new CommentedTag(dialog.tagName, dialog.comment);
}
else {
return null;
}
}
/** /**
* Creates new form TagDialog * Creates new form TagDialog
*/ */
public TagAndCommentDialog(Taggable taggable) { private TagAndCommentDialog() {
super((JFrame)WindowManager.getDefault().getMainWindow(), "Tag and Comment", true); super((JFrame)WindowManager.getDefault().getMainWindow(), "Tag and Comment", true);
this.taggable = taggable;
initComponents(); initComponents();
// Close the dialog when Esc is pressed // Close the dialog when Esc is pressed
@ -60,8 +82,8 @@ public class TagAndCommentDialog extends JDialog {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName);
ActionMap actionMap = getRootPane().getActionMap(); ActionMap actionMap = getRootPane().getActionMap();
actionMap.put(cancelName, new AbstractAction() { actionMap.put(cancelName, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
//doClose(RET_CANCEL);
dispose(); dispose();
} }
}); });
@ -82,14 +104,9 @@ public class TagAndCommentDialog extends JDialog {
//center it //center it
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
customizeComponent();
setVisible(true); // blocks setVisible(true); // blocks
} }
private void customizeComponent() {
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -195,22 +212,12 @@ public class TagAndCommentDialog extends JDialog {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
//doClose(RET_OK); tagName = (String)tagCombo.getSelectedItem();
comment = commentText.getText();
// get the selected tag and comment
String selectedTag = (String)tagCombo.getSelectedItem();
String comment = commentText.getText();
// create the tag
taggable.createTag(selectedTag, comment);
refreshDirectoryTree();
dispose(); dispose();
}//GEN-LAST:event_okButtonActionPerformed }//GEN-LAST:event_okButtonActionPerformed
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
//doClose(RET_CANCEL);
dispose(); dispose();
}//GEN-LAST:event_cancelButtonActionPerformed }//GEN-LAST:event_cancelButtonActionPerformed
@ -218,14 +225,12 @@ public class TagAndCommentDialog extends JDialog {
* Closes the dialog * Closes the dialog
*/ */
private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
//doClose(RET_CANCEL);
dispose(); dispose();
}//GEN-LAST:event_closeDialog }//GEN-LAST:event_closeDialog
private void newTagButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagButtonActionPerformed private void newTagButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagButtonActionPerformed
String newTagName = CreateTagDialog.getNewTagNameDialog(null); String newTagName = CreateTagDialog.getNewTagNameDialog(null);
if (newTagName != null) { if (newTagName != null) {
//tagsModel.addElement(newTagName);
tagCombo.addItem(newTagName); tagCombo.addItem(newTagName);
tagCombo.setSelectedItem(newTagName); tagCombo.setSelectedItem(newTagName);
} }
@ -240,12 +245,4 @@ public class TagAndCommentDialog extends JDialog {
private javax.swing.JComboBox tagCombo; private javax.swing.JComboBox tagCombo;
private javax.swing.JLabel tagLabel; private javax.swing.JLabel tagLabel;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
//private int returnStatus = RET_CANCEL;
private void refreshDirectoryTree() {
//TODO instead should send event to node children, which will call its refresh() / refreshKeys()
DirectoryTreeTopComponent viewer = DirectoryTreeTopComponent.findInstance();
viewer.refreshTree(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE);
viewer.refreshTree(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT);
}
} }

View File

@ -0,0 +1,71 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent;
import java.util.Collection;
import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import org.openide.util.Utilities;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.datamodel.BlackboardArtifact;
public class TagBlackboardArtifactAction 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).
private static TagBlackboardArtifactAction instance;
public static synchronized TagBlackboardArtifactAction getInstance() {
if (null == instance) {
instance = new TagBlackboardArtifactAction();
}
return instance;
}
private TagBlackboardArtifactAction() {
}
@Override
public JMenuItem getPopupPresenter() {
return new TagBlackboardArtifactMenu();
}
@Override
public void actionPerformed(ActionEvent e) {
// Do nothing - this action should never be performed.
// Submenu actions are invoked instead.
}
private static class TagBlackboardArtifactMenu extends TagMenu {
public TagBlackboardArtifactMenu() {
super(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class).size() > 1 ? "Tag Results" : "Tag Result");
}
@Override
protected void applyTag(String tagName, String comment) {
Collection<? extends BlackboardArtifact> selectedArtifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
for (BlackboardArtifact artifact : selectedArtifacts) {
Tags.createTag(artifact, tagName, comment);
}
}
}
}

View File

@ -24,38 +24,20 @@ import java.util.List;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import org.sleuthkit.autopsy.datamodel.Tags; import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.autopsy.datamodel.Tags.Taggable;
import org.sleuthkit.autopsy.datamodel.Tags.TaggableBlackboardArtifact;
import org.sleuthkit.autopsy.datamodel.Tags.TaggableFile;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
/** /**
* The menu that results when one right-clicks on a file or artifact. * The menu that results when one right-clicks on a file or artifact.
*/ */
public class TagMenu extends JMenu { public abstract class TagMenu extends JMenu {
public TagMenu(String menuItemText) {
super(menuItemText);
private Taggable tagCreator; // Create the 'Quick Tag' sub-menu and add it to the tag menu.
public TagMenu(AbstractFile file) {
super("Tag File");
tagCreator = new TaggableFile(file);
init();
}
public TagMenu(BlackboardArtifact bba) {
super("Tag Result");
tagCreator = new TaggableBlackboardArtifact(bba);
init();
}
private void init() {
// create the 'Quick Tag' menu and add it to the 'Tag File' menu
JMenu quickTagMenu = new JMenu("Quick Tag"); JMenu quickTagMenu = new JMenu("Quick Tag");
add(quickTagMenu); add(quickTagMenu);
// create the 'Quick Tag' sub-menu items and add them to the 'Quick Tag' menu // Get the existing tag names.
List<String> tagNames = Tags.getTagNames(); List<String> tagNames = Tags.getTagNames();
if (tagNames.isEmpty()) { if (tagNames.isEmpty()) {
JMenuItem empty = new JMenuItem("No tags"); JMenuItem empty = new JMenuItem("No tags");
@ -63,44 +45,48 @@ public class TagMenu extends JMenu {
quickTagMenu.add(empty); quickTagMenu.add(empty);
} }
// Add a menu item for each existing tag name to the 'Quick Tag' menu.
for (final String tagName : tagNames) { for (final String tagName : tagNames) {
JMenuItem tagItem = new JMenuItem(tagName); JMenuItem tagNameItem = new JMenuItem(tagName);
tagItem.addActionListener(new ActionListener() { tagNameItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
tagCreator.createTag(tagName, ""); applyTag(tagName, "");
refreshDirectoryTree(); refreshDirectoryTree();
} }
}); });
quickTagMenu.add(tagItem); quickTagMenu.add(tagNameItem);
} }
quickTagMenu.addSeparator(); quickTagMenu.addSeparator();
// create the 'New Tag' menu item // Create the 'New Tag' menu item and add it to the 'Quick Tag' menu.
JMenuItem newTagMenuItem = new JMenuItem("New Tag"); JMenuItem newTagMenuItem = new JMenuItem("New Tag");
newTagMenuItem.addActionListener(new ActionListener() { newTagMenuItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String newTagName = CreateTagDialog.getNewTagNameDialog(null); String tagName = CreateTagDialog.getNewTagNameDialog(null);
if (newTagName != null) { if (tagName != null) {
tagCreator.createTag(newTagName, ""); applyTag(tagName, "");
refreshDirectoryTree(); refreshDirectoryTree();
} }
} }
}); });
// add the 'New Tag' menu item to the 'Quick Tag' menu
quickTagMenu.add(newTagMenuItem); quickTagMenu.add(newTagMenuItem);
JMenuItem newTagItem = new JMenuItem("Tag and Comment"); // Create the 'Tag and Comment' menu item and add it to the tag menu.
newTagItem.addActionListener(new ActionListener() { JMenuItem tagAndCommentItem = new JMenuItem("Tag and Comment");
tagAndCommentItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
new TagAndCommentDialog(tagCreator); TagAndCommentDialog.CommentedTag commentedTag = TagAndCommentDialog.doDialog();
if (null != commentedTag) {
applyTag(commentedTag.getName(), commentedTag.getComment());
refreshDirectoryTree();
}
} }
}); });
add(newTagItem); add(tagAndCommentItem);
} }
private void refreshDirectoryTree() { private void refreshDirectoryTree() {
@ -109,4 +95,6 @@ public class TagMenu extends JMenu {
viewer.refreshTree(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE); viewer.refreshTree(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE);
viewer.refreshTree(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT); viewer.refreshTree(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT);
} }
protected abstract void applyTag(String tagName, String comment);
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -26,13 +26,14 @@ import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.util.List; import java.util.List;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.openide.util.Lookup;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.casemodule.IngestConfigurator;
/** /**
* IngestDialog shown on Case.CASE_ADD_IMAGE property change * IngestDialog shown on Case.CASE_ADD_IMAGE property change
@ -41,21 +42,18 @@ public class IngestDialog extends JDialog {
private static final String TITLE = "Ingest Modules"; private static final String TITLE = "Ingest Modules";
private static Dimension DIMENSIONS = new Dimension(500, 300); private static Dimension DIMENSIONS = new Dimension(500, 300);
private IngestDialogPanel panel = null; private IngestConfigurator ingestConfigurator;
private static final Logger logger = Logger.getLogger(IngestDialog.class.getName());
public IngestDialog(JFrame frame, String title, boolean modal) { public IngestDialog(JFrame frame, String title, boolean modal) {
super(frame, title, modal); super(frame, title, modal);
panel = new IngestDialogPanel(); ingestConfigurator = Lookup.getDefault().lookup(IngestConfigurator.class);
ingestConfigurator.reload();
} }
public IngestDialog(){ public IngestDialog(){
this(new JFrame(TITLE), TITLE, true); this(new JFrame(TITLE), TITLE, true);
} }
/** /**
* Shows the Ingest dialog. * Shows the Ingest dialog.
*/ */
@ -71,17 +69,14 @@ public class IngestDialog extends JDialog {
// set the location of the popUp Window on the center of the screen // set the location of the popUp Window on the center of the screen
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2); setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
panel.reload(); // reload the simple panel add(ingestConfigurator.getIngestConfigPanel(), BorderLayout.PAGE_START);
add(panel, BorderLayout.PAGE_START);
JButton startButton = new JButton("Start"); JButton startButton = new JButton("Start");
JButton closeButton = new JButton("Close"); JButton closeButton = new JButton("Close");
startButton.addActionListener(new ActionListener() { startButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ingestConfigurator.start();
panel.save();
panel.start();
close(); close();
} }
}); });
@ -89,7 +84,7 @@ public class IngestDialog extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
panel.save(); ingestConfigurator.save();
close(); close();
} }
}); });
@ -97,7 +92,7 @@ public class IngestDialog extends JDialog {
@Override @Override
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
panel.save(); ingestConfigurator.save();
close(); close();
} }
}); });
@ -115,10 +110,9 @@ public class IngestDialog extends JDialog {
} }
public void setContent(List<Content> inputContent) { public void setContent(List<Content> inputContent) {
panel.setContent(inputContent); ingestConfigurator.setContent(inputContent);
} }
/** /**
* Closes the Ingest dialog * Closes the Ingest dialog
*/ */
@ -126,6 +120,4 @@ public class IngestDialog extends JDialog {
setVisible(false); setVisible(false);
dispose(); dispose();
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,24 +18,15 @@
*/ */
package org.sleuthkit.autopsy.ingest; package org.sleuthkit.autopsy.ingest;
import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent; import java.util.AbstractMap;
import java.beans.PropertyChangeListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JPanel;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
@ -43,80 +34,47 @@ import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.IngestConfigurator;
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog; import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract.ModuleType;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* main configuration panel for all ingest modules, reusable JPanel component * main configuration panel for all ingest modules, reusable JPanel component
*/ */
@ServiceProvider(service = IngestConfigurator.class) public class IngestDialogPanel extends javax.swing.JPanel {
public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfigurator {
private IngestManager manager = null;
private List<IngestModuleAbstract> modules;
private IngestModuleAbstract currentModule; private IngestModuleAbstract currentModule;
private Map<String, Boolean> moduleStates;
private ModulesTableModel tableModel; private ModulesTableModel tableModel;
private static final Logger logger = Logger.getLogger(IngestDialogPanel.class.getName());
public static final String DISABLED_MOD = "Disabled_Ingest_Modules"; public static final String DISABLED_MOD = "Disabled_Ingest_Modules";
public static final String PARSE_UNALLOC = "Process_Unallocated_Space"; public static final String PARSE_UNALLOC = "Process_Unallocated_Space";
// The input content that's just been added to the database
private List<Content> inputContent;
// private static IngestDialogPanel instance = null;
/** /**
* Creates new form IngestDialogPanel * Creates new form IngestDialogPanel
*/ */
public IngestDialogPanel() { public IngestDialogPanel() {
tableModel = new ModulesTableModel(); tableModel = new ModulesTableModel();
modules = new ArrayList<IngestModuleAbstract>();
moduleStates = new HashMap<String, Boolean>();
initComponents(); initComponents();
customizeComponents(); customizeComponents();
} }
private void loadModules() { public IngestModuleAbstract getCurrentIngestModule() {
this.modules.clear(); return currentModule;
//this.moduleStates.clear(); maintain the state
Collection<IngestModuleDataSource> imageModules = manager.enumerateDataSourceModules();
for (final IngestModuleDataSource module : imageModules) {
addModule(module);
} }
Collection<IngestModuleAbstractFile> fsModules = manager.enumerateAbstractFileModules();
for (final IngestModuleAbstractFile module : fsModules) { public List<IngestModuleAbstract> getModulesToStart() {
addModule(module); return tableModel.getSelectedModules();
} }
public boolean processUnallocSpaceEnabled() {
return processUnallocCheckbox.isSelected();
} }
private void customizeComponents() { private void customizeComponents() {
modulesTable.setModel(tableModel); modulesTable.setModel(tableModel);
this.manager = IngestManager.getDefault();
loadModules();
try {
IngestModuleLoader.getDefault().addModulesReloadedListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(IngestModuleLoader.Event.ModulesReloaded.toString())) {
loadModules();
}
}
});
} catch (IngestModuleLoaderException ex) {
logger.log(Level.SEVERE, "Could not initialize ingest module loader to listen for module config changes", ex);
}
modulesTable.setTableHeader(null); modulesTable.setTableHeader(null);
modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//custom renderer for tooltips //custom renderer for tooltips
ModulesTableRenderer renderer = new ModulesTableRenderer(); ModulesTableRenderer renderer = new ModulesTableRenderer();
//customize column witdhs //customize column witdhs
final int width = modulesScrollPane.getPreferredSize().width; final int width = modulesScrollPane.getPreferredSize().width;
TableColumn column = null; TableColumn column = null;
@ -135,40 +93,30 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource(); ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
if (!listSelectionModel.isSelectionEmpty()) { if (!listSelectionModel.isSelectionEmpty()) {
save();
int index = listSelectionModel.getMinSelectionIndex(); int index = listSelectionModel.getMinSelectionIndex();
currentModule = modules.get(index); currentModule = tableModel.getModule(index);
reload();
// add the module-specific configuration panel, if there is one
simplePanel.removeAll();
if (currentModule.hasSimpleConfiguration()) {
simplePanel.add(currentModule.getSimpleConfiguration());
}
simplePanel.revalidate();
simplePanel.repaint();
advancedButton.setEnabled(currentModule.hasAdvancedConfiguration()); advancedButton.setEnabled(currentModule.hasAdvancedConfiguration());
} else { } else {
currentModule = null; currentModule = null;
} }
} }
}); });
processUnallocCheckbox.setSelected(manager.getProcessUnallocSpace());
} }
private void setProcessUnallocSpaceEnabled(boolean enabled) { public void setProcessUnallocSpaceEnabled(final boolean enabled) {
processUnallocCheckbox.setEnabled(enabled); processUnallocCheckbox.setSelected(enabled);
} }
@Override public void setDisabledModules(List<IngestModuleAbstract> disabledModules) {
public void paint(Graphics g) { tableModel.setUnselectedModules(disabledModules);
super.paint(g);
if (manager.isIngestRunning()) {
setProcessUnallocSpaceEnabled(false);
} else {
setProcessUnallocSpaceEnabled(true);
}
}
private void addModule(IngestModuleAbstract module) {
final String moduleName = module.getName();
modules.add(module);
moduleStates.put(moduleName, true);
} }
/** /**
@ -311,22 +259,19 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
dialog.close(); dialog.close();
currentModule.saveAdvancedConfiguration(); currentModule.saveAdvancedConfiguration();
reload();
} }
}); });
dialog.addWindowListener(new WindowAdapter() { dialog.addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
dialog.close(); dialog.close();
reload();
} }
}); });
save(); // save the simple panel dialog.display(currentModule.getAdvancedConfiguration());
dialog.display(currentModule.getAdvancedConfiguration(null));
}//GEN-LAST:event_advancedButtonActionPerformed }//GEN-LAST:event_advancedButtonActionPerformed
private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed
// TODO add your handling code here: // nothing to do here
}//GEN-LAST:event_processUnallocCheckboxActionPerformed }//GEN-LAST:event_processUnallocCheckboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton advancedButton; private javax.swing.JButton advancedButton;
@ -343,9 +288,18 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
private class ModulesTableModel extends AbstractTableModel { private class ModulesTableModel extends AbstractTableModel {
private List<Map.Entry<IngestModuleAbstract, Boolean>>moduleData = new ArrayList<>();
public ModulesTableModel() {
List<IngestModuleAbstract> modules = IngestManager.getDefault().enumerateAllModules();
for (IngestModuleAbstract ingestModuleAbstract : modules) {
moduleData.add(new AbstractMap.SimpleEntry<>(ingestModuleAbstract, Boolean.TRUE));
}
}
@Override @Override
public int getRowCount() { public int getRowCount() {
return modules.size(); return moduleData.size();
} }
@Override @Override
@ -355,11 +309,11 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
@Override @Override
public Object getValueAt(int rowIndex, int columnIndex) { public Object getValueAt(int rowIndex, int columnIndex) {
String name = modules.get(rowIndex).getName(); Map.Entry<IngestModuleAbstract, Boolean> entry = moduleData.get(rowIndex);
if (columnIndex == 0) { if (columnIndex == 0) {
return moduleStates.get(name); return entry.getValue();
} else { } else {
return name; return entry.getKey().getName();
} }
} }
@ -371,8 +325,7 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 0) { if (columnIndex == 0) {
moduleStates.put((String) getValueAt(rowIndex, 1), (Boolean) aValue); moduleData.get(rowIndex).setValue((Boolean)aValue);
} }
} }
@ -380,125 +333,69 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
public Class<?> getColumnClass(int c) { public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass(); return getValueAt(0, c).getClass();
} }
}
List<IngestModuleAbstract> getModulesToStart() { public List<IngestModuleAbstract> getSelectedModules() {
List<IngestModuleAbstract> modulesToStart = new ArrayList<IngestModuleAbstract>(); List<IngestModuleAbstract> selectedModules = new ArrayList<>();
for (IngestModuleAbstract module : modules) { for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
boolean moduleEnabled = moduleStates.get(module.getName()); if (entry.getValue().booleanValue()) {
if (moduleEnabled) { selectedModules.add(entry.getKey());
modulesToStart.add(module);
} }
} }
return modulesToStart; return selectedModules;
}
private boolean processUnallocSpaceEnabled() {
return processUnallocCheckbox.isEnabled();
} }
/** /**
* To be called whenever the next, close, or start buttons are pressed. * Sets the given modules as selected in the modules table
* * @param selectedModules
*/ */
@Override public void setSelectedModules(List<IngestModuleAbstract> selectedModules) {
public void save() { // unselect all modules
// Save the current module for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
if (currentModule != null && currentModule.hasSimpleConfiguration()) { entry.setValue(Boolean.FALSE);
currentModule.saveSimpleConfiguration();
} }
// Save this panel
List<String> modulesDisabled = new ArrayList<String>();
for (int i = 0; i < modulesTable.getRowCount(); i++) {
// Column 0 is always the module's checkbox (which is retreived as a boolean)
Boolean enabled = (Boolean) modulesTable.getValueAt(i, 0);
if (!enabled) {
// Column 1 is always the module name
String moduleName = (String) modulesTable.getValueAt(i, 1);
modulesDisabled.add(moduleName);
}
}
// Add all the enabled modules to the properties separated by a coma
String list = "";
for (int i = 0; i < modulesDisabled.size(); i++) {
list += modulesDisabled.get(i);
if (i + 1 < modulesDisabled.size()) {
list += ", ";
}
}
ModuleSettings.setConfigSetting(IngestManager.MODULE_PROPERTIES, DISABLED_MOD, list);
String processUnalloc = Boolean.toString(processUnallocCheckbox.isSelected());
ModuleSettings.setConfigSetting(IngestManager.MODULE_PROPERTIES, PARSE_UNALLOC, processUnalloc);
// select only the given modules
for (IngestModuleAbstract selectedModule : selectedModules) {
getEntryForModule(selectedModule).setValue(Boolean.TRUE);
}
// tell everyone about it
fireTableDataChanged();
} }
/** /**
* Called when the dialog needs to be reloaded. Most commonly used to * Sets the given modules as NOT selected in the modules table
* refresh the simple panel. * @param selectedModules
*
* Called every time this panel is displayed.
*/ */
@Override public void setUnselectedModules(List<IngestModuleAbstract> unselectedModules) {
public void reload() { // select all modules
// Reload the simple panel for (Map.Entry<IngestModuleAbstract, Boolean> entry : moduleData) {
if (this.modulesTable.getSelectedRow() != -1) { entry.setValue(Boolean.TRUE);
simplePanel.removeAll();
if (currentModule.hasSimpleConfiguration()) {
simplePanel.add(currentModule.getSimpleConfiguration(null));
}
simplePanel.revalidate();
simplePanel.repaint();
}
// Reload this panel
String list = ModuleSettings.getConfigSetting(IngestManager.MODULE_PROPERTIES, DISABLED_MOD);
if (list != null) { // if no property is found, list will be null
List<String> modulesDisabled = new ArrayList<String>(Arrays.asList(list.split(", ")));
// For every row, see if that module name is in the ArrayList
for (int i = 0; i < modulesTable.getRowCount(); i++) {
String moduleName = (String) modulesTable.getValueAt(i, 1);
if (modulesDisabled.contains(moduleName)) {
modulesTable.setValueAt(false, i, 0); // we found it, disable the module
} else {
modulesTable.setValueAt(true, i, 0); // not on disabled list, or a new module, enable it
}
}
}
String processUnalloc = ModuleSettings.getConfigSetting(IngestManager.MODULE_PROPERTIES, PARSE_UNALLOC);
if (processUnalloc != null) {
processUnallocCheckbox.setSelected(Boolean.parseBoolean(processUnalloc));
}
} }
@Override // unselect only the given modules
public JPanel getIngestConfigPanel() { for (IngestModuleAbstract unselectedModule : unselectedModules) {
this.reload(); getEntryForModule(unselectedModule).setValue(Boolean.FALSE);
return this;
} }
@Override // tell everyone about it
public void setContent(List<Content> inputContent) { fireTableDataChanged();
this.inputContent = inputContent;
} }
@Override public IngestModuleAbstract getModule(int row) {
public void start() { return moduleData.get(row).getKey();
//pick the modules
List<IngestModuleAbstract> modulesToStart = getModulesToStart();
//update ingest proc. unalloc space
if (processUnallocSpaceEnabled()) {
manager.setProcessUnallocSpace(processUnallocCheckbox.isSelected());
} }
if (!modulesToStart.isEmpty()) { private Map.Entry<IngestModuleAbstract, Boolean> getEntryForModule(IngestModuleAbstract module) {
manager.execute(modulesToStart, inputContent); Map.Entry<IngestModuleAbstract, Boolean> entry = null;
for (Map.Entry<IngestModuleAbstract, Boolean> anEntry : moduleData) {
if (anEntry.getKey().equals(module)) {
entry = anEntry;
break;
} }
} }
return entry;
@Override }
public boolean isIngestRunning() {
return manager.isIngestRunning();
} }
/** /**
@ -506,57 +403,26 @@ public class IngestDialogPanel extends javax.swing.JPanel implements IngestConfi
*/ */
private class ModulesTableRenderer extends DefaultTableCellRenderer { private class ModulesTableRenderer extends DefaultTableCellRenderer {
List<String> tooltips = new ArrayList<>();
public ModulesTableRenderer() {
List<IngestModuleAbstract> modules = IngestManager.getDefault().enumerateAllModules();
for (IngestModuleAbstract ingestModuleAbstract : modules) {
tooltips.add(ingestModuleAbstract.getDescription());
}
}
@Override @Override
public Component getTableCellRendererComponent( public Component getTableCellRendererComponent(
JTable table, Object value, JTable table, Object value,
boolean isSelected, boolean hasFocus, boolean isSelected, boolean hasFocus,
int row, int column) { int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
final Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (column == 1) { if (column == 1) {
//String moduleName = (String) table.getModel().getValueAt(row, column); setToolTipText(tooltips.get(row));
IngestModuleAbstract module = modules.get(row);
String moduleDescr = module.getDescription();
String toolTip = moduleDescr;
if (inputContent != null && module.getType().equals(ModuleType.DataSource)) {
//DataSource module accepts only data source, does not work on any child
//show warning to user and set fg red for that module
boolean isDataSource = true;
for (Content content : inputContent) {
try {
if (content.getParent() != null) {
isDataSource = false;
break;
} }
} catch (TskCoreException e) { return this;
logger.log(Level.SEVERE, "Error checking if module input content is parentless data source", e);
}
}
if (! isDataSource ) {
cell.setForeground(Color.red);
toolTip = toolTip + "<br />WARNING: this module will not run on current selection because it operates only on root-level data-source (such as Image, Filesets).";
}
else {
cell.setForeground(Color.black);
}
} //end data source
else {
cell.setForeground(Color.black);
}
//
setToolTipText("<html>" + toolTip+ "</html>");
}
return cell;
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012 Basis Technology Corp. * Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -154,8 +154,6 @@ public class IngestManager {
} catch (IngestModuleLoaderException ex) { } catch (IngestModuleLoaderException ex) {
logger.log(Level.SEVERE, "Error getting module loader"); logger.log(Level.SEVERE, "Error getting module loader");
} }
} }
/** /**
@ -243,7 +241,6 @@ public class IngestManager {
if (ui != null) { if (ui != null) {
ui.restoreMessages(); ui.restoreMessages();
} }
} }
/** /**
@ -346,8 +343,6 @@ public class IngestManager {
} }
} }
} }
//}
//AbstractFile ingester //AbstractFile ingester
boolean startAbstractFileIngester = false; boolean startAbstractFileIngester = false;
@ -421,7 +416,6 @@ public class IngestManager {
List<IngestDataSourceThread> toStop = new ArrayList<IngestDataSourceThread>(); List<IngestDataSourceThread> toStop = new ArrayList<IngestDataSourceThread>();
toStop.addAll(dataSourceIngesters); toStop.addAll(dataSourceIngesters);
for (IngestDataSourceThread dataSourceWorker : toStop) { for (IngestDataSourceThread dataSourceWorker : toStop) {
IngestModuleDataSource s = dataSourceWorker.getModule(); IngestModuleDataSource s = dataSourceWorker.getModule();
@ -440,7 +434,6 @@ public class IngestManager {
logger.log(Level.WARNING, "Exception while stopping module: " + s.getName(), e); logger.log(Level.WARNING, "Exception while stopping module: " + s.getName(), e);
} }
} }
} }
logger.log(Level.INFO, "stopped all"); logger.log(Level.INFO, "stopped all");
@ -545,7 +538,6 @@ public class IngestManager {
return module.hasBackgroundJobsRunning(); return module.hasBackgroundJobsRunning();
} }
} else { } else {
//data source module //data source module
synchronized (this) { synchronized (this) {
@ -570,10 +562,7 @@ public class IngestManager {
return false; return false;
} }
} }
} }
} }
/** /**
@ -607,7 +596,7 @@ public class IngestManager {
* *
* @param processUnallocSpace * @param processUnallocSpace
*/ */
void setProcessUnallocSpace(boolean processUnallocSpace) { public void setProcessUnallocSpace(boolean processUnallocSpace) {
this.processUnallocSpace = processUnallocSpace; this.processUnallocSpace = processUnallocSpace;
} }
@ -672,6 +661,13 @@ public class IngestManager {
return moduleLoader.getAbstractFileIngestModules(); return moduleLoader.getAbstractFileIngestModules();
} }
public List<IngestModuleAbstract> enumerateAllModules() {
List<IngestModuleAbstract> modules = new ArrayList<>();
modules.addAll(enumerateDataSourceModules());
modules.addAll(enumerateAbstractFileModules());
return modules;
}
//data source worker to remove itself when complete or interrupted //data source worker to remove itself when complete or interrupted
void removeDataSourceIngestWorker(IngestDataSourceThread worker) { void removeDataSourceIngestWorker(IngestDataSourceThread worker) {
//remove worker //remove worker
@ -697,7 +693,6 @@ public class IngestManager {
IngestManagerStats() { IngestManagerStats() {
errors = new HashMap<IngestModuleAbstract, Integer>(); errors = new HashMap<IngestModuleAbstract, Integer>();
} }
/** /**
@ -775,19 +770,8 @@ public class IngestManager {
public String toHtmlString() { public String toHtmlString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("<html><body>"); sb.append("<html><body>");
sb.append("Ingest time: ").append(getTotalTimeString()).append("<br />"); sb.append("Ingest time: ").append(getTotalTimeString()).append("<br />");
sb.append("Total errors: ").append(errorsTotal).append("<br />"); sb.append("Total errors: ").append(errorsTotal).append("<br />");
/*
if (errorsTotal > 0) {
sb.append("Errors per module:");
for (IngestModuleAbstract module : errors.keySet()) {
final int errorsModule = errors.get(module);
sb.append("\t").append(module.getName()).append(": ").append(errorsModule).append("<br />");
}
}
* */
sb.append("</body></html>"); sb.append("</body></html>");
return sb.toString(); return sb.toString();
} }

View File

@ -146,34 +146,27 @@ public abstract class IngestModuleAbstract {
public void saveAdvancedConfiguration() {} public void saveAdvancedConfiguration() {}
/** /**
* Returns a panel that displays the simple (run-time) configuration * Returns a panel that displays the simple (run-time) configuration.
* for the given configuration context (such as pipeline instance).
* This is presented to the user before ingest starts and only basic * This is presented to the user before ingest starts and only basic
* settings should be given here. Use the advanced (general) configuration * settings should be given here. use the advanced (general) configuration
* panel for more in-depth interfaces. * panel for more in-depth interfaces.
* The module (or its configuration controller object) is responsible for preserving / saving its configuration state * The module is responsible for preserving / saving its configuration state
* In addition, saveSimpleConfiguration() can be used as the trigger. * In addition, saveSimpleConfiguration() can be used
* *
* @param context the configuration context to use in the panel
* @return JPanel containing basic configuration widgets or null if simple configuration is not available * @return JPanel containing basic configuration widgets or null if simple configuration is not available
*/ */
public javax.swing.JPanel getSimpleConfiguration(String context) { public javax.swing.JPanel getSimpleConfiguration() {
return null; return null;
} }
/** /**
* Returns a panel that displays the advanced (run-time) configuration * Implements advanced module configuration exposed to the user before ingest starts
* for the given configuration context (such as pipeline instance). * The module is responsible for preserving / saving its configuration state
* Implements advanced module configuration exposed to the user before ingest starts. * In addition, saveAdvancedConfiguration() can be used
* *
* The module (or its configuration controller object) * @return JPanel containing basic configuration widgets or null if advanced configuration is not available
* is responsible for preserving / saving its configuration state
* In addition, saveAdvancedConfiguration() can be used as the trigger.
*
* @param context the configuration context to use in the panel
* @return JPanel containing advanced configuration widgets or null if advanced configuration is not available
*/ */
public javax.swing.JPanel getAdvancedConfiguration(String context) { public javax.swing.JPanel getAdvancedConfiguration() {
return null; return null;
}; };
} }

View File

@ -216,13 +216,13 @@ public class HashDbIngestModule extends IngestModuleAbstractFile {
} }
@Override @Override
public javax.swing.JPanel getSimpleConfiguration(String context) { public javax.swing.JPanel getSimpleConfiguration() {
HashDbXML.getCurrent().reload(); HashDbXML.getCurrent().reload();
return new HashDbSimplePanel(); return new HashDbSimplePanel();
} }
@Override @Override
public javax.swing.JPanel getAdvancedConfiguration(String context) { public javax.swing.JPanel getAdvancedConfiguration() {
//return HashDbManagementPanel.getDefault(); //return HashDbManagementPanel.getDefault();
getPanel().load(); getPanel().load();
return getPanel(); return getPanel();

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011 Basis Technology Corp. * Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -28,9 +28,9 @@ import org.openide.nodes.PropertySupport;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup; import org.openide.util.lookup.ProxyLookup;
import org.sleuthkit.autopsy.directorytree.TagAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.TagAbstractFileAction;
import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -128,8 +128,6 @@ class KeywordSearchFilterNode extends FilterNode {
Content content = this.getOriginal().getLookup().lookup(Content.class); Content content = this.getOriginal().getLookup().lookup(Content.class);
actions.addAll(content.accept(new GetPopupActionsContentVisitor())); actions.addAll(content.accept(new GetPopupActionsContentVisitor()));
//actions.add(new IndexContentFilesAction(nodeContent, "Index"));
return actions.toArray(new Action[actions.size()]); return actions.toArray(new Action[actions.size()]);
} }
@ -137,33 +135,29 @@ class KeywordSearchFilterNode extends FilterNode {
@Override @Override
public List<Action> visit(File f) { public List<Action> visit(File f) {
List<Action> actions = new ArrayList<Action>(); return getFileActions();
actions.add(new NewWindowViewAction("View in New Window", KeywordSearchFilterNode.this));
actions.add(new ExternalViewerAction("Open in External Viewer", getOriginal()));
actions.add(null);
actions.add(new ExtractAction("Extract File", getOriginal()));
actions.add(new HashSearchAction("Search for files with the same MD5 hash", getOriginal()));
actions.add(null); // creates a menu separator
actions.add(new TagAction(getOriginal()));
return actions;
} }
@Override @Override
public List<Action> visit(DerivedFile f) { public List<Action> visit(DerivedFile f) {
List<Action> actions = new ArrayList<Action>(); return getFileActions();
}
private List<Action> getFileActions() {
List<Action> actions = new ArrayList<>();
actions.add(new NewWindowViewAction("View in New Window", KeywordSearchFilterNode.this)); actions.add(new NewWindowViewAction("View in New Window", KeywordSearchFilterNode.this));
actions.add(new ExternalViewerAction("Open in External Viewer", getOriginal())); actions.add(new ExternalViewerAction("Open in External Viewer", getOriginal()));
actions.add(null); actions.add(null);
actions.add(new ExtractAction("Extract File", getOriginal())); actions.add(ExtractAction.getInstance());
actions.add(new HashSearchAction("Search for files with the same MD5 hash", getOriginal())); actions.add(new HashSearchAction("Search for files with the same MD5 hash", getOriginal()));
actions.add(null); // creates a menu separator actions.add(null); // creates a menu separator
actions.add(new TagAction(getOriginal())); actions.add(TagAbstractFileAction.getInstance());
return actions; return actions;
} }
@Override @Override
protected List<Action> defaultVisit(Content c) { protected List<Action> defaultVisit(Content c) {
return new ArrayList<Action>(); return new ArrayList<>();
} }
} }
} }

View File

@ -432,13 +432,13 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
} }
@Override @Override
public javax.swing.JPanel getSimpleConfiguration(String context) { public javax.swing.JPanel getSimpleConfiguration() {
KeywordSearchListsXML.getCurrent().reload(); KeywordSearchListsXML.getCurrent().reload();
return new KeywordSearchIngestSimplePanel(); return new KeywordSearchIngestSimplePanel();
} }
@Override @Override
public javax.swing.JPanel getAdvancedConfiguration(String context) { public javax.swing.JPanel getAdvancedConfiguration() {
//return KeywordSearchConfigurationPanel.getDefault(); //return KeywordSearchConfigurationPanel.getDefault();
getPanel().load(); getPanel().load();
return getPanel(); return getPanel();