From 7b52520f9022141a2af55c6ba9f404c44b15764d Mon Sep 17 00:00:00 2001 From: raman-bt Date: Fri, 11 Oct 2013 12:16:07 -0400 Subject: [PATCH] Cleanup of Add Image/DataSource Wizard. Pass #1. --- .../AddImageWizardChooseDataSourcePanel.java | 7 + .../AddImageWizardChooseDataSourceVisual.java | 81 ++- .../AddImageWizardIngestConfigPanel.java | 96 ++- .../casemodule/AddImageWizardIterator.java | 13 +- .../autopsy/casemodule/ContentTypePanel.java | 28 +- .../autopsy/casemodule/DSPCallback.java | 42 ++ .../casemodule/DataSourceProcessor.java | 87 +++ .../autopsy/casemodule/ImageDSProcessor.java | 566 ++++++++++++++++++ .../autopsy/casemodule/ImageFilePanel.java | 4 +- .../autopsy/casemodule/LocalDiskPanel.java | 4 +- .../autopsy/casemodule/LocalFilesPanel.java | 4 +- 11 files changed, 905 insertions(+), 27 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/DSPCallback.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/DataSourceProcessor.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardChooseDataSourcePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardChooseDataSourcePanel.java index 39a00baacc..7fb2a69b0b 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardChooseDataSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardChooseDataSourcePanel.java @@ -43,6 +43,7 @@ class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel datasourceProcessorsMap = new HashMap();; + + /** * Creates new form AddImageVisualPanel1 @@ -75,13 +87,55 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel { } private void customInit() { + + + discoverDataSourceProcessors(); + model = new ContentTypeModel(); typeComboBox.setModel(model); typeComboBox.setSelectedIndex(0); typePanel.setLayout(new BorderLayout()); - updateCurrentPanel(ImageFilePanel.getDefault()); + + //updateCurrentPanel(ImageFilePanel.getDefault()); + updateCurrentPanel(model.getElementAt(0)); } + private void discoverDataSourceProcessors() { + + //datasourceHandlersMap.clear(); + logger.log(Level.INFO, "RAMAN discoverDataSourceProcessors()..."); + + // RAMAN TBD: hack for now + { + //ContentTypePanel.RegisterPanel(ImageFilePanel.getDefault()); + //ContentTypePanel.RegisterPanel(LocalDiskPanel.getDefault()); + //ContentTypePanel.RegisterPanel(LocalFilesPanel.getDefault()); + } + + for (DataSourceProcessor dsProcessor: Lookup.getDefault().lookupAll(DataSourceProcessor.class)) { + + logger.log(Level.INFO, "RAMAN discoverDataSourceHandlers(): found an instance of DataSourceHandler"); + + + String dsType = dsProcessor.getType(); + JPanel panel = dsProcessor.getPanel(); + String validate = dsProcessor.validatePanel(); + //dshandler.run(null); + //String[] errors = dshandler.getErrors(); + + if (!datasourceProcessorsMap.containsKey(dsProcessor.getType()) ) { + + // Regsiter the panel for the discovered DS handler here + ContentTypePanel.RegisterPanel(dsProcessor.getPanel()); + + datasourceProcessorsMap.put(dsProcessor.getType(), dsProcessor); + } + + } + + + } + /** * Changes the current panel to the given panel. * @@ -105,7 +159,7 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel { } }); currentPanel.select(); - if (currentPanel.getContentType().equals(ContentType.LOCAL)) { + if (currentPanel.getContentType().equals("LOCAL")) { //disable image specific options noFatOrphansCheckbox.setEnabled(false); descLabel.setEnabled(false); @@ -118,6 +172,25 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel { updateUI(null); } + /** + * Returns the currently selected DS handler in the combobox + * + * + * @return name the name of this panel + */ + public DataSourceProcessor GetCurrentDSProcessor() { + + logger.log(Level.INFO, "RAMAN GetCurrentDSProcessor()..."); + // get the type of the currently selected panel and then look up + // the correspodning DS Handler in the map + String dsType = currentPanel.getContentType(); + + DataSourceProcessor dsProcessor = datasourceProcessorsMap.get(dsType); + + return dsProcessor; + + } + /** * Returns the name of the this panel. This name will be shown on the left * panel of the "Add Image" wizard panel. @@ -143,7 +216,7 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel { * * @return data source selected */ - public ContentType getContentType() { + public String getContentType() { return currentPanel.getContentType(); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java index 3f5b77e281..dab6bf7318 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java @@ -37,7 +37,7 @@ import javax.swing.event.ChangeListener; import org.openide.WizardDescriptor; import org.openide.util.HelpCtx; import org.openide.util.Lookup; -import org.sleuthkit.autopsy.casemodule.ContentTypePanel.ContentType; +//import org.sleuthkit.autopsy.casemodule.ContentTypePanel.ContentType; import org.sleuthkit.autopsy.casemodule.services.FileManager; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; @@ -73,7 +73,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel messages = ingestConfig.setContext(AddImageWizardIngestConfigPanel.class.getCanonicalName()); if (messages.isEmpty() == false) { @@ -188,12 +193,13 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel errList, List contents) { + dataSourceProcessorDone(result, errList, contents ); + } + + }; + // Kick off the DSProcessor + dsProcessor.run(settings, progressPanel, cbObj); + } + private void cancelDataSourceProcessing() { + logger.log(Level.INFO, "RAMAN cancelDataSourceProcessing()."); + dsProcessor.cancel(); + } + + private void dataSourceProcessorDone(DSPCallback.DSP_Result result, List errList, List contents) { + logger.log(Level.INFO, "RAMAN dataSourceProcessorDone()."); + + // RAMAN TBD + // check if there is any new content and kick off ingest.... + + // RAMAN TBD: check the result + + // RAMAN TBD: if errors, display them on the progress panel + + // disbale the cleanup task + cleanupTask.disable(); + + + newContents.clear(); + newContents.addAll(contents); + + //notify the case + if (!newContents.isEmpty()) { + Case.getCurrentCase().addLocalDataSource(newContents.get(0)); + } + + // Start ingest if we can + startIngest(); + + } /** * Class for getting the currently processing directory. * @@ -313,7 +389,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel> getPanels() { if (panels == null) { - AddImageWizardAddingProgressPanel wizPanel = new AddImageWizardAddingProgressPanel(); panels = new ArrayList>(); - panels.add(new AddImageWizardChooseDataSourcePanel()); - panels.add(new AddImageWizardIngestConfigPanel(action, wizPanel)); - panels.add(wizPanel); + + AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(); + + AddImageWizardChooseDataSourcePanel dsPanel = new AddImageWizardChooseDataSourcePanel(progressPanel); + AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel); + + panels.add(dsPanel); + panels.add(ingestConfigPanel); + panels.add(progressPanel); String[] steps = new String[panels.size()]; for (int i = 0; i < panels.size(); i++) { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ContentTypePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/ContentTypePanel.java index 07664d9401..4b2f4aada8 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/ContentTypePanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/ContentTypePanel.java @@ -20,17 +20,39 @@ package org.sleuthkit.autopsy.casemodule; import java.beans.PropertyChangeListener; import javax.swing.JPanel; +import java.util.ArrayList; +import java.util.List; abstract class ContentTypePanel extends JPanel { - public enum ContentType{IMAGE, DISK, LOCAL}; + // Collection of panels that are dynamically discovered and registered + private static List registeredPanels = new ArrayList();; + + public static void RegisterPanel(ContentTypePanel panel) + { + // RAMAN TBD: check if this panel is already regsitered... + + registeredPanels.add(panel); + + + } + //public enum ContentType{IMAGE, DISK, LOCAL}; + + + private String contentType; /** * Returns a list off all the panels extending ImageTypePanel. * @return list of all ImageTypePanels */ public static ContentTypePanel[] getPanels() { - return new ContentTypePanel[] {ImageFilePanel.getDefault(), LocalDiskPanel.getDefault(), LocalFilesPanel.getDefault() }; + //return new ContentTypePanel[] {ImageFilePanel.getDefault(), LocalDiskPanel.getDefault(), LocalFilesPanel.getDefault() }; + + + + + + return registeredPanels.toArray(new ContentTypePanel[registeredPanels.size()]); } /** @@ -50,7 +72,7 @@ abstract class ContentTypePanel extends JPanel { * Get content type (image, disk, local file) of the source this wizard panel is for * @return ContentType of the source panel */ - abstract public ContentType getContentType(); + abstract public String getContentType(); /** * Returns if the next button should be enabled in the current wizard. diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/DSPCallback.java b/Core/src/org/sleuthkit/autopsy/casemodule/DSPCallback.java new file mode 100644 index 0000000000..58ec4d8ce0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/DSPCallback.java @@ -0,0 +1,42 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.awt.EventQueue; +import java.util.List; +import org.sleuthkit.datamodel.Content; + +/** + * + * @author raman + */ +public abstract class DSPCallback { + + public enum DSP_Result + { + NO_ERRORS, + CRITICAL_ERRORS, + NONCRITICAL_ERRORS, + }; + + void done(DSP_Result result, List errList, List newContents) + { + + final DSP_Result resultf = result; + final List errListf = errList; + final List newContentsf = newContents; + + // Invoke doneEDT() that runs on the EDT . + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + doneEDT(resultf, errListf, newContentsf ); + + } + }); + } + + abstract void doneEDT(DSP_Result result, List errList, List newContents); +}; diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/DataSourceProcessor.java b/Core/src/org/sleuthkit/autopsy/casemodule/DataSourceProcessor.java new file mode 100644 index 0000000000..123d26275b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/DataSourceProcessor.java @@ -0,0 +1,87 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2013 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.util.List; +import javax.swing.JPanel; +import org.openide.WizardDescriptor; +import org.sleuthkit.autopsy.casemodule.AddImageWizardAddingProgressPanel; +import org.sleuthkit.autopsy.casemodule.ContentTypePanel; +import org.sleuthkit.datamodel.Content; + +public interface DataSourceProcessor { + + + + + // public DataSourceProcessor createInstance(); + + + /** + * Returns the type of Data Source it handles. + * This name gets displayed in the drop-down listbox + **/ + String getType(); + + /** + * Returns the picker panel to be displayed along with any other + * runtime options supported by the data source handler. + **/ + ContentTypePanel getPanel(); + + /** + * Called to validate the input data in the panel. + * Returns null if no errors, or + * Returns a string describing the error if there are errors. + **/ + String validatePanel(); + + /** + * Called to invoke the handling of Data source in the background. + * Returns after starting the background thread + * @param settings wizard settings to read/store properties + * @param progressPanel progress panel to be updated while processing + * + **/ + void run(WizardDescriptor settings, AddImageWizardAddingProgressPanel progressPanel, DSPCallback dspCallback); + + /** + * Called after run() is done to get the new content added by the handler. + * Returns a list of content added by the data source handler + **/ + // List getNewContents(); + + + /** + * Called to get the list of errors. + **/ + // String[] getErrors(); + + /** + * Called to cancel the background processing. + * + * TODO look into current use cases to see if this should wait until it has stopped or not. + **/ + void cancel(); + + + + + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java b/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java new file mode 100644 index 0000000000..e44c0f32a1 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageDSProcessor.java @@ -0,0 +1,566 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Window; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import org.openide.WizardDescriptor; +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.SleuthkitJNI; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskDataException; +import org.sleuthkit.datamodel.TskException; + +/** + * + * @author raman + */ +@ServiceProvider(service = DataSourceProcessor.class) +public class ImageDSProcessor implements DataSourceProcessor { + + static final Logger logger = Logger.getLogger(ImageDSProcessor.class.getName()); + + private ImageFilePanel imageFilePanel; + private AddImageTask addImageTask; + private CurrentDirectoryFetcher fetcher; + + private boolean addImageDone = false; + private boolean cancelled = false; + + DSPCallback callbackObj = null; + + public ImageDSProcessor() { + logger.log(Level.INFO, "RAMAN ImageDSHandler()..."); + + // Create the config panel + imageFilePanel = ImageFilePanel.getDefault(); + + } + + /**** + @Override + public ImageDSProcessor createInstance() { + return new ImageDSProcessor(); + } + *****/ + + + @Override + public String getType() { + + logger.log(Level.INFO, "RAMAN getName()..."); + + return imageFilePanel.getContentType(); + + } + + + @Override + public ContentTypePanel getPanel() { + + logger.log(Level.INFO, "RAMAN getPanel()..."); + + return imageFilePanel; + } + + @Override + public String validatePanel() { + + logger.log(Level.INFO, "RAMAN validatePanel()..."); + + return null; + + } + + @Override + public void run(WizardDescriptor settings, AddImageWizardAddingProgressPanel progressPanel, DSPCallback cbObj) { + + logger.log(Level.INFO, "RAMAN run()..."); + + callbackObj = cbObj; + addImageDone = false; + cancelled = false; + + addImageTask = new AddImageTask(settings, progressPanel, cbObj); + addImageTask.execute(); + + return; + } + + /*** + @Override + public String[] getErrors() { + + logger.log(Level.INFO, "RAMAN getErrors()..."); + + // RAMAN TBD + return null; + } + *****/ + + @Override + public void cancel() { + + logger.log(Level.INFO, "RAMAN cancelProcessing()..."); + + cancelled = true; + addImageTask.cancelTask(); + + return; + } + + /***** + @Override + public List getNewContents() { + return addImageTask.getNewContents(); + } + * *****/ + + + private static class CurrentDirectoryFetcher extends SwingWorker { + + //AddImageWizardIngestConfigPanel.AddImageTask task; + JProgressBar progressBar; + AddImageWizardAddingProgressVisual progressVisual; + SleuthkitJNI.CaseDbHandle.AddImageProcess process; + + CurrentDirectoryFetcher(JProgressBar aProgressBar, AddImageWizardAddingProgressVisual wiz, SleuthkitJNI.CaseDbHandle.AddImageProcess proc) { + this.progressVisual = wiz; + this.process = proc; + this.progressBar = aProgressBar; + } + + /** + * @return the currently processing directory + */ + @Override + protected Integer doInBackground() { + try { + while (progressBar.getValue() < 100 || progressBar.isIndeterminate()) { //TODO Rely on state variable in AddImgTask class + + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + progressVisual.setCurrentDirText(process.currentDirectory()); + } + }); + + Thread.sleep(2 * 1000); + } + return 1; + } catch (InterruptedException ie) { + return -1; + } + } + } + + + private class AddImageTask extends SwingWorker { + + private JProgressBar progressBar; + private Case currentCase; + // true if the process was requested to stop + private boolean cancelled = false; + //true if revert has been invoked. + private boolean reverted = false; + private boolean hasCritError = false; + private boolean addImagedone = false; + + + //private String errorString = null; + private List errorList = new ArrayList(); + + private WizardDescriptor wizDescriptor; + + private Logger logger = Logger.getLogger(AddImageTask.class.getName()); + private AddImageWizardAddingProgressPanel progressPanel; + private DSPCallback callbackObj; + + private final List newContents = Collections.synchronizedList(new ArrayList()); + + private SleuthkitJNI.CaseDbHandle.AddImageProcess addImageProcess; + + protected AddImageTask(WizardDescriptor settings, AddImageWizardAddingProgressPanel aProgressPanel, DSPCallback cbObj ) { + this.progressPanel = aProgressPanel; + this.progressBar = progressPanel.getComponent().getProgressBar(); + currentCase = Case.getCurrentCase(); + + this.callbackObj = cbObj; + this.wizDescriptor = settings; + } + + /** + * Starts the addImage process, but does not commit the results. + * + * @return + * + * @throws Exception + */ + @Override + protected Integer doInBackground() { + + logger.log(Level.INFO, "RAMAN: doInBackground()"); + + this.setProgress(0); + + errorList.clear(); + + /**** RAMAN TBD: a higher level caller should set up the cleanup task and then call DataSourceHandler.cancelProcessing() + * + // Add a cleanup task to interrupt the backgroud process if the + // wizard exits while the background process is running. + AddImageAction.CleanupTask cancelledWhileRunning = action.new CleanupTask() { + @Override + void cleanup() throws Exception { + logger.log(Level.INFO, "Add image process interrupted."); + addImageTask.interrupt(); //it might take time to truly interrupt + } + }; + * *************************/ + + + try { + //lock DB for writes in EWT thread + //wait until lock acquired in EWT + EventQueue.invokeAndWait(new Runnable() { + @Override + public void run() { + SleuthkitCase.dbWriteLock(); + } + }); + } catch (InterruptedException ex) { + logger.log(Level.WARNING, "Errors occurred while running add image, could not acquire lock. ", ex); + return 0; + + } catch (InvocationTargetException ex) { + logger.log(Level.WARNING, "Errors occurred while running add image, could not acquire lock. ", ex); + return 0; + } + + + String dataSourcePath = (String) wizDescriptor.getProperty(AddImageAction.DATASOURCEPATH_PROP); + String dataSourceType = (String) wizDescriptor.getProperty(AddImageAction.DATASOURCETYPE_PROP); + String timeZone = wizDescriptor.getProperty(AddImageAction.TIMEZONE_PROP).toString(); + boolean noFatOrphans = ((Boolean) wizDescriptor.getProperty(AddImageAction.NOFATORPHANS_PROP)).booleanValue(); + + + addImageProcess = currentCase.makeAddImageProcess(timeZone, true, noFatOrphans); + fetcher = new CurrentDirectoryFetcher(this.progressBar, progressPanel.getComponent(), addImageProcess); + //RAMAN TBD: handle the cleanup task + //cancelledWhileRunning.enable(); + try { + progressPanel.setStateStarted(); + fetcher.execute(); + addImageProcess.run(new String[]{dataSourcePath}); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Core errors occurred while running add image. ", ex); + //critical core/system error and process needs to be interrupted + hasCritError = true; + //errorString = ex.getMessage(); + errorList.add(ex.getMessage()); + } catch (TskDataException ex) { + logger.log(Level.WARNING, "Data errors occurred while running add image. ", ex); + //errorString = ex.getMessage(); + errorList.add(ex.getMessage()); + } finally { + // process is over, doesn't need to be dealt with if cancel happens + //RAMAN TBD: handle the cleanup task + //cancelledWhileRunning.disable(); + + } + + return 0; + } + + /** + * Commit the finished AddImageProcess, and cancel the CleanupTask that + * would have reverted it. + * + * @param settings property set to get AddImageProcess and CleanupTask + * from + * + * @throws Exception if commit or adding the image to the case failed + */ + private void commitImage(WizardDescriptor settings) throws Exception { + + logger.log(Level.INFO, "RAMAN: commitImage()..."); + + String contentPath = (String) settings.getProperty(AddImageAction.DATASOURCEPATH_PROP); + + String timezone = settings.getProperty(AddImageAction.TIMEZONE_PROP).toString(); + settings.putProperty(AddImageAction.IMAGEID_PROP, ""); + + long imageId = 0; + try { + imageId = addImageProcess.commit(); + } catch (TskException e) { + logger.log(Level.WARNING, "Errors occured while committing the image", e); + errorList.add(e.getMessage()); + } finally { + //commit done, unlock db write in EWT thread + //before doing anything else + SleuthkitCase.dbWriteUnlock(); + + if (imageId != 0) { + Image newImage = Case.getCurrentCase().addImage(contentPath, imageId, timezone); + + //while we have the image, verify the size of its contents + String verificationErrors = newImage.verifyImageSize(); + if (verificationErrors.equals("") == false) { + //data error (non-critical) + errorList.add(verificationErrors); + //progressPanel.addErrors(verificationErrors, false); + } + + /*** RAMAN TBD: how to handle the newContent notification back to IngestConfigPanel **/ + newContents.add(newImage); + + settings.putProperty(AddImageAction.IMAGEID_PROP, imageId); + } + + // Can't bail and revert image add after commit, so disable image cleanup + // task + + // RAMAN TBD: cleanup task should be handled by the caller + // cleanupImage.disable(); + + settings.putProperty(AddImageAction.IMAGECLEANUPTASK_PROP, null); + + logger.log(Level.INFO, "Image committed, imageId: " + imageId); + logger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo()); + + } + } + + /** + * + * (called by EventDispatch Thread after doInBackground finishes) + * + * Must Not return without invoking the callBack. + */ + @Override + protected void done() { + + logger.log(Level.INFO, "RAMAN: done()..."); + + //these are required to stop the CurrentDirectoryFetcher + progressBar.setIndeterminate(false); + setProgress(100); + + addImageDone = true; + + // attempt actions that might fail and force the process to stop + + if (cancelled || hasCritError) { + logger.log(Level.INFO, "Handling errors or interruption that occured in add image process"); + revert(); + if (hasCritError) { + //core error + // RAMAN TBD: Error reporting needs to be removed from here. All errors are returned to caller directly. + //progressPanel.addErrors(errorString, true); + } + // Do not return yet. Callback must be called + } + if (!errorList.isEmpty()) { + //data error (non-critical) + logger.log(Level.INFO, "Handling non-critical errors that occured in add image process"); + + // RAMAN TBD: Error reporting needs to be removed from here. All errors are returned to caller directly. + //progressPanel.addErrors(errorString, false); + } + + // When everything happens without an error: + if (!(cancelled || hasCritError)) { + + try { + + + /* ***************************** + * RAMAN TBD: the caller needs to handle the cleanup ??? + // the add-image process needs to be reverted if the wizard doesn't finish + cleanupImage = action.new CleanupTask() { + //note, CleanupTask runs inside EWT thread + @Override + void cleanup() throws Exception { + logger.log(Level.INFO, "Running cleanup task after add image process"); + revert(); + } + }; + cleanupImage.enable(); + * ************************/ + + //if (errorString == null) { // complete progress bar + if (errorList.isEmpty() ) { // complete progress bar + progressPanel.getComponent().setProgressBarTextAndColor("*Data Source added.", 100, Color.black); + } + + // RAMAN TBD: this should not be happening in here - caller should do this + + // Get attention for the process finish + java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP! + AddImageWizardAddingProgressVisual panel = progressPanel.getComponent(); + if (panel != null) { + Window w = SwingUtilities.getWindowAncestor(panel); + if (w != null) { + w.toFront(); + } + } + + // Tell the panel we're done + progressPanel.setStateFinished(); + + + if (newContents.isEmpty()) { + if (addImageProcess != null) { // and if we're done configuring ingest + // commit anything + try { + commitImage(wizDescriptor); + } catch (Exception ex) { + // Log error/display warning + logger.log(Level.SEVERE, "Error adding image to case.", ex); + } + } else { + logger.log(Level.SEVERE, "Missing image process object"); + } + } + + else //already commited? + { + logger.log(Level.INFO, "Assuming image already committed, will not commit."); + + } + + + + + // Start ingest if we can + // RAMAN TBD - remove this from here + //startIngest(); + + } catch (Exception ex) { + //handle unchecked exceptions post image add + + logger.log(Level.WARNING, "Unexpected errors occurred while running post add image cleanup. ", ex); + + progressPanel.getComponent().setProgressBarTextAndColor("*Failed to add image.", 0, Color.black); // set error message + + // Log error/display warning + + logger.log(Level.SEVERE, "Error adding image to case", ex); + } finally { + + + } + } + + // invoke the callBack, unless the caller cancelled + if (!cancelled) + doCallBack(); + + } + + + void doCallBack() + { + logger.log(Level.INFO, "RAMAN In doCallback()"); + + DSPCallback.DSP_Result result; + + if (hasCritError) { + result = DSPCallback.DSP_Result.CRITICAL_ERRORS; + } + else if (!errorList.isEmpty()) { + result = DSPCallback.DSP_Result.NONCRITICAL_ERRORS; + } + else { + result = DSPCallback.DSP_Result.NO_ERRORS; + } + + callbackObj.done(result, errorList, newContents); + } + + /***** + public List getNewContents() { + + return newContents; + + } + * ********/ + + void cancelTask() { + + logger.log(Level.INFO, "RAMAN: cancelTask()..."); + + cancelled = true; + + if (!addImageDone) { + try { + addImageTask.interrupt(); + } + catch (Exception ex) { + logger.log(Level.SEVERE, "Failed to interrup the add image task..."); + } + } + else { + try { + addImageTask.revert(); + } + catch(Exception ex) { + logger.log(Level.SEVERE, "Failed to revert the add image task..."); + } + } + } + void interrupt() throws Exception { + + logger.log(Level.INFO, "RAMAN: interrupt()..."); + + //interrupted = true; + try { + logger.log(Level.INFO, "interrupt() add image process"); + addImageProcess.stop(); //it might take time to truly stop processing and writing to db + } catch (TskException ex) { + throw new Exception("Error stopping add-image process.", ex); + } + } + + //runs in EWT + void revert() { + + logger.log(Level.INFO, "RAMAN: revert()..."); + if (!reverted) { + + try { + logger.log(Level.INFO, "Revert after add image process"); + try { + addImageProcess.revert(); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error reverting add image process", ex); + } + } finally { + //unlock db write within EWT thread + SleuthkitCase.dbWriteUnlock(); + } + reverted = true; + } + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java index a71ad31681..3bc25fe42d 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/ImageFilePanel.java @@ -158,8 +158,8 @@ public class ImageFilePanel extends ContentTypePanel implements DocumentListener } @Override - public ContentType getContentType() { - return ContentType.IMAGE; + public String getContentType() { + return "IMAGE"; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java index 6a51382940..f007189683 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalDiskPanel.java @@ -153,8 +153,8 @@ public class LocalDiskPanel extends ContentTypePanel { } @Override - public ContentType getContentType() { - return ContentType.DISK; + public String getContentType() { + return "DISK"; } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/LocalFilesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/LocalFilesPanel.java index 7d07033ac1..4af5cf0ab9 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/LocalFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/LocalFilesPanel.java @@ -79,8 +79,8 @@ public class LocalFilesPanel extends ContentTypePanel { } @Override - public ContentType getContentType() { - return ContentType.LOCAL; + public String getContentType() { + return "LOCAL"; } @Override