mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 17:27:43 +00:00
Revert "Fix thread safety, clean up add data source wizard classes"
This reverts commit b93d45fbf12824d7172ac6297ce4e6c24fbe1ed4.
This commit is contained in:
parent
fc6f972e54
commit
eda180e34f
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2014 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,11 +21,13 @@ package org.sleuthkit.autopsy.casemodule;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
@ -35,91 +37,139 @@ import org.openide.util.HelpCtx;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action that adds a data source to the current case.
|
* The action to add an image to the current Case. This action should be
|
||||||
|
* disabled on creation and it will be enabled on new case creation or case
|
||||||
|
* opened.
|
||||||
*
|
*
|
||||||
* RC: This action needs to be enabled and disabled as cases are opened and
|
* @author jantonius
|
||||||
* closed. Currently this is done using
|
|
||||||
* CallableSystemAction.get(AddImageAction.class).setEnabled().
|
|
||||||
*/
|
*/
|
||||||
|
// TODO: need annotation because there's a "Lookup.getDefault().lookup(AddImageAction.class)"
|
||||||
|
// used in AddImageWizardPanel1 (among other places). It really shouldn't be done like that.
|
||||||
|
@ServiceProvider(service = AddImageAction.class)
|
||||||
public final class AddImageAction extends CallableSystemAction implements Presenter.Toolbar {
|
public final class AddImageAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
// Keys into the WizardDescriptor properties that pass information between stages of the wizard
|
||||||
private static final Logger logger = Logger.getLogger(AddImageAction.class.getName());
|
// <TYPE>: <DESCRIPTION>
|
||||||
private final ChangeSupport cleanupSupport;
|
// String: time zone that the image is from
|
||||||
private final JButton toolbarButton;
|
static final String TIMEZONE_PROP = "timeZone"; //NON-NLS
|
||||||
|
// String[]: array of paths to each data source selected
|
||||||
|
static final String DATASOURCEPATH_PROP = "dataSrcPath"; //NON-NLS
|
||||||
|
// String data source type selected
|
||||||
|
static final String DATASOURCETYPE_PROP = "dataSrcType"; //NON-NLS
|
||||||
|
// CleanupTask: task to clean up the database file if wizard errors/is cancelled after it is created
|
||||||
|
static final String IMAGECLEANUPTASK_PROP = "finalFileCleanup"; //NON-NLS
|
||||||
|
// int: the next availble id for a new image
|
||||||
|
static final String IMAGEID_PROP = "imageId"; //NON-NLS
|
||||||
|
// AddImageProcess: the next availble id for a new image
|
||||||
|
static final String PROCESS_PROP = "process"; //NON-NLS
|
||||||
|
// boolean: whether or not to lookup files in the hashDB
|
||||||
|
static final String LOOKUPFILES_PROP = "lookupFiles"; //NON-NLS
|
||||||
|
// boolean: whether or not to skip processing orphan files on FAT filesystems
|
||||||
|
static final String NOFATORPHANS_PROP = "nofatorphans"; //NON-NLS
|
||||||
|
|
||||||
|
static final Logger logger = Logger.getLogger(AddImageAction.class.getName());
|
||||||
|
|
||||||
private WizardDescriptor wizardDescriptor;
|
private WizardDescriptor wizardDescriptor;
|
||||||
private WizardDescriptor.Iterator<WizardDescriptor> iterator;
|
private WizardDescriptor.Iterator<WizardDescriptor> iterator;
|
||||||
|
private Dialog dialog;
|
||||||
|
private JButton toolbarButton = new JButton();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an action that adds a data source to the current case.
|
* The constructor for AddImageAction class
|
||||||
*/
|
*/
|
||||||
public AddImageAction() {
|
public AddImageAction() {
|
||||||
cleanupSupport = new ChangeSupport(this);
|
putValue(Action.NAME, NbBundle.getMessage(AddImageAction.class, "CTL_AddImage")); // set the action Name
|
||||||
putValue(Action.NAME, NbBundle.getMessage(AddImageAction.class, "CTL_AddImage"));
|
|
||||||
toolbarButton = new JButton();
|
// set the action for the toolbar button
|
||||||
toolbarButton.addActionListener(AddImageAction.this::actionPerformed);
|
toolbarButton.addActionListener(new ActionListener() {
|
||||||
setEnabled(false);
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
AddImageAction.this.actionPerformed(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setEnabled(false); // disable this action class
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the first panel of the add data source wizard.
|
* Pop-up the "Add Image" wizard panel.
|
||||||
*
|
*
|
||||||
* @param notUsed An action event, may be null.
|
* @param e
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent notUsed) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
/*
|
|
||||||
* If ingest is running, confirm that the user wants to add another data
|
|
||||||
* source at this time, instead of waiting for the current ingest job to
|
|
||||||
* complete.
|
|
||||||
*/
|
|
||||||
if (IngestManager.getInstance().isIngestRunning()) {
|
if (IngestManager.getInstance().isIngestRunning()) {
|
||||||
if (JOptionPane.showConfirmDialog(null,
|
final String msg = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg");
|
||||||
NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg"),
|
if (JOptionPane.showConfirmDialog(null, msg,
|
||||||
NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.title"),
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddImageAction.ingestConfig.ongoingIngest.title"),
|
||||||
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
|
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
iterator = new AddImageWizardIterator(this);
|
||||||
* Construct and display the wizard.
|
|
||||||
*/
|
|
||||||
iterator = new AddImageWizardIterator();
|
|
||||||
wizardDescriptor = new WizardDescriptor(iterator);
|
wizardDescriptor = new WizardDescriptor(iterator);
|
||||||
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "AddImageAction.wizard.title"));
|
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "AddImageAction.wizard.title"));
|
||||||
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
|
wizardDescriptor.putProperty(NAME, e);
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
dialog.setVisible(false); // hide the old one
|
||||||
|
}
|
||||||
|
dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
dialog.toFront();
|
dialog.toFront();
|
||||||
|
|
||||||
/*
|
// Do any cleanup that needs to happen (potentially: stopping the
|
||||||
* Run any registered cleanup tasks by firing a change event. This will
|
//add-image process, reverting an image)
|
||||||
* cause the stateChanged method of any implementations of the inner,
|
runCleanupTasks();
|
||||||
* abstract CleanupTask class to call their cleanup methods (assuming
|
|
||||||
* they have not done an override of stateChanged), after which the
|
|
||||||
* CleanupTasks are unregistered.
|
|
||||||
*
|
|
||||||
* RC: This is a convoluted and error-prone way to implement clean up.
|
|
||||||
* Fortunately, it is confined to this package.
|
|
||||||
*/
|
|
||||||
cleanupSupport.fireChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Closes the current dialog and wizard, and opens a new one. Used in the
|
||||||
|
* "Add another image" action on the last panel
|
||||||
|
*/
|
||||||
|
void restart() {
|
||||||
|
// Simulate clicking finish for the current dialog
|
||||||
|
wizardDescriptor.setValue(WizardDescriptor.FINISH_OPTION);
|
||||||
|
dialog.setVisible(false);
|
||||||
|
|
||||||
|
// let the previous call to AddImageAction.actionPerformed() finish up
|
||||||
|
// after the wizard, this will run when its it's done
|
||||||
|
final Runnable r = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
actionPerformed(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IndexImageTask {
|
||||||
|
|
||||||
|
void runTask(Image newImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
|
||||||
|
* instead of this method.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
actionPerformed(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Gets the name of this action. This may be presented as an item in a menu.
|
||||||
|
*
|
||||||
|
* @return actionName
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -127,7 +177,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Gets the HelpCtx associated with implementing object
|
||||||
|
*
|
||||||
|
* @return HelpCtx or HelpCtx.DEFAULT_HELP
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelpCtx() {
|
public HelpCtx getHelpCtx() {
|
||||||
@ -135,7 +187,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Returns the toolbar component of this action
|
||||||
|
*
|
||||||
|
* @return component the toolbar button
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Component getToolbarPresenter() {
|
public Component getToolbarPresenter() {
|
||||||
@ -146,7 +200,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Set this action to be enabled/disabled
|
||||||
|
*
|
||||||
|
* @param value whether to enable this action or not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean value) {
|
public void setEnabled(boolean value) {
|
||||||
@ -155,80 +211,68 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does nothing, do not use.
|
* Set the focus to the button of the given name on this wizard dialog.
|
||||||
*
|
*
|
||||||
* @deprecated Classes in this package may call requestFocusForWizardButton
|
* Note: the name of the buttons that available are "Next >", "< Back",
|
||||||
* instead.
|
* "Cancel", and "Finish". If you change the name of any of those buttons,
|
||||||
|
* use the latest name instead.
|
||||||
|
*
|
||||||
|
* @param buttonText the text of the button
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public void requestFocusButton(String buttonText) {
|
public void requestFocusButton(String buttonText) {
|
||||||
}
|
// get all buttons on this wizard panel
|
||||||
|
Object[] wizardButtons = wizardDescriptor.getOptions();
|
||||||
/**
|
for (int i = 0; i < wizardButtons.length; i++) {
|
||||||
* Requests focus for an add data source wizard button.
|
JButton tempButton = (JButton) wizardButtons[i];
|
||||||
*
|
if (tempButton.getText().equals(buttonText)) {
|
||||||
* @param buttonText The text of the button.
|
tempButton.setDefaultCapable(true);
|
||||||
*/
|
tempButton.requestFocus();
|
||||||
void requestFocusForWizardButton(String buttonText) {
|
|
||||||
for (Object wizardButton : wizardDescriptor.getOptions()) {
|
|
||||||
JButton button = (JButton) wizardButton;
|
|
||||||
if (button.getText().equals(buttonText)) {
|
|
||||||
button.setDefaultCapable(true);
|
|
||||||
button.requestFocus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enabled instances of this class are called to do clean up after the add
|
* Run and clear any cleanup tasks for wizard closing that might be
|
||||||
* data source wizard is closed. The instances are disabled after the
|
* registered. This should be run even when the wizard exits cleanly, so
|
||||||
* cleanUp method is called. Implementations should not override
|
* that no cleanup actions remain the next time the wizard is run.
|
||||||
* stateChanged, and should not re-enable themselves after cleanUp is
|
*/
|
||||||
* called. To stop cleanUp being called, call disable before the wizard is
|
private void runCleanupTasks() {
|
||||||
* dismissed.
|
cleanupSupport.fireChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeSupport cleanupSupport = new ChangeSupport(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instances of this class implement the cleanup() method to run cleanup
|
||||||
|
* code when the wizard exits.
|
||||||
*
|
*
|
||||||
* Instances must be constructed using a reference to an AddImageAction
|
* After enable() has been called on an instance it will run once after the
|
||||||
* object because this is a non-static inner class.
|
* wizard closes (on both a cancel and a normal finish).
|
||||||
*
|
*
|
||||||
* RC: This is a convoluted and error-prone way to implement clean up.
|
* If disable() is called before the wizard exits, the task will not run.
|
||||||
* Fortunately, it is confined to this package.
|
|
||||||
*/
|
*/
|
||||||
abstract class CleanupTask implements ChangeListener {
|
abstract class CleanupTask implements ChangeListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
/*
|
// fired by AddImageAction.runCleanupTasks() after the wizard closes
|
||||||
* actionPerformed fires this event after the add data source wizard
|
|
||||||
* is closed.
|
|
||||||
*/
|
|
||||||
try {
|
try {
|
||||||
cleanup();
|
cleanup();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.log(Level.SEVERE, "Error cleaning in add data source wizard clean up task", ex); //NON-NLS
|
Logger logger = Logger.getLogger(this.getClass().getName());
|
||||||
|
logger.log(Level.WARNING, "Error cleaning up from wizard.", ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
/*
|
disable(); // cleanup tasks should only run once.
|
||||||
* Clean up tasks should only be done exactly once.
|
|
||||||
*/
|
|
||||||
disable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds this task to the list of tasks to be done when the wizard
|
* Add task to the enabled list to run when the wizard closes.
|
||||||
* closes.
|
|
||||||
*/
|
*/
|
||||||
void enable() {
|
public void enable() {
|
||||||
cleanupSupport.addChangeListener(this);
|
cleanupSupport.addChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes this task from the list of tasks to be done when the wizard
|
|
||||||
* closes.
|
|
||||||
*/
|
|
||||||
void disable() {
|
|
||||||
cleanupSupport.removeChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs cleanup action when called
|
* Performs cleanup action when called
|
||||||
*
|
*
|
||||||
@ -236,12 +280,11 @@ public final class AddImageAction extends CallableSystemAction implements Presen
|
|||||||
*/
|
*/
|
||||||
abstract void cleanup() throws Exception;
|
abstract void cleanup() throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove task from the enabled list.
|
||||||
|
*/
|
||||||
|
public void disable() {
|
||||||
|
cleanupSupport.removeChangeListener(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public interface IndexImageTask {
|
|
||||||
|
|
||||||
void runTask(Image newImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2014 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");
|
||||||
@ -20,97 +20,105 @@ package org.sleuthkit.autopsy.casemodule;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import org.openide.WizardDescriptor;
|
import org.openide.WizardDescriptor;
|
||||||
import org.openide.util.ChangeSupport;
|
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The third and final panel of the add data source wizard. The visual component
|
* The final panel of the add image wizard. It displays a progress bar and
|
||||||
* of this panel displays a progress bar that is managed by the previous panel
|
* status updates.
|
||||||
* and the data source processor.
|
*
|
||||||
|
* All the real work is kicked off in the previous panel:
|
||||||
|
* {@link AddImageWizardIngestConfigPanel} (which is a bit weird if you ask m
|
||||||
|
* -jm)
|
||||||
*/
|
*/
|
||||||
// All the real work is kicked off in the previous panel:
|
class AddImageWizardAddingProgressPanel implements WizardDescriptor.FinishablePanel<WizardDescriptor> {
|
||||||
// {@link AddImageWizardIngestConfigPanel} (which is a bit weird if you ask m
|
|
||||||
// -jm)
|
|
||||||
final class AddImageWizardAddingProgressPanel implements WizardDescriptor.FinishablePanel<WizardDescriptor> {
|
|
||||||
|
|
||||||
private final ChangeSupport changeSupport;
|
/**
|
||||||
private final DSPProgressMonitorImpl dspProgressMonitor = new DSPProgressMonitorImpl();
|
* flag to indicate that the image adding process is finished and this panel
|
||||||
|
* is completed(valid)
|
||||||
|
*/
|
||||||
|
private boolean imgAdded = false;
|
||||||
|
/**
|
||||||
|
* The visual component that displays this panel. If you need to access the
|
||||||
|
* component from this class, just use getComponent().
|
||||||
|
*/
|
||||||
private AddImageWizardAddingProgressVisual component;
|
private AddImageWizardAddingProgressVisual component;
|
||||||
private boolean dataSourceAdded = false;
|
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
|
||||||
|
|
||||||
/**
|
private DSPProgressMonitorImpl dspProgressMonitorImpl = new DSPProgressMonitorImpl();
|
||||||
* Constructs an instance of the third and final panel of the add data
|
|
||||||
* source wizard.
|
public DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
|
||||||
*/
|
return dspProgressMonitorImpl;
|
||||||
AddImageWizardAddingProgressPanel() {
|
|
||||||
changeSupport = new ChangeSupport(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the data source progress monitor. Allows the previous panel to hand
|
|
||||||
* off the progress monitor to the data source processor.
|
|
||||||
*/
|
|
||||||
DSPProgressMonitorImpl getDSPProgressMonitor() {
|
|
||||||
return dspProgressMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A data source processor progress monitor that acts as a bridge between
|
|
||||||
* the data source processor started by the previous panel and the progress
|
|
||||||
* bar displayed by the visual component of this panel.
|
|
||||||
*/
|
|
||||||
private class DSPProgressMonitorImpl implements DataSourceProcessorProgressMonitor {
|
private class DSPProgressMonitorImpl implements DataSourceProcessorProgressMonitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIndeterminate(final boolean indeterminate) {
|
public void setIndeterminate(final boolean indeterminate) {
|
||||||
EventQueue.invokeLater(() -> {
|
// update the progress bar asynchronously
|
||||||
getComponent().getProgressBar().setIndeterminate(indeterminate);
|
EventQueue.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getComponent().getProgressBar().setIndeterminate(indeterminate);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProgress(final int progress) {
|
public void setProgress(final int progress) {
|
||||||
// update the progress bar asynchronously
|
// update the progress bar asynchronously
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(new Runnable() {
|
||||||
getComponent().getProgressBar().setValue(progress);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getComponent().getProgressBar().setValue(progress);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProgressText(final String text) {
|
public void setProgressText(final String text) {
|
||||||
// update the progress UI asynchronously
|
// update the progress UI asynchronously
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(new Runnable() {
|
||||||
getComponent().setProgressMsgText(text);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getComponent().setProgressMsgText(text);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the visual component for the panel. In this template, the component
|
* Get the visual component for the panel. In this template, the component
|
||||||
* is kept separate. This can be more efficient: if the wizard is created
|
* is kept separate. This can be more efficient: if the wizard is created
|
||||||
* but never displayed, or not all panels are displayed, it is better to
|
* but never displayed, or not all panels are displayed, it is better to
|
||||||
* create only those which really need to be visible.
|
* create only those which really need to be visible.
|
||||||
*
|
*
|
||||||
* @return The UI component of this wizard panel.
|
* It also separates the view from the control - jm
|
||||||
|
*
|
||||||
|
* @return component the UI component of this wizard panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AddImageWizardAddingProgressVisual getComponent() {
|
public AddImageWizardAddingProgressVisual getComponent() {
|
||||||
if (null == component) {
|
if (component == null) {
|
||||||
component = new AddImageWizardAddingProgressVisual();
|
component = new AddImageWizardAddingProgressVisual();
|
||||||
}
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the help for this panel. When the panel is active, this is used as
|
* Help for this panel. When the panel is active, this is used as the help
|
||||||
* the help for the wizard dialog.
|
* for the wizard dialog.
|
||||||
*
|
*
|
||||||
* @return The help for this panel
|
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelp() {
|
public HelpCtx getHelp() {
|
||||||
@ -126,12 +134,17 @@ final class AddImageWizardAddingProgressPanel implements WizardDescriptor.Finish
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return dataSourceAdded;
|
// set the focus to the next button of the wizard dialog if it's enabled
|
||||||
|
if (imgAdded) {
|
||||||
|
Lookup.getDefault().lookup(AddImageAction.class).requestFocusButton(
|
||||||
|
NbBundle.getMessage(this.getClass(), "AddImageWizardAddingProgressPanel.isValid.focusNext"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return imgAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the progress bar of the visual component of this panel indicate
|
* Updates the UI to display the add image process has begun.
|
||||||
* that the data source processor is running.
|
|
||||||
*/
|
*/
|
||||||
void setStateStarted() {
|
void setStateStarted() {
|
||||||
component.getProgressBar().setIndeterminate(true);
|
component.getProgressBar().setIndeterminate(true);
|
||||||
@ -140,85 +153,94 @@ final class AddImageWizardAddingProgressPanel implements WizardDescriptor.Finish
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the progress bar of the visual component of this panel indicate
|
* Updates the UI to display the add image process is over.
|
||||||
* that the data source processor is not running.
|
|
||||||
*/
|
*/
|
||||||
void setStateFinished() {
|
void setStateFinished() {
|
||||||
dataSourceAdded = true;
|
imgAdded = true;
|
||||||
getComponent().setStateFinished();
|
getComponent().setStateFinished();
|
||||||
fireChangeEvent();
|
fireChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc5
|
* Adds a listener to changes of the panel's validity.
|
||||||
|
*
|
||||||
|
* @param l the change listener to add
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void addChangeListener(ChangeListener listener) {
|
public final void addChangeListener(ChangeListener l) {
|
||||||
changeSupport.addChangeListener(listener);
|
synchronized (listeners) {
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Removes a listener to changes of the panel's validity.
|
||||||
|
*
|
||||||
|
* @param l the change listener to move
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void removeChangeListener(ChangeListener listener) {
|
public final void removeChangeListener(ChangeListener l) {
|
||||||
changeSupport.removeChangeListener(listener);
|
synchronized (listeners) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* This method is auto-generated. It seems that this method is used to
|
||||||
|
* listen to any change in this wizard panel.
|
||||||
*/
|
*/
|
||||||
protected final void fireChangeEvent() {
|
protected final void fireChangeEvent() {
|
||||||
changeSupport.fireChange();
|
Iterator<ChangeListener> it;
|
||||||
|
synchronized (listeners) {
|
||||||
|
it = new HashSet<ChangeListener>(listeners).iterator();
|
||||||
|
}
|
||||||
|
ChangeEvent ev = new ChangeEvent(this);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next().stateChanged(ev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the current data--either the default data
|
* Load the image locations from the WizardDescriptor settings object, and
|
||||||
* or already-modified settings, if the user used the previous and/or next
|
* the
|
||||||
* buttons. This method can be called multiple times on one instance of
|
|
||||||
* WizardDescriptor.Panel.
|
|
||||||
*
|
*
|
||||||
* @param settings The settings.
|
* @param settings the setting to be read from
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void readSettings(WizardDescriptor settings) {
|
public void readSettings(WizardDescriptor settings) {
|
||||||
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
|
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
|
||||||
if (dataSourceAdded) {
|
if (imgAdded) {
|
||||||
getComponent().setStateFinished();
|
getComponent().setStateFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the opportunity to update the settings
|
* this doesn't appear to store anything? plus, there are no settings in
|
||||||
* with its current customized state. Rather than updating its settings with
|
* this panel -jm
|
||||||
* every change in the GUI, it should collect them, and then only save them
|
|
||||||
* when requested to by this method. This method can be called multiple
|
|
||||||
* times on one instance of WizardDescriptor.Panel.
|
|
||||||
*
|
*
|
||||||
* @param settings the setting to be stored to
|
* @param settings the setting to be stored to
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void storeSettings(WizardDescriptor settings) {
|
public void storeSettings(WizardDescriptor settings) {
|
||||||
|
//why did we do this? -jm
|
||||||
|
// getComponent().resetInfoPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays an error message from the data source processor for the data
|
* forward errors to visual component
|
||||||
* source being added.
|
|
||||||
*
|
*
|
||||||
* @param errorString The error message to be displayed
|
* should this be modified to handle a list of errors? -jm
|
||||||
* @param critical True if this is a critical error
|
*
|
||||||
|
*
|
||||||
|
* @param errorString the error string to be displayed
|
||||||
|
* @param critical true if this is a critical error
|
||||||
*/
|
*/
|
||||||
// Should this be modified to handle a list of errors? -jm
|
void addErrors(String errorString, boolean critical) {
|
||||||
void displayDataSourceProcessorError(String errorString, boolean critical) {
|
|
||||||
getComponent().showErrors(errorString, critical);
|
getComponent().showErrors(errorString, critical);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFinishPanel() {
|
public boolean isFinishPanel() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011 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");
|
||||||
@ -20,43 +20,55 @@ package org.sleuthkit.autopsy.casemodule;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import org.openide.WizardDescriptor;
|
import org.openide.WizardDescriptor;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import org.openide.util.ChangeSupport;
|
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The first panel of the add data source wizard. The visual component of this
|
* The "Add Image" wizard panel1 handling the logic of selecting image file(s)
|
||||||
* panel allows a user to select data sources to add to the current case.
|
* to add to Case, and pick the time zone.
|
||||||
*/
|
*/
|
||||||
final class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel<WizardDescriptor>, PropertyChangeListener {
|
class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel<WizardDescriptor>, PropertyChangeListener {
|
||||||
|
|
||||||
private AddImageWizardChooseDataSourceVisual component;
|
|
||||||
private final ChangeSupport changeSupport;
|
|
||||||
private boolean nextButtonIsEnabled = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of the first panel of the add data source wizard.
|
* The visual component that displays this panel. If you need to access the
|
||||||
|
* component from this class, just use getComponent().
|
||||||
*/
|
*/
|
||||||
AddImageWizardChooseDataSourcePanel() {
|
private AddImageWizardAddingProgressPanel progressPanel;
|
||||||
changeSupport = new ChangeSupport(this);
|
private AddImageWizardChooseDataSourceVisual component;
|
||||||
|
private boolean isNextEnable = false;
|
||||||
|
private static final String PROP_LASTDATASOURCE_PATH = "LBL_LastDataSource_PATH"; //NON-NLS
|
||||||
|
private static final String PROP_LASTDATASOURCE_TYPE = "LBL_LastDataSource_TYPE"; //NON-NLS
|
||||||
|
// paths to any set hash lookup databases (can be null)
|
||||||
|
private String NSRLPath, knownBadPath;
|
||||||
|
|
||||||
|
AddImageWizardChooseDataSourcePanel(AddImageWizardAddingProgressPanel proPanel) {
|
||||||
|
|
||||||
|
this.progressPanel = proPanel;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the visual component for the panel. The component is kept separate.
|
* Get the visual component for the panel. In this template, the component
|
||||||
* This can be more efficient: if the wizard is created but never displayed,
|
* is kept separate. This can be more efficient: if the wizard is created
|
||||||
* or not all panels are displayed, it is better to create only those which
|
* but never displayed, or not all panels are displayed, it is better to
|
||||||
* really need to be visible.
|
* create only those which really need to be visible.
|
||||||
*
|
*
|
||||||
* @return The UI component of this wizard panel.
|
* @return component the UI component of this wizard panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AddImageWizardChooseDataSourceVisual getComponent() {
|
public AddImageWizardChooseDataSourceVisual getComponent() {
|
||||||
if (null == component) {
|
if (component == null) {
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
component = new AddImageWizardChooseDataSourceVisual(this);
|
component = new AddImageWizardChooseDataSourceVisual(this);
|
||||||
}
|
}
|
||||||
@ -65,103 +77,156 @@ final class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Pane
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the help for this panel. When the panel is active, this is used as
|
* Help for this panel. When the panel is active, this is used as the help
|
||||||
* the help for the wizard dialog.
|
* for the wizard dialog.
|
||||||
*
|
*
|
||||||
* @return The help for this panel
|
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelp() {
|
public HelpCtx getHelp() {
|
||||||
// Show no Help button for this panel:
|
// Show no Help button for this panel:
|
||||||
return HelpCtx.DEFAULT_HELP;
|
return HelpCtx.DEFAULT_HELP;
|
||||||
|
// If you have context help:
|
||||||
|
// return new HelpCtx(SampleWizardPanel1.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Tests whether the panel is finished and it is safe to proceed to the next
|
||||||
|
* one. If the panel is valid, the "Next" button will be enabled.
|
||||||
*
|
*
|
||||||
* Tests whether or not the panel is finished. If the panel is valid, the
|
* @return boolean true if all the fields are correctly filled, false
|
||||||
* "Finish" button will be enabled.
|
* otherwise
|
||||||
*
|
|
||||||
* @return True or false.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
// If it is always OK to press Next or Finish, then:
|
return isNextEnable;
|
||||||
// return true;
|
|
||||||
// If it depends on some condition (form filled out...), then:
|
|
||||||
// return someCondition();
|
|
||||||
// and when this condition changes (last form field filled in...) then:
|
|
||||||
// fireChangeEvent();
|
|
||||||
/*
|
|
||||||
* When it is valid, the visual component calls enableNextButton to set
|
|
||||||
* this flag.
|
|
||||||
*/
|
|
||||||
return nextButtonIsEnabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the keyboard focus to the next button of the wizard.
|
* Move the keyboard focus to the next button
|
||||||
*/
|
*/
|
||||||
void moveFocusToNext() {
|
void moveFocusToNext() {
|
||||||
if (nextButtonIsEnabled) {
|
// set the focus to the next button of the wizard dialog if it's enabled
|
||||||
CallableSystemAction.get(AddImageAction.class).requestFocusForWizardButton(
|
if (isNextEnable) {
|
||||||
|
Lookup.getDefault().lookup(AddImageAction.class).requestFocusButton(
|
||||||
NbBundle.getMessage(this.getClass(), "AddImageWizardChooseDataSourcePanel.moveFocusNext"));
|
NbBundle.getMessage(this.getClass(), "AddImageWizardChooseDataSourcePanel.moveFocusNext"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the "Next" button and fires a change event to update the UI.
|
* Enable the "Next" button and fireChangeEvent to update the GUI
|
||||||
*
|
*
|
||||||
* @param isEnabled True if next button should be enabled, false otherwise.
|
* @param isEnabled true if next button can be enabled, false otherwise
|
||||||
*/
|
*/
|
||||||
void enableNextButton(boolean isEnabled) {
|
public void enableNextButton(boolean isEnabled) {
|
||||||
nextButtonIsEnabled = isEnabled;
|
isNextEnable = isEnabled;
|
||||||
fireChangeEvent();
|
fireChangeEvent();
|
||||||
}
|
}
|
||||||
|
private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Adds a listener to changes of the panel's validity.
|
||||||
|
*
|
||||||
|
* @param l the change listener to add
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void addChangeListener(ChangeListener listener) {
|
public final void addChangeListener(ChangeListener l) {
|
||||||
changeSupport.addChangeListener(listener);
|
synchronized (listeners) {
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Removes a listener to changes of the panel's validity.
|
||||||
|
*
|
||||||
|
* @param l the change listener to move
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void removeChangeListener(ChangeListener listener) {
|
public final void removeChangeListener(ChangeListener l) {
|
||||||
changeSupport.removeChangeListener(listener);
|
synchronized (listeners) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* This method is auto-generated. It seems that this method is used to
|
||||||
|
* listen to any change in this wizard panel.
|
||||||
*/
|
*/
|
||||||
protected final void fireChangeEvent() {
|
protected final void fireChangeEvent() {
|
||||||
changeSupport.fireChange();
|
Iterator<ChangeListener> it;
|
||||||
|
synchronized (listeners) {
|
||||||
|
it = new HashSet<ChangeListener>(listeners).iterator();
|
||||||
|
}
|
||||||
|
ChangeEvent ev = new ChangeEvent(this);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next().stateChanged(ev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// You can use a settings object to keep track of state. Normally the
|
||||||
|
// settings object will be the WizardDescriptor, so you can use
|
||||||
|
// WizardDescriptor.getProperty & putProperty to store information entered
|
||||||
|
// by the user.
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the current data--either the default data
|
* Provides the wizard panel with the current data--either the default data
|
||||||
* or already-modified settings, if the user used the previous and/or next
|
* or already-modified settings, if the user used the previous and/or next
|
||||||
* buttons. This method can be called multiple times on one instance of
|
* buttons. This method can be called multiple times on one instance of
|
||||||
* WizardDescriptor.Panel.
|
* WizardDescriptor.Panel. s
|
||||||
*
|
*
|
||||||
* @param settings The settings.
|
* @param settings the setting to be read from
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void readSettings(WizardDescriptor settings) {
|
public void readSettings(WizardDescriptor settings) {
|
||||||
|
|
||||||
|
//reset settings if supports it
|
||||||
|
//getComponent().reset();
|
||||||
|
// Prepopulate the image directory from the properties file
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Load hash database settings, enable or disable the checkbox
|
||||||
|
this.NSRLPath = null;
|
||||||
|
this.knownBadPath = null;
|
||||||
|
//JCheckBox lookupFilesCheckbox = component.getLookupFilesCheckbox();
|
||||||
|
//lookupFilesCheckbox.setSelected(false);
|
||||||
|
//lookupFilesCheckbox.setEnabled(this.NSRLPath != null || this.knownBadPath != null);
|
||||||
|
|
||||||
|
// If there is a process object in the settings, revert it and remove it from the settings
|
||||||
|
AddImageAction.CleanupTask cleanupTask = (AddImageAction.CleanupTask) settings.getProperty(AddImageAction.IMAGECLEANUPTASK_PROP);
|
||||||
|
if (cleanupTask != null) {
|
||||||
|
try {
|
||||||
|
cleanupTask.cleanup();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger logger = Logger.getLogger(AddImageWizardChooseDataSourcePanel.class.getName());
|
||||||
|
logger.log(Level.WARNING, "Error cleaning up image task", ex); //NON-NLS
|
||||||
|
} finally {
|
||||||
|
cleanupTask.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Provides the wizard panel with the opportunity to update the settings
|
||||||
|
* with its current customized state. Rather than updating its settings with
|
||||||
|
* every change in the GUI, it should collect them, and then only save them
|
||||||
|
* when requested to by this method. This method can be called multiple
|
||||||
|
* times on one instance of WizardDescriptor.Panel.
|
||||||
|
*
|
||||||
|
* @param settings the setting to be stored to
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void storeSettings(WizardDescriptor settings) {
|
public void storeSettings(WizardDescriptor settings) {
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* The "listener" for any property change in this panel. Any property
|
||||||
|
* changes will invoke the "fireChangeEvent()" method.
|
||||||
|
*
|
||||||
|
* @param evt the property change event
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2015 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");
|
||||||
@ -31,9 +31,7 @@ import javax.swing.JOptionPane;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import org.openide.WizardDescriptor;
|
import org.openide.WizardDescriptor;
|
||||||
import org.openide.util.ChangeSupport;
|
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
@ -42,108 +40,80 @@ import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The second panel of the add data source wizard. The visual component of this
|
* second panel of add image wizard, allows user to configure ingest modules.
|
||||||
* panel allows a user to configure the ingest modules for the ingest job for
|
*
|
||||||
* the data source, and this panel both runs the data source processor and
|
* TODO: review this for dead code. think about moving logic of adding image to
|
||||||
* starts the ingest job.
|
* 3rd panel( {@link AddImageWizardAddingProgressPanel}) separate class -jm
|
||||||
*/
|
*/
|
||||||
// JM: Think about moving the logic of adding image to the 3rd panel
|
class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||||
// ( {@link AddImageWizardAddingProgressPanel})
|
|
||||||
final class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDescriptor> {
|
|
||||||
|
|
||||||
private final AddImageWizardChooseDataSourcePanel selectDataSourcePanel;
|
|
||||||
private final AddImageWizardAddingProgressPanel progressPanel;
|
|
||||||
private final ChangeSupport changeSupport;
|
|
||||||
private final List<Content> newContents;
|
|
||||||
private final IngestJobSettingsPanel ingestJobSettingsPanel;
|
private final IngestJobSettingsPanel ingestJobSettingsPanel;
|
||||||
private Component component;
|
|
||||||
private volatile boolean ingestModulesConfigured;
|
|
||||||
private volatile boolean ingestJobStarted;
|
|
||||||
private AddImageAction.CleanupTask cleanupTask;
|
|
||||||
private DataSourceProcessor dsProcessor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of The second panel of the add data source wizard.
|
* The visual component that displays this panel. If you need to access the
|
||||||
* The visual component of this panel allows a user to configure the ingest
|
* component from this class, just use getComponent().
|
||||||
* modules for the ingest job for the data source.
|
|
||||||
*
|
|
||||||
* @param selectDataSourcePanel The second panel of the add data source
|
|
||||||
* wizard.
|
|
||||||
* @param progressPanel The third panel of the data source wizard.
|
|
||||||
*/
|
*/
|
||||||
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel selectDataSourcePanel, AddImageWizardAddingProgressPanel progressPanel) {
|
private Component component = null;
|
||||||
this.selectDataSourcePanel = selectDataSourcePanel;
|
|
||||||
this.progressPanel = progressPanel;
|
|
||||||
changeSupport = new ChangeSupport(this);
|
|
||||||
|
|
||||||
/*
|
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
|
||||||
* Create a collection to receive the Content objects returned by the
|
private boolean ingested = false;
|
||||||
* data source processor.
|
private boolean readyToIngest = false;
|
||||||
*/
|
|
||||||
newContents = Collections.synchronizedList(new ArrayList<Content>());
|
// task that will clean up the created database file if the wizard is cancelled before it finishes
|
||||||
|
private AddImageAction.CleanupTask cleanupTask;
|
||||||
|
|
||||||
|
private final AddImageAction addImageAction;
|
||||||
|
|
||||||
|
private final AddImageWizardAddingProgressPanel progressPanel;
|
||||||
|
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
|
||||||
|
|
||||||
|
private DataSourceProcessor dsProcessor;
|
||||||
|
|
||||||
|
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
|
||||||
|
this.addImageAction = action;
|
||||||
|
this.progressPanel = proPanel;
|
||||||
|
this.dataSourcePanel = dsPanel;
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the ingest job settings for the add data source wizard context
|
|
||||||
* and use them to create an ingest module configuration panel.
|
|
||||||
*/
|
|
||||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
|
IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
|
||||||
showIngestModuleConfigurationWarnings(ingestJobSettings);
|
showWarnings(ingestJobSettings);
|
||||||
ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
|
this.ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
|
||||||
|
|
||||||
/*
|
|
||||||
* This flag is used to stop the data source processing thread from
|
|
||||||
* starting the ingest job before the user has finished configuring the
|
|
||||||
* ingest modules. It is only set in the EDT.
|
|
||||||
*/
|
|
||||||
ingestModulesConfigured = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This flag is required because because the storeSettings method is
|
|
||||||
* currently called twice during the course of executing the add data
|
|
||||||
* source wizard, whether invoked from the new case wizard or
|
|
||||||
* independently. This means that the tryStartDataSourceIngestJob method
|
|
||||||
* gets called three times: once when the data source processor
|
|
||||||
* completes, and twice when the two storeSettings calls are made.
|
|
||||||
*
|
|
||||||
* TODO (AUT-1864): Figure out whether storeSettings is always called
|
|
||||||
* twice by NetBeans, or the extra call is due to an Autopsy bug.
|
|
||||||
*/
|
|
||||||
ingestJobStarted = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the visual component for the panel. In this template, the component
|
* Get the visual component for the panel. In this template, the component
|
||||||
* is kept separate. This can be more efficient: if the wizard is created
|
* is kept separate. This can be more efficient: if the wizard is created
|
||||||
* but never displayed, or not all panels are displayed, it is better to
|
* but never displayed, or not all panels are displayed, it is better to
|
||||||
* create only those which really need to be visible.
|
* create only those which really need to be visible.
|
||||||
*
|
*
|
||||||
* @return The UI component of this wizard panel.
|
* @return component the UI component of this wizard panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Component getComponent() {
|
public Component getComponent() {
|
||||||
if (null == component) {
|
if (component == null) {
|
||||||
component = new AddImageWizardIngestConfigVisual(this.ingestJobSettingsPanel);
|
component = new AddImageWizardIngestConfigVisual(this.ingestJobSettingsPanel);
|
||||||
}
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the help for this panel. When the panel is active, this is used as
|
* Help for this panel. When the panel is active, this is used as the help
|
||||||
* the help for the wizard dialog.
|
* for the wizard dialog.
|
||||||
*
|
*
|
||||||
* @return The help for this panel
|
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public HelpCtx getHelp() {
|
public HelpCtx getHelp() {
|
||||||
// Show no Help button for this panel:
|
// Show no Help button for this panel:
|
||||||
return HelpCtx.DEFAULT_HELP;
|
return HelpCtx.DEFAULT_HELP;
|
||||||
|
// If you have context help:
|
||||||
|
// return new HelpCtx(SampleWizardPanel1.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether or not the panel is finished. If the panel is valid, the
|
* Tests whether the panel is finished. If the panel is valid, the "Finish"
|
||||||
* "Finish" button will be enabled.
|
* button will be enabled.
|
||||||
*
|
*
|
||||||
* @return True or false.
|
* @return true the finish button should be always enabled at this point
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
@ -153,53 +123,52 @@ final class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<Wi
|
|||||||
// return someCondition();
|
// return someCondition();
|
||||||
// and when this condition changes (last form field filled in...) then:
|
// and when this condition changes (last form field filled in...) then:
|
||||||
// fireChangeEvent();
|
// fireChangeEvent();
|
||||||
|
// and uncomment the complicated stuff below.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Adds a listener to changes of the panel's validity.
|
||||||
|
*
|
||||||
|
* @param l the change listener to add
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void addChangeListener(ChangeListener listener) {
|
public final void addChangeListener(ChangeListener l) {
|
||||||
changeSupport.addChangeListener(listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Removes a listener to changes of the panel's validity.
|
||||||
|
*
|
||||||
|
* @param l the change listener to move
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void removeChangeListener(ChangeListener listener) {
|
public final void removeChangeListener(ChangeListener l) {
|
||||||
changeSupport.removeChangeListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
protected final void fireChangeEvent() {
|
|
||||||
changeSupport.fireChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// You can use a settings object to keep track of state. Normally the
|
||||||
|
// settings object will be the WizardDescriptor, so you can use
|
||||||
|
// WizardDescriptor.getProperty & putProperty to store information entered
|
||||||
|
// by the user.
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the current data--either the default data
|
* Provides the wizard panel with the current data--either the default data
|
||||||
* or already-modified settings, if the user used the previous and/or next
|
* or already-modified settings, if the user used the previous and/or next
|
||||||
* buttons. This method can be called multiple times on one instance of
|
* buttons. This method can be called multiple times on one instance of
|
||||||
* WizardDescriptor.Panel.
|
* WizardDescriptor.Panel.
|
||||||
*
|
*
|
||||||
* @param settings The settings.
|
* @param settings the setting to be read from
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void readSettings(WizardDescriptor settings) {
|
public void readSettings(WizardDescriptor settings) {
|
||||||
/*
|
JButton cancel = new JButton(
|
||||||
* The user has pushed the next button on the previous panel of the add
|
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text"));
|
||||||
* data source wizard. Start the data source processor so it can run
|
|
||||||
* while the user is doing the ingest module configuration. It is ok to
|
|
||||||
* do this now because the back button is disabled for this wizard - the
|
|
||||||
* user cannot go back to choose a different data source.
|
|
||||||
*
|
|
||||||
* RC: Not sure why the cancel button is disabled.
|
|
||||||
*/
|
|
||||||
JButton cancel = new JButton(NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text"));
|
|
||||||
cancel.setEnabled(false);
|
cancel.setEnabled(false);
|
||||||
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, cancel});
|
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, cancel});
|
||||||
|
cleanupTask = null;
|
||||||
|
readyToIngest = false;
|
||||||
|
|
||||||
|
newContents.clear();
|
||||||
|
|
||||||
|
// Start processing the data source by handing it off to the selected DSP,
|
||||||
|
// so it gets going in the background while the user is still picking the Ingest modules
|
||||||
startDataSourceProcessing(settings);
|
startDataSourceProcessing(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,29 +183,16 @@ final class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<Wi
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void storeSettings(WizardDescriptor settings) {
|
public void storeSettings(WizardDescriptor settings) {
|
||||||
/*
|
|
||||||
* The user has pushed the next button on this panel. Save the ingest
|
|
||||||
* job settings for the add data source wizard context and try to start
|
|
||||||
* the ingest job. It is ok to do this now because the back button is
|
|
||||||
* disabled for this wizard - the user cannot go back to choose a
|
|
||||||
* different data source. However, the job will not be started if either
|
|
||||||
* the data source processor has not finished yet, or it finished but
|
|
||||||
* did not produce any Content objects for the data source.
|
|
||||||
*/
|
|
||||||
IngestJobSettings ingestJobSettings = this.ingestJobSettingsPanel.getSettings();
|
IngestJobSettings ingestJobSettings = this.ingestJobSettingsPanel.getSettings();
|
||||||
ingestJobSettings.save();
|
ingestJobSettings.save();
|
||||||
showIngestModuleConfigurationWarnings(ingestJobSettings);
|
showWarnings(ingestJobSettings);
|
||||||
ingestModulesConfigured = true;
|
|
||||||
tryStartIngestJob();
|
// Start ingest if it hasn't already been started
|
||||||
|
readyToIngest = true;
|
||||||
|
startIngest();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static void showWarnings(IngestJobSettings ingestJobSettings) {
|
||||||
* Displays any warnings returned form operations on the ingest job settings
|
|
||||||
* for the add data source wizard context.
|
|
||||||
*
|
|
||||||
* @param ingestJobSettings The ingest job settings.
|
|
||||||
*/
|
|
||||||
private static void showIngestModuleConfigurationWarnings(IngestJobSettings ingestJobSettings) {
|
|
||||||
List<String> warnings = ingestJobSettings.getWarnings();
|
List<String> warnings = ingestJobSettings.getWarnings();
|
||||||
if (warnings.isEmpty() == false) {
|
if (warnings.isEmpty() == false) {
|
||||||
StringBuilder warningMessage = new StringBuilder();
|
StringBuilder warningMessage = new StringBuilder();
|
||||||
@ -248,78 +204,76 @@ final class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<Wi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the data source processor selected by the user when the previous
|
* Start ingest after verifying we have a new image, we are ready to ingest,
|
||||||
* panel was displayed.
|
* and we haven't already ingested.
|
||||||
|
*/
|
||||||
|
private void startIngest() {
|
||||||
|
if (!newContents.isEmpty() && readyToIngest && !ingested) {
|
||||||
|
ingested = true;
|
||||||
|
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettingsPanel.getSettings());
|
||||||
|
progressPanel.setStateFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the Data source processing by kicking off the selected
|
||||||
|
* DataSourceProcessor
|
||||||
*/
|
*/
|
||||||
private void startDataSourceProcessing(WizardDescriptor settings) {
|
private void startDataSourceProcessing(WizardDescriptor settings) {
|
||||||
/*
|
final UUID dataSourceId = UUID.randomUUID();
|
||||||
* Create a unique id to use to synch up the data source events that are
|
|
||||||
* published for the data source being added.
|
|
||||||
*/
|
|
||||||
final UUID addDataSourceEventId = UUID.randomUUID();
|
|
||||||
|
|
||||||
/*
|
// Add a cleanup task to interrupt the background process if the
|
||||||
* Register a clean up task with the action that invokes the add data
|
// wizard exits while the background process is running.
|
||||||
* source wizard. This action takes responsibility for doing cleanup
|
cleanupTask = addImageAction.new CleanupTask() {
|
||||||
* after the wizard is closed (see the definition of the AddImageAction
|
|
||||||
* class).
|
|
||||||
*/
|
|
||||||
cleanupTask = CallableSystemAction.get(AddImageAction.class).new CleanupTask() {
|
|
||||||
@Override
|
@Override
|
||||||
void cleanup() throws Exception {
|
void cleanup() throws Exception {
|
||||||
new Thread(() -> {
|
cancelDataSourceProcessing(dataSourceId);
|
||||||
/*
|
|
||||||
* Publish a failed adding data source event, using the
|
|
||||||
* event id associated with the adding data source event.
|
|
||||||
*/
|
|
||||||
Case.getCurrentCase().notifyFailedAddingDataSource(addDataSourceEventId);
|
|
||||||
}).start();
|
|
||||||
dsProcessor.cancel();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cleanupTask.enable();
|
cleanupTask.enable();
|
||||||
|
|
||||||
/*
|
// get the selected DSProcessor
|
||||||
* Publish an adding data source event.
|
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
|
||||||
*/
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Case.getCurrentCase().notifyAddingDataSource(addDataSourceEventId);
|
Case.getCurrentCase().notifyAddingDataSource(dataSourceId);
|
||||||
}).start();
|
}).start();
|
||||||
|
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
|
||||||
/*
|
|
||||||
* Notify the progress panel for this wizard that data source processing
|
|
||||||
* is starting.
|
|
||||||
*/
|
|
||||||
progressPanel.setStateStarted();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the data source processor the user selected and start it.
|
|
||||||
*/
|
|
||||||
dsProcessor = selectDataSourcePanel.getComponent().getCurrentDSProcessor();
|
|
||||||
DataSourceProcessorCallback callback = new DataSourceProcessorCallback() {
|
|
||||||
@Override
|
@Override
|
||||||
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||||
dataSourceProcessorDone(addDataSourceEventId, result, errList, contents);
|
dataSourceProcessorDone(dataSourceId, result, errList, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
dsProcessor.run(progressPanel.getDSPProgressMonitor(), callback);
|
|
||||||
|
progressPanel.setStateStarted();
|
||||||
|
|
||||||
|
// Kick off the DSProcessor
|
||||||
|
dsProcessor.run(progressPanel.getDSPProgressMonitorImpl(), cbObj);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The callback for the data source processor to invoke when it finishes.
|
* Cancels the data source processing - in case the users presses 'Cancel'
|
||||||
*/
|
*/
|
||||||
private void dataSourceProcessorDone(UUID addDataSourceEventId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
||||||
/*
|
new Thread(() -> {
|
||||||
* Disable the clean up task.
|
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
||||||
*/
|
}).start();
|
||||||
|
dsProcessor.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback for the data source processor. Invoked by the DSP on the EDT
|
||||||
|
* thread, when it finishes processing the data source.
|
||||||
|
*/
|
||||||
|
private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||||
|
// disable the cleanup task
|
||||||
cleanupTask.disable();
|
cleanupTask.disable();
|
||||||
|
|
||||||
/*
|
// Get attention for the process finish
|
||||||
* Get the user's attention.
|
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
|
||||||
*
|
|
||||||
* RC: Is this really necessary?
|
|
||||||
*/
|
|
||||||
java.awt.Toolkit.getDefaultToolkit().beep();
|
|
||||||
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
|
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
|
||||||
if (panel != null) {
|
if (panel != null) {
|
||||||
Window w = SwingUtilities.getWindowAncestor(panel);
|
Window w = SwingUtilities.getWindowAncestor(panel);
|
||||||
@ -327,12 +281,10 @@ final class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<Wi
|
|||||||
w.toFront();
|
w.toFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Tell the panel we're done
|
||||||
/*
|
|
||||||
* Notify the progress panel that the data source processor has finished
|
|
||||||
* its work and display the processing results on the progress panel.
|
|
||||||
*/
|
|
||||||
progressPanel.setStateFinished();
|
progressPanel.setStateFinished();
|
||||||
|
|
||||||
|
//check the result and display to user
|
||||||
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
|
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
|
||||||
progressPanel.getComponent().setProgressBarTextAndColor(
|
progressPanel.getComponent().setProgressBarTextAndColor(
|
||||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
|
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
|
||||||
@ -340,45 +292,32 @@ final class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<Wi
|
|||||||
progressPanel.getComponent().setProgressBarTextAndColor(
|
progressPanel.getComponent().setProgressBarTextAndColor(
|
||||||
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
|
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if errors, display them on the progress panel
|
||||||
boolean critErr = false;
|
boolean critErr = false;
|
||||||
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
|
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
|
||||||
critErr = true;
|
critErr = true;
|
||||||
}
|
}
|
||||||
for (String err : errList) {
|
for (String err : errList) {
|
||||||
progressPanel.displayDataSourceProcessorError(err, critErr);
|
// TBD: there probably should be an error level for each error
|
||||||
|
progressPanel.addErrors(err, critErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Save the Content objects returned by the data source processor.
|
|
||||||
*/
|
|
||||||
newContents.clear();
|
newContents.clear();
|
||||||
newContents.addAll(contents);
|
newContents.addAll(contents);
|
||||||
|
|
||||||
|
//notify the UI of the new content added to the case
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
if (!newContents.isEmpty()) {
|
if (!newContents.isEmpty()) {
|
||||||
Case.getCurrentCase().notifyDataSourceAdded(newContents.get(0), addDataSourceEventId);
|
Case.getCurrentCase().notifyDataSourceAdded(newContents.get(0), dataSourceId);
|
||||||
} else {
|
} else {
|
||||||
Case.getCurrentCase().notifyFailedAddingDataSource(addDataSourceEventId);
|
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
/*
|
// Start ingest if we can
|
||||||
* Try starting the ingest job for this data source. If the data source
|
progressPanel.setStateStarted();
|
||||||
* processor finished before the user finished configuring the ingest
|
startIngest();
|
||||||
* modules, the job will not be started yet.
|
|
||||||
*/
|
|
||||||
tryStartIngestJob();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts an ingest job for the data source, but only if the data source
|
|
||||||
* processor has been run and has produced content, and the ingest modules
|
|
||||||
* are configured.
|
|
||||||
*/
|
|
||||||
synchronized private void tryStartIngestJob() {
|
|
||||||
if (!newContents.isEmpty() && ingestModulesConfigured && !ingestJobStarted) {
|
|
||||||
ingestJobStarted = true; // See contructor for comment on this flag.
|
|
||||||
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettingsPanel.getSettings());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011 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,52 +28,52 @@ import org.openide.WizardDescriptor;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The iterator for the add data source wizard panels.
|
* The iterator class for the "Add Image" wizard panel. This class is used to
|
||||||
|
* iterate on the sequence of panels of the "Add Image" wizard panel.
|
||||||
*/
|
*/
|
||||||
final class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescriptor> {
|
class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescriptor> {
|
||||||
|
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
private List<WizardDescriptor.Panel<WizardDescriptor>> panels;
|
private List<WizardDescriptor.Panel<WizardDescriptor>> panels;
|
||||||
|
private AddImageAction action;
|
||||||
|
|
||||||
|
AddImageWizardIterator(AddImageAction action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazily create the panels for the add data source wizard.
|
* Initialize panels representing individual wizard's steps and sets various
|
||||||
|
* properties for them influencing wizard appearance.
|
||||||
*/
|
*/
|
||||||
private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
|
private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
|
||||||
if (null == panels) {
|
if (panels == null) {
|
||||||
panels = new ArrayList<>();
|
panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the wizard panels. The first panel is used to select a
|
|
||||||
* data source. The second panel is used to configure the ingest
|
|
||||||
* modules. The third panel has a progress bar that tracks progress
|
|
||||||
* as the Sleuthkit layer adds the data source to the case database.
|
|
||||||
*/
|
|
||||||
AddImageWizardChooseDataSourcePanel dsPanel = new AddImageWizardChooseDataSourcePanel();
|
|
||||||
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel();
|
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel();
|
||||||
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, progressPanel);
|
|
||||||
|
AddImageWizardChooseDataSourcePanel dsPanel = new AddImageWizardChooseDataSourcePanel(progressPanel);
|
||||||
|
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel);
|
||||||
|
|
||||||
panels.add(dsPanel);
|
panels.add(dsPanel);
|
||||||
panels.add(ingestConfigPanel);
|
panels.add(ingestConfigPanel);
|
||||||
panels.add(progressPanel);
|
panels.add(progressPanel);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the appearance of the visual components of the panels.
|
|
||||||
*/
|
|
||||||
String[] steps = new String[panels.size()];
|
String[] steps = new String[panels.size()];
|
||||||
for (int i = 0; i < panels.size(); i++) {
|
for (int i = 0; i < panels.size(); i++) {
|
||||||
Component visualComponent = panels.get(i).getComponent();
|
Component c = panels.get(i).getComponent();
|
||||||
// Default step name to component name.
|
// Default step name to component name of panel.
|
||||||
steps[i] = visualComponent.getName();
|
steps[i] = c.getName();
|
||||||
if (visualComponent instanceof JComponent) {
|
if (c instanceof JComponent) { // assume Swing components
|
||||||
JComponent jc = (JComponent) visualComponent;
|
JComponent jc = (JComponent) c;
|
||||||
// Set step number.
|
// Sets step number of a component
|
||||||
jc.putClientProperty("WizardPanel_contentSelectedIndex", i);
|
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
|
||||||
// Sets step name.
|
// Sets steps names for a panel
|
||||||
jc.putClientProperty("WizardPanel_contentData", steps);
|
jc.putClientProperty("WizardPanel_contentData", steps);
|
||||||
// Turn on subtitle creation.
|
// Turn on subtitle creation on each step
|
||||||
jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
|
jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
|
||||||
// Show steps on the left side, with image in the background.
|
// Show steps on the left side with the image on the background
|
||||||
jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
|
jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
|
||||||
// Turn on step numbering.
|
// Turn on numbering of all steps
|
||||||
jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
|
jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,10 +81,20 @@ final class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDe
|
|||||||
return panels;
|
return panels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the current panel. Note: 0 = panel 1, 1 = panel 2,
|
||||||
|
* etc
|
||||||
|
*
|
||||||
|
* @return index the current panel index
|
||||||
|
*/
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current panel.
|
* Gets the current panel.
|
||||||
*
|
*
|
||||||
* @return The current panel.
|
* @return panel the current panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public WizardDescriptor.Panel<WizardDescriptor> current() {
|
public WizardDescriptor.Panel<WizardDescriptor> current() {
|
||||||
@ -98,17 +108,18 @@ final class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDe
|
|||||||
/**
|
/**
|
||||||
* Gets the name of the current panel.
|
* Gets the name of the current panel.
|
||||||
*
|
*
|
||||||
* @return The name of the current panel.
|
* @return name the name of the current panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
return NbBundle.getMessage(this.getClass(), "AddImageWizardIterator.stepXofN", Integer.toString(index + 1), getPanels().size());
|
return NbBundle.getMessage(this.getClass(), "AddImageWizardIterator.stepXofN", Integer.toString(index + 1),
|
||||||
|
getPanels().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether there is a next panel.
|
* Tests whether there is a next panel.
|
||||||
*
|
*
|
||||||
* @return True or false.
|
* @return boolean true if it has next panel, false if not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
@ -118,18 +129,17 @@ final class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDe
|
|||||||
/**
|
/**
|
||||||
* Tests whether there is a previous panel.
|
* Tests whether there is a previous panel.
|
||||||
*
|
*
|
||||||
* @return True or false.
|
* @return boolean true if it has previous panel, false if not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
// disable the previous button on all panels
|
||||||
public boolean hasPrevious() {
|
public boolean hasPrevious() {
|
||||||
/*
|
|
||||||
* Disable the back buttons for the add data source wizard.
|
|
||||||
*/
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves to the next panel.
|
* Moves to the next panel. I.e. increment its index, need not actually
|
||||||
|
* change any GUI itself.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void nextPanel() {
|
public void nextPanel() {
|
||||||
@ -140,7 +150,8 @@ final class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves to the previous panel.
|
* Moves to the previous panel. I.e. decrement its index, need not actually
|
||||||
|
* change any GUI itself.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void previousPanel() {
|
public void previousPanel() {
|
||||||
@ -153,18 +164,12 @@ final class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDe
|
|||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// If nothing unusual changes in the middle of the wizard, simply:
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void addChangeListener(ChangeListener l) {
|
public void addChangeListener(ChangeListener l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void removeChangeListener(ChangeListener l) {
|
public void removeChangeListener(ChangeListener l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ AddImageAction.ingestConfig.ongoingIngest.msg=<html>Ingest is ongoing on another
|
|||||||
AddImageAction.ingestConfig.ongoingIngest.title=Ingest in progress
|
AddImageAction.ingestConfig.ongoingIngest.title=Ingest in progress
|
||||||
AddImageTask.run.progress.adding=Adding\: {0}
|
AddImageTask.run.progress.adding=Adding\: {0}
|
||||||
AddImageTask.interrupt.exception.msg=Error stopping add-image process.
|
AddImageTask.interrupt.exception.msg=Error stopping add-image process.
|
||||||
|
AddImageWizardAddingProgressPanel.isValid.focusNext=Next >
|
||||||
AddImageWizardAddingProgressPanel.stateStarted.progressBarText=*This process may take some time for large data sources.
|
AddImageWizardAddingProgressPanel.stateStarted.progressBarText=*This process may take some time for large data sources.
|
||||||
AddImageWizardAddingProgressVisual.addingDsComplete.text=Adding Data Source - Complete
|
AddImageWizardAddingProgressVisual.addingDsComplete.text=Adding Data Source - Complete
|
||||||
AddImageWizardAddingProgressVisual.getName.text=Add Data Source
|
AddImageWizardAddingProgressVisual.getName.text=Add Data Source
|
||||||
|
@ -88,6 +88,7 @@ AddImageAction.ingestConfig.ongoingIngest.msg=<html>\u4ed6\u306e\u30c7\u30fc\u30
|
|||||||
AddImageAction.ingestConfig.ongoingIngest.title=\u51e6\u7406\u4e2d
|
AddImageAction.ingestConfig.ongoingIngest.title=\u51e6\u7406\u4e2d
|
||||||
AddImageTask.run.progress.adding=\u8ffd\u52a0\u4e2d\uff1a{0}
|
AddImageTask.run.progress.adding=\u8ffd\u52a0\u4e2d\uff1a{0}
|
||||||
AddImageTask.interrupt.exception.msg=\u30a4\u30e1\u30fc\u30b8\u8ffd\u52a0\u30d7\u30ed\u30bb\u30b9\u306e\u505c\u6b62\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
AddImageTask.interrupt.exception.msg=\u30a4\u30e1\u30fc\u30b8\u8ffd\u52a0\u30d7\u30ed\u30bb\u30b9\u306e\u505c\u6b62\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||||
|
AddImageWizardAddingProgressPanel.isValid.focusNext=\u6b21 >
|
||||||
AddImageWizardAddingProgressPanel.stateStarted.progressBarText=*\u5927\u304d\u3044\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u5834\u5408\u3001\u3053\u306e\u30d7\u30ed\u30bb\u30b9\u306f\u6642\u9593\u304c\u304b\u304b\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
|
AddImageWizardAddingProgressPanel.stateStarted.progressBarText=*\u5927\u304d\u3044\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306e\u5834\u5408\u3001\u3053\u306e\u30d7\u30ed\u30bb\u30b9\u306f\u6642\u9593\u304c\u304b\u304b\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
|
||||||
AddImageWizardAddingProgressVisual.addingDsComplete.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 - \u5b8c\u4e86
|
AddImageWizardAddingProgressVisual.addingDsComplete.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0 - \u5b8c\u4e86
|
||||||
AddImageWizardAddingProgressVisual.getName.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
AddImageWizardAddingProgressVisual.getName.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user