Merge pull request #602 from rcordovano/parallel_file_ingest

Parallel file ingest
This commit is contained in:
Richard Cordovano 2014-04-09 11:19:36 -04:00
commit 379b1ddfc3
7 changed files with 118 additions and 149 deletions

View File

@ -73,6 +73,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskException; import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
/** /**
* Top component which displays something. * Top component which displays something.
*/ */
@ -82,7 +83,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
private transient ExplorerManager em = new ExplorerManager(); private transient ExplorerManager em = new ExplorerManager();
private static DirectoryTreeTopComponent instance; private static DirectoryTreeTopComponent instance;
private DataResultTopComponent dataResult = new DataResultTopComponent(true, NbBundle.getMessage(this.getClass(), private DataResultTopComponent dataResult = new DataResultTopComponent(true, NbBundle.getMessage(this.getClass(),
"DirectoryTreeTopComponent.title.text")); "DirectoryTreeTopComponent.title.text"));
private LinkedList<String[]> backList; private LinkedList<String[]> backList;
private LinkedList<String[]> forwardList; private LinkedList<String[]> forwardList;
/** /**
@ -222,12 +223,12 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
private void backButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backButtonActionPerformed private void backButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backButtonActionPerformed
// change the cursor to "waiting cursor" for this operation // change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
// the end is the current place, // the end is the current place,
String[] currentNodePath = backList.pollLast(); String[] currentNodePath = backList.pollLast();
forwardList.addLast(currentNodePath); forwardList.addLast(currentNodePath);
forwardButton.setEnabled(true); forwardButton.setEnabled(true);
/* We peek instead of poll because we use its existence /* We peek instead of poll because we use its existence
* in the list later on so that we do not reset the forward list * in the list later on so that we do not reset the forward list
* after the selection occurs. */ * after the selection occurs. */
@ -239,7 +240,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
} else { } else {
backButton.setEnabled(false); backButton.setEnabled(false);
} }
// update the selection on directory tree // update the selection on directory tree
setSelectedNode(newCurrentNodePath, null); setSelectedNode(newCurrentNodePath, null);
@ -256,10 +257,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
} else { } else {
forwardButton.setEnabled(false); forwardButton.setEnabled(false);
} }
backList.addLast(newCurrentNodePath); backList.addLast(newCurrentNodePath);
backButton.setEnabled(true); backButton.setEnabled(true);
// update the selection on directory tree // update the selection on directory tree
setSelectedNode(newCurrentNodePath, null); setSelectedNode(newCurrentNodePath, null);
@ -543,8 +544,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
// The current case has been closed. Reset the ExplorerManager. // The current case has been closed. Reset the ExplorerManager.
Node emptyNode = new AbstractNode(Children.LEAF); Node emptyNode = new AbstractNode(Children.LEAF);
em.setRootContext(emptyNode); em.setRootContext(emptyNode);
} } else if (newValue != null) {
else if (newValue != null) {
// A new case has been opened. Reset the forward and back // A new case has been opened. Reset the forward and back
// buttons. Note that a call to CoreComponentControl.openCoreWindows() // buttons. Note that a call to CoreComponentControl.openCoreWindows()
// by the new Case object will lead to a componentOpened() call // by the new Case object will lead to a componentOpened() call
@ -598,7 +598,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
refreshTree(event.getArtifactType()); refreshTree(event.getArtifactType());
} }
}); });
} else if (changed.equals(IngestEvent.COMPLETED.toString())) { } else if (changed.equals(IngestEvent.INGEST_JOB_COMPLETED.toString())
|| changed.equals(IngestEvent.INGEST_JOB_CANCELLED.toString())) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -654,7 +655,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
return; return;
} }
Node originNode = origin.getNode(); Node originNode = origin.getNode();
//set node, wrap in filter node first to filter out children //set node, wrap in filter node first to filter out children
Node drfn = new DataResultFilterNode(originNode, DirectoryTreeTopComponent.this.em); Node drfn = new DataResultFilterNode(originNode, DirectoryTreeTopComponent.this.em);
Node kffn = new KnownFileFilterNode(drfn, KnownFileFilterNode.getSelectionContext(originNode)); Node kffn = new KnownFileFilterNode(drfn, KnownFileFilterNode.getSelectionContext(originNode));
@ -667,9 +668,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
displayName = content.getUniquePath(); displayName = content.getUniquePath();
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Exception while calling Content.getUniquePath() for node: " + originNode); logger.log(Level.SEVERE, "Exception while calling Content.getUniquePath() for node: " + originNode);
} }
} } else if (originNode.getLookup().lookup(String.class) != null) {
else if (originNode.getLookup().lookup(String.class) != null) {
displayName = originNode.getLookup().lookup(String.class); displayName = originNode.getLookup().lookup(String.class);
} }
dataResult.setPath(displayName); dataResult.setPath(displayName);
@ -695,12 +695,12 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
// update the back and forward list // update the back and forward list
updateHistory(em.getSelectedNodes()); updateHistory(em.getSelectedNodes());
} }
private void updateHistory(Node[] selectedNodes) { private void updateHistory(Node[] selectedNodes) {
if (selectedNodes.length == 0) { if (selectedNodes.length == 0) {
return; return;
} }
Node selectedNode = selectedNodes[0]; Node selectedNode = selectedNodes[0];
String selectedNodeName = selectedNode.getName(); String selectedNodeName = selectedNode.getName();
@ -729,7 +729,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
forwardButton.setEnabled(false); // disable the forward Button forwardButton.setEnabled(false); // disable the forward Button
} }
} }
/** /**
* Resets the back and forward list, and also disable the back and forward * Resets the back and forward list, and also disable the back and forward
* buttons. * buttons.
@ -752,8 +752,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
pcs.removePropertyChangeListener(listener); pcs.removePropertyChangeListener(listener);
} }
/** /**
* Gets the tree on this DirectoryTreeTopComponent. * Gets the tree on this DirectoryTreeTopComponent.
* *
@ -768,13 +766,13 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
*/ */
public void refreshContentTreeSafe() { public void refreshContentTreeSafe() {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
refreshContentTree(); refreshContentTree();
} }
}); });
} }
/** /**
* Refreshes changed content nodes * Refreshes changed content nodes
*/ */
@ -865,7 +863,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
/** /**
* Set the selected node using a path to a previously selected node. * Set the selected node using a path to a previously selected node.
* *
* @param previouslySelectedNodePath Path to a previously selected node. * @param previouslySelectedNodePath Path to a previously selected node.
* @param rootNodeName Name of the root node to match, may be null. * @param rootNodeName Name of the root node to match, may be null.
*/ */
private void setSelectedNode(final String[] previouslySelectedNodePath, final String rootNodeName) { private void setSelectedNode(final String[] previouslySelectedNodePath, final String rootNodeName) {
@ -876,28 +874,26 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
@Override @Override
public void run() { public void run() {
if (previouslySelectedNodePath.length > 0 && (rootNodeName == null || previouslySelectedNodePath[0].equals(rootNodeName))) { if (previouslySelectedNodePath.length > 0 && (rootNodeName == null || previouslySelectedNodePath[0].equals(rootNodeName))) {
Node selectedNode = null; Node selectedNode = null;
ArrayList<String> selectedNodePath = new ArrayList<>(Arrays.asList(previouslySelectedNodePath)); ArrayList<String> selectedNodePath = new ArrayList<>(Arrays.asList(previouslySelectedNodePath));
while (null == selectedNode && !selectedNodePath.isEmpty()) { while (null == selectedNode && !selectedNodePath.isEmpty()) {
try { try {
selectedNode = NodeOp.findPath(em.getRootContext(), selectedNodePath.toArray(new String[0])); selectedNode = NodeOp.findPath(em.getRootContext(), selectedNodePath.toArray(new String[0]));
} } catch (NodeNotFoundException ex) {
catch (NodeNotFoundException ex) {
// The selected node may have been deleted (e.g., a deleted tag), so truncate the path and try again. // The selected node may have been deleted (e.g., a deleted tag), so truncate the path and try again.
if (selectedNodePath.size() > 1) { if (selectedNodePath.size() > 1) {
selectedNodePath.remove(selectedNodePath.size() - 1); selectedNodePath.remove(selectedNodePath.size() - 1);
} } else {
else {
StringBuilder nodePath = new StringBuilder(); StringBuilder nodePath = new StringBuilder();
for (int i = 0; i < previouslySelectedNodePath.length; ++i) { for (int i = 0; i < previouslySelectedNodePath.length; ++i) {
nodePath.append(previouslySelectedNodePath[i]).append("/"); nodePath.append(previouslySelectedNodePath[i]).append("/");
} }
logger.log(Level.WARNING, "Failed to find any nodes to select on path " + nodePath.toString(), ex); logger.log(Level.WARNING, "Failed to find any nodes to select on path " + nodePath.toString(), ex);
break; break;
} }
} }
} }
if (null != selectedNode) { if (null != selectedNode) {
if (rootNodeName != null) { if (rootNodeName != null) {
//called from tree auto refresh context //called from tree auto refresh context
@ -905,9 +901,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
backList.pollLast(); backList.pollLast();
} }
try { try {
em.setExploredContextAndSelection(selectedNode, new Node[]{selectedNode}); em.setExploredContextAndSelection(selectedNode, new Node[]{selectedNode});
} } catch (PropertyVetoException ex) {
catch (PropertyVetoException ex) {
logger.log(Level.WARNING, "Property veto from ExplorerManager setting selection to " + selectedNode.getName(), ex); logger.log(Level.WARNING, "Property veto from ExplorerManager setting selection to " + selectedNode.getName(), ex);
} }
} }
@ -970,11 +965,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
} catch (TskException ex) { } catch (TskException ex) {
logger.log(Level.WARNING, "Error retrieving attributes", ex); logger.log(Level.WARNING, "Error retrieving attributes", ex);
} }
} else if ( type.equals(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT) || } else if (type.equals(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT)
type.equals(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT) ) { || type.equals(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT)) {
Node interestingItemsRootNode = resultsChilds.findChild(type.getLabel()); Node interestingItemsRootNode = resultsChilds.findChild(type.getLabel());
Children interestingItemsRootChildren = interestingItemsRootNode.getChildren(); Children interestingItemsRootChildren = interestingItemsRootNode.getChildren();
try { try {
String setName = null; String setName = null;
List<BlackboardAttribute> attributes = art.getAttributes(); List<BlackboardAttribute> attributes = art.getAttributes();
for (BlackboardAttribute att : attributes) { for (BlackboardAttribute att : attributes) {
@ -1030,16 +1025,15 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
} }
void fireViewerComplete() { void fireViewerComplete() {
try { try {
firePropertyChange(BlackboardResultViewer.FINISHED_DISPLAY_EVT, 0, 1); firePropertyChange(BlackboardResultViewer.FINISHED_DISPLAY_EVT, 0, 1);
} } catch (Exception e) {
catch (Exception e) {
logger.log(Level.SEVERE, "DirectoryTreeTopComponent listener threw exception", e); logger.log(Level.SEVERE, "DirectoryTreeTopComponent listener threw exception", e);
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "DirectoryTreeTopComponent.moduleErr"), MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "DirectoryTreeTopComponent.moduleErr"),
NbBundle.getMessage(this.getClass(), NbBundle.getMessage(this.getClass(),
"DirectoryTreeTopComponent.moduleErr.msg"), "DirectoryTreeTopComponent.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR); MessageNotifyUtil.MessageType.ERROR);
} }
} }
} }

View File

@ -89,7 +89,7 @@ final class FileIngestPipeline {
} }
file.close(); file.close();
if (!job.isCancelled()) { if (!job.isCancelled()) {
IngestManager.fireFileDone(file.getId()); IngestManager.fireFileIngestDone(file.getId());
} }
return errors; return errors;
} }

View File

@ -133,7 +133,7 @@ public class IngestManager {
} }
} }
synchronized void cancelIngestJobs() { void cancelIngestJobs() {
new IngestCancellationWorker().execute(); new IngestCancellationWorker().execute();
} }
@ -143,29 +143,24 @@ public class IngestManager {
public enum IngestEvent { public enum IngestEvent {
/** /**
* Event sent when an ingest module has been started. Second argument of * Property change event fired when an ingest job is started. The ingest
* the property change is a string form of the module name and the third * job id is in old value field of the PropertyChangeEvent object.
* argument is null.
*/ */
STARTED, INGEST_JOB_STARTED,
/** /**
* Event sent when an ingest module has completed processing by its own * Property change event fired when an ingest job is completed. The
* means. Second argument of the property change is a string form of the * ingest job id is in old value field of the PropertyChangeEvent
* module name and the third argument is null. * object.
*
* This event is generally used by listeners to perform a final data
* view refresh (listeners need to query all data from the blackboard).
*/ */
COMPLETED, INGEST_JOB_COMPLETED,
/** /**
* Event sent when an ingest module has stopped processing, and likely * Property change event fired when an ingest job is canceled. The
* not all data has been processed. Second argument of the property * ingest job id is in old value field of the PropertyChangeEvent
* change is a string form of the module name and third argument is * object.
* null.
*/ */
STOPPED, INGEST_JOB_CANCELLED,
/** /**
* Event sent when ingest module posts new data to blackboard or * Event sent when an ingest module posts new data to blackboard or
* somewhere else. Second argument of the property change fired contains * somewhere else. Second argument of the property change fired contains
* ModuleDataEvent object and third argument is null. The object can * ModuleDataEvent object and third argument is null. The object can
* contain encapsulated new data created by the module. Listener can * contain encapsulated new data created by the module. Listener can
@ -198,9 +193,9 @@ public class IngestManager {
pcs.removePropertyChangeListener(listener); pcs.removePropertyChangeListener(listener);
} }
static void fireModuleEvent(String eventType, String moduleName) { static void fireIngestJobEvent(String eventType, long jobId) {
try { try {
pcs.firePropertyChange(eventType, moduleName, null); pcs.firePropertyChange(eventType, jobId, null);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Ingest manager listener threw exception", e); logger.log(Level.SEVERE, "Ingest manager listener threw exception", e);
MessageNotifyUtil.Notify.show(NbBundle.getMessage(IngestManager.class, "IngestManager.moduleErr"), MessageNotifyUtil.Notify.show(NbBundle.getMessage(IngestManager.class, "IngestManager.moduleErr"),
@ -212,11 +207,11 @@ public class IngestManager {
/** /**
* Fire event when file is done with a pipeline run * Fire event when file is done with a pipeline run
* *
* @param objId ID of file that is done * @param fileId ID of file that is done
*/ */
static void fireFileDone(long objId) { static void fireFileIngestDone(long fileId) {
try { try {
pcs.firePropertyChange(IngestEvent.FILE_DONE.toString(), objId, null); pcs.firePropertyChange(IngestEvent.FILE_DONE.toString(), fileId, null);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Ingest manager listener threw exception", e); logger.log(Level.SEVERE, "Ingest manager listener threw exception", e);
MessageNotifyUtil.Notify.show(NbBundle.getMessage(IngestManager.class, "IngestManager.moduleErr"), MessageNotifyUtil.Notify.show(NbBundle.getMessage(IngestManager.class, "IngestManager.moduleErr"),
@ -340,7 +335,8 @@ public class IngestManager {
} }
for (Long jobId : completedJobs) { for (Long jobId : completedJobs) {
ingestJobs.remove(jobId); IngestJob job = ingestJobs.remove(jobId);
fireIngestJobEvent(job.isCancelled() ? IngestEvent.INGEST_JOB_CANCELLED.toString() : IngestEvent.INGEST_JOB_COMPLETED.toString(), jobId);
} }
} }
@ -375,7 +371,7 @@ public class IngestManager {
}); });
progress.start(2 * dataSources.size()); progress.start(2 * dataSources.size());
int processed = 0; int workUnitsCompleted = 0;
for (Content dataSource : dataSources) { for (Content dataSource : dataSources) {
if (Thread.currentThread().isInterrupted()) { if (Thread.currentThread().isInterrupted()) {
break; break;
@ -411,17 +407,18 @@ public class IngestManager {
// Queue the data source ingest tasks for the ingest job. // Queue the data source ingest tasks for the ingest job.
final String inputName = dataSource.getName(); final String inputName = dataSource.getName();
progress.progress("DataSource Ingest" + " " + inputName, processed); progress.progress("Data source ingest tasks for " + inputName, workUnitsCompleted); // RJCTODO: Improve
scheduler.getDataSourceScheduler().schedule(ingestJob); scheduler.getDataSourceScheduler().schedule(ingestJob);
progress.progress("DataSource Ingest" + " " + inputName, ++processed); progress.progress("Data source ingest tasks for " + inputName, ++workUnitsCompleted);
// Queue the file ingest tasks for the ingest job. // Queue the file ingest tasks for the ingest job.
progress.progress("File Ingest" + " " + inputName, processed); progress.progress("Data source ingest tasks for " + inputName, workUnitsCompleted);
scheduler.getFileScheduler().scheduleIngestOfFiles(ingestJob); scheduler.getFileScheduler().scheduleIngestOfFiles(ingestJob);
progress.progress("File Ingest" + " " + inputName, ++processed); progress.progress("Data source ingest tasks for " + inputName, ++workUnitsCompleted);
if (!Thread.currentThread().isInterrupted()) { if (!Thread.currentThread().isInterrupted()) {
startIngestTasks(); startIngestTasks();
fireIngestJobEvent(IngestEvent.INGEST_JOB_STARTED.toString(), ingestJob.getId());
} }
} }
} catch (Exception ex) { } catch (Exception ex) {

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.hashdatabase;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Frame; import java.awt.Frame;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
@ -71,8 +72,13 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSetttingsPa
IngestManager.addPropertyChangeListener(new PropertyChangeListener() { IngestManager.addPropertyChangeListener(new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
if (isFileIngestStatusChangeEvent(evt)) { if (isIngestJobEvent(evt)) {
updateComponents(); EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
updateComponents();
}
});
} }
} }
}); });
@ -224,8 +230,10 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSetttingsPa
return shortenedPath; return shortenedPath;
} }
private boolean isFileIngestStatusChangeEvent(PropertyChangeEvent evt) { private boolean isIngestJobEvent(PropertyChangeEvent evt) {
return evt.getPropertyName().equals(IngestManager.IngestEvent.STARTED.toString()) || evt.getPropertyName().equals(IngestManager.IngestEvent.COMPLETED.toString()) || evt.getPropertyName().equals(IngestManager.IngestEvent.STOPPED.toString()); return evt.getPropertyName().equals(IngestManager.IngestEvent.INGEST_JOB_STARTED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestEvent.INGEST_JOB_COMPLETED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestEvent.INGEST_JOB_CANCELLED.toString());
} }
@Override @Override

View File

@ -18,6 +18,7 @@
*/ */
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import java.awt.EventQueue;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
@ -52,7 +53,6 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName()); private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName());
private KeywordTableModel tableModel; private KeywordTableModel tableModel;
private KeywordList currentKeywordList; private KeywordList currentKeywordList;
private boolean ingestRunning;
/** /**
* Creates new form KeywordSearchEditListPanel * Creates new form KeywordSearchEditListPanel
@ -101,7 +101,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
} }
}); });
initButtons(); setButtonStates();
addWordField.setComponentPopupMenu(rightClickMenu); addWordField.setComponentPopupMenu(rightClickMenu);
ActionListener actList = new ActionListener() { ActionListener actList = new ActionListener() {
@ -124,49 +124,28 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
pasteMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList);
if (IngestManager.getInstance().isIngestRunning()) { setButtonStates();
initIngest(0);
} else {
initIngest(1);
}
IngestManager.addPropertyChangeListener(new PropertyChangeListener() { IngestManager.addPropertyChangeListener(new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
String changed = evt.getPropertyName(); String changed = evt.getPropertyName();
Object oldValue = evt.getOldValue(); if (changed.equals(IngestEvent.INGEST_JOB_STARTED.toString())
if (changed.equals(IngestEvent.COMPLETED.toString()) || changed.equals(IngestEvent.INGEST_JOB_COMPLETED.toString())
&& ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) { || changed.equals(IngestEvent.INGEST_JOB_CANCELLED.toString())) {
initIngest(1); EventQueue.invokeLater(new Runnable() {
} else if (changed.equals(IngestEvent.STARTED.toString()) @Override
&& ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) { public void run() {
initIngest(0); setButtonStates();
} else if (changed.equals(IngestEvent.STOPPED.toString()) }
&& ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) { });
initIngest(1);
} }
} }
}); });
} }
/** void setButtonStates() {
* Initialize this panel depending on whether ingest is running boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
*
* @param running case 0: ingest running case 1: ingest not running
*/
private void initIngest(int running) {
switch (running) {
case 0:
ingestRunning = true;
break;
case 1:
ingestRunning = false;
break;
}
initButtons();
}
void initButtons() {
boolean listSet = currentKeywordList != null; boolean listSet = currentKeywordList != null;
boolean isLocked = !listSet ? true : currentKeywordList.isLocked(); boolean isLocked = !listSet ? true : currentKeywordList.isLocked();
boolean noKeywords = !listSet ? true : currentKeywordList.getKeywords().isEmpty(); boolean noKeywords = !listSet ? true : currentKeywordList.getKeywords().isEmpty();
@ -441,7 +420,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
chRegex.setSelected(false); chRegex.setSelected(false);
addWordField.setText(""); addWordField.setText("");
initButtons(); setButtonStates();
}//GEN-LAST:event_addWordButtonActionPerformed }//GEN-LAST:event_addWordButtonActionPerformed
private void deleteWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteWordButtonActionPerformed private void deleteWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteWordButtonActionPerformed
@ -449,7 +428,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
tableModel.deleteSelected(keywordTable.getSelectedRows()); tableModel.deleteSelected(keywordTable.getSelectedRows());
KeywordSearchListsXML.getCurrent().addList(currentKeywordList); KeywordSearchListsXML.getCurrent().addList(currentKeywordList);
initButtons(); setButtonStates();
} }
}//GEN-LAST:event_deleteWordButtonActionPerformed }//GEN-LAST:event_deleteWordButtonActionPerformed
@ -549,11 +528,11 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
currentKeywordList = loader.getListsL(false).get(index); currentKeywordList = loader.getListsL(false).get(index);
tableModel.resync(); tableModel.resync();
initButtons(); setButtonStates();
} else { } else {
currentKeywordList = null; currentKeywordList = null;
tableModel.resync(); tableModel.resync();
initButtons(); setButtonStates();
} }
} }

View File

@ -44,7 +44,7 @@ final class KeywordSearchGlobalListSettingsPanel extends javax.swing.JPanel impl
if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.title"), NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.body"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) { if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.title"), NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.body"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) {
String toDelete = editListPanel.getCurrentKeywordList().getName(); String toDelete = editListPanel.getCurrentKeywordList().getName();
editListPanel.setCurrentKeywordList(null); editListPanel.setCurrentKeywordList(null);
editListPanel.initButtons(); editListPanel.setButtonStates();
// RJCTODO: Move this into a deleteList method in the manager // RJCTODO: Move this into a deleteList method in the manager
KeywordSearchListsXML deleter = KeywordSearchListsXML.getCurrent(); KeywordSearchListsXML deleter = KeywordSearchListsXML.getCurrent();
deleter.deleteList(toDelete); deleter.deleteList(toDelete);

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
import java.awt.Component; import java.awt.Component;
import java.awt.Cursor; import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
@ -114,26 +115,23 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
} }
}); });
if (IngestManager.getInstance().isIngestRunning()) { ingestRunning = IngestManager.getInstance().isIngestRunning();
initIngest(true); updateComponents();
} else {
initIngest(false);
}
IngestManager.addPropertyChangeListener(new PropertyChangeListener() { IngestManager.addPropertyChangeListener(new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
String changed = evt.getPropertyName(); String changed = evt.getPropertyName();
Object oldValue = evt.getOldValue(); if (changed.equals(IngestEvent.INGEST_JOB_STARTED.toString())
if (changed.equals(IngestEvent.COMPLETED.toString()) || changed.equals(IngestEvent.INGEST_JOB_COMPLETED.toString())
&& ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) { || changed.equals(IngestEvent.INGEST_JOB_CANCELLED.toString())) {
initIngest(false); EventQueue.invokeLater(new Runnable() {
} else if (changed.equals(IngestEvent.STARTED.toString()) @Override
&& ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) { public void run() {
initIngest(true); ingestRunning = IngestManager.getInstance().isIngestRunning();
} else if (changed.equals(IngestEvent.STOPPED.toString()) updateComponents();
&& ((String) oldValue).equals(KeywordSearchModuleFactory.getModuleName())) { }
initIngest(false); });
} }
} }
}); });
@ -152,28 +150,21 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
searchAddButton.addActionListener(searchAddListener); searchAddButton.addActionListener(searchAddListener);
} }
/** private void updateComponents() {
* Initialize this panel depending on whether ingest is running ingestRunning = IngestManager.getInstance().isIngestRunning();
* if (ingestRunning) {
* @param running case 0: ingest running case 1: ingest not running
*/
private void initIngest(boolean running) {
if (running) {
ingestRunning = true;
searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestTitle")); searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestMsg" )); searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestMsg" ));
listsTableModel.resync();
} else { } else {
ingestRunning = false;
searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.searchIngestTitle")); searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg")); searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
listsTableModel.resync();
} }
updateIngestIndexLabel(running); listsTableModel.resync();
updateIngestIndexLabel();
} }
private void updateIngestIndexLabel(boolean ingestRunning) { private void updateIngestIndexLabel() {
if (ingestRunning) { if (ingestRunning) {
ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed)); ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed));
} }
@ -184,7 +175,7 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
@Override @Override
protected void postFilesIndexedChange() { protected void postFilesIndexedChange() {
updateIngestIndexLabel(ingestRunning); updateIngestIndexLabel();
} }
/** /**