19 package org.sleuthkit.autopsy.casemodule;
 
   21 import java.awt.Color;
 
   22 import java.awt.Cursor;
 
   23 import java.awt.EventQueue;
 
   24 import java.awt.Window;
 
   25 import java.util.ArrayList;
 
   26 import java.util.Collections;
 
   27 import java.util.HashSet;
 
   28 import java.util.Iterator;
 
   29 import java.util.List;
 
   31 import java.util.UUID;
 
   32 import java.util.logging.Level;
 
   33 import javax.swing.JOptionPane;
 
   34 import javax.swing.SwingUtilities;
 
   35 import javax.swing.event.ChangeEvent;
 
   36 import javax.swing.event.ChangeListener;
 
   37 import org.openide.WizardDescriptor;
 
   38 import org.openide.util.HelpCtx;
 
   39 import org.openide.util.Lookup;
 
   40 import org.openide.util.NbBundle;
 
   41 import org.openide.windows.WindowManager;
 
   60 @SuppressWarnings(
"PMD.SingularField") 
 
   61 class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
 
   63     private boolean readyToIngest = 
false;
 
   65     private AddImageAction.CleanupTask cleanupTask;
 
   67     private final AddImageAction addImageAction;
 
   69     private DataSourceProcessor dsProcessor = null;
 
   70     private boolean cancelled;
 
   75     private boolean imgAdded = 
false;
 
   76     private boolean ingested = 
false;
 
   81     private AddImageWizardAddingProgressVisual component;
 
   82     private final Set<ChangeListener> listeners = 
new HashSet<>(1); 
 
   83     private final List<Content> newContents = Collections.synchronizedList(
new ArrayList<>());
 
   84     private final DSPProgressMonitorImpl dspProgressMonitorImpl = 
new DSPProgressMonitorImpl();
 
   85     private IngestJobSettings ingestJobSettings;
 
   87     AddImageWizardAddingProgressPanel(AddImageAction action) {
 
   88         this.addImageAction = action;
 
   91     DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
 
   92         return dspProgressMonitorImpl;
 
  100             EventQueue.invokeLater(
new Runnable() {
 
  103                     getComponent().getProgressBar().setIndeterminate(indeterminate);
 
  111             EventQueue.invokeLater(
new Runnable() {
 
  114                     getComponent().getProgressBar().setValue(progress);
 
  122             EventQueue.invokeLater(
new Runnable() {
 
  125                     getComponent().getProgressBar().setMaximum(max);
 
  133             EventQueue.invokeLater(
new Runnable() {
 
  136                     getComponent().setProgressMsgText(text);
 
  154     public AddImageWizardAddingProgressVisual getComponent() {
 
  155         if (component == null) {
 
  156             component = 
new AddImageWizardAddingProgressVisual();
 
  168     public HelpCtx getHelp() {
 
  170         return HelpCtx.DEFAULT_HELP;
 
  180     public boolean isValid() {
 
  183             Lookup.getDefault().lookup(AddImageAction.class).requestFocusButton(
 
  184                     NbBundle.getMessage(
this.getClass(), 
"AddImageWizardAddingProgressPanel.isValid.focusNext"));
 
  193     void setStateStarted() {
 
  194         component.getProgressBar().setIndeterminate(
true);
 
  195         component.setProgressBarTextAndColor(
 
  196                 NbBundle.getMessage(
this.getClass(), 
"AddImageWizardAddingProgressPanel.stateStarted.progressBarText"), 0, Color.black);
 
  202     void setStateFinished() {
 
  204         getComponent().setStateFinished();
 
  214     public final void addChangeListener(ChangeListener l) {
 
  215         synchronized (listeners) {
 
  226     public final void removeChangeListener(ChangeListener l) {
 
  227         synchronized (listeners) {
 
  236     protected final void fireChangeEvent() {
 
  237         Iterator<ChangeListener> it;
 
  238         synchronized (listeners) {
 
  239             it = 
new HashSet<>(listeners).iterator();
 
  241         ChangeEvent ev = 
new ChangeEvent(
this);
 
  242         while (it.hasNext()) {
 
  243             it.next().stateChanged(ev);
 
  254     public void readSettings(WizardDescriptor settings) {
 
  257         settings.setOptions(
new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
 
  259             getComponent().setStateFinished();
 
  263     void resetReadyToIngest() {
 
  264         this.readyToIngest = 
false;
 
  267     void setIngestJobSettings(IngestJobSettings ingestSettings) {
 
  268         showWarnings(ingestSettings);
 
  269         this.readyToIngest = 
true;
 
  270         this.ingestJobSettings = ingestSettings;
 
  280     public void storeSettings(WizardDescriptor settings) {
 
  294     void addErrors(String errorString, 
boolean critical) {
 
  295         getComponent().showErrors(errorString, critical);
 
  302     private void startIngest() {
 
  303         if (!newContents.isEmpty() && readyToIngest && !ingested) {
 
  305             IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettings);
 
  310     private static void showWarnings(IngestJobSettings ingestJobSettings) {
 
  311         List<String> warnings = ingestJobSettings.getWarnings();
 
  312         if (warnings.isEmpty() == 
false) {
 
  313             StringBuilder warningMessage = 
new StringBuilder();
 
  314             for (String warning : warnings) {
 
  315                 warningMessage.append(warning).append(
"\n");
 
  317             JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), warningMessage.toString());
 
  325     void startDataSourceProcessing(DataSourceProcessor dsp) {
 
  326         if (dsProcessor == null) {  
 
  327             final UUID dataSourceId = UUID.randomUUID();
 
  330             readyToIngest = 
false;
 
  335             cleanupTask = addImageAction.new CleanupTask() {
 
  337                 void cleanup() throws Exception {
 
  338                     WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
 
  339                     cancelDataSourceProcessing(dataSourceId);
 
  341                     WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 
  345             cleanupTask.enable();
 
  349                     Case.getCurrentCaseThrows().notifyAddingDataSource(dataSourceId);
 
  350                 } 
catch (NoCurrentCaseException ex) {
 
  351                      Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  354             DataSourceProcessorCallback cbObj = 
new DataSourceProcessorCallback() {
 
  356                 public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
 
  357                     dataSourceProcessorDone(dataSourceId, result, errList, contents);
 
  364             dsProcessor.run(getDSPProgressMonitorImpl(), cbObj);
 
  371     private void cancelDataSourceProcessing(UUID dataSourceId) {
 
  372         dsProcessor.cancel();
 
  379     private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
 
  381         cleanupTask.disable();
 
  385         if (PlatformUtil.isWindowsOS() == 
true) {
 
  386             java.awt.Toolkit.getDefaultToolkit().beep(); 
 
  388         AddImageWizardAddingProgressVisual panel = getComponent();
 
  390             Window w = SwingUtilities.getWindowAncestor(panel);
 
  399         if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
 
  400             getComponent().setProgressBarTextAndColor(
 
  401                     NbBundle.getMessage(
this.getClass(), 
"AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
 
  403             getComponent().setProgressBarTextAndColor(
 
  404                     NbBundle.getMessage(
this.getClass(), 
"AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
 
  408         boolean critErr = 
false;
 
  409         if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
 
  412         for (String err : errList) {
 
  414             addErrors(err, critErr);
 
  420                 if (!contents.isEmpty()) {
 
  421                     Case.getCurrentCaseThrows().notifyDataSourceAdded(contents.get(0), dataSourceId);
 
  423                     Case.getCurrentCaseThrows().notifyFailedAddingDataSource(dataSourceId);
 
  425             } 
catch (NoCurrentCaseException ex) {
 
  426                 Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  432             newContents.addAll(contents);
 
void setIndeterminate(final boolean indeterminate)
void setProgressText(final String text)
void setProgressMax(final int max)
void setProgress(final int progress)