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;
 
   61 @SuppressWarnings(
"PMD.SingularField") 
 
   62 class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
 
   64     private boolean readyToIngest = 
false;
 
   66     private AddImageAction.CleanupTask cleanupTask;
 
   68     private final AddImageAction addImageAction;
 
   70     private DataSourceProcessor dsProcessor = null;
 
   71     private boolean cancelled;
 
   76     private boolean imgAdded = 
false;
 
   77     private boolean ingested = 
false;
 
   82     private AddImageWizardAddingProgressVisual component;
 
   83     private final Set<ChangeListener> listeners = 
new HashSet<>(1); 
 
   84     private final List<Content> newContents = Collections.synchronizedList(
new ArrayList<>());
 
   85     private final DSPProgressMonitorImpl dspProgressMonitorImpl = 
new DSPProgressMonitorImpl();
 
   86     private IngestJobSettings ingestJobSettings;
 
   88     AddImageWizardAddingProgressPanel(AddImageAction action) {
 
   89         this.addImageAction = action;
 
   92     DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
 
   93         return dspProgressMonitorImpl;
 
  101             EventQueue.invokeLater(
new Runnable() {
 
  104                     getComponent().getProgressBar().setIndeterminate(indeterminate);
 
  112             EventQueue.invokeLater(
new Runnable() {
 
  115                     getComponent().getProgressBar().setValue(progress);
 
  123             EventQueue.invokeLater(
new Runnable() {
 
  126                     getComponent().getProgressBar().setMaximum(max);
 
  134             EventQueue.invokeLater(
new Runnable() {
 
  137                     getComponent().setProgressMsgText(text);
 
  155     public AddImageWizardAddingProgressVisual getComponent() {
 
  156         if (component == null) {
 
  157             component = 
new AddImageWizardAddingProgressVisual();
 
  169     public HelpCtx getHelp() {
 
  171         return HelpCtx.DEFAULT_HELP;
 
  181     public boolean isValid() {
 
  184             Lookup.getDefault().lookup(AddImageAction.class).requestFocusButton(
 
  185                     NbBundle.getMessage(
this.getClass(), 
"AddImageWizardAddingProgressPanel.isValid.focusNext"));
 
  194     void setStateStarted() {
 
  195         component.getProgressBar().setIndeterminate(
true);
 
  196         component.setProgressBarTextAndColor(
 
  197                 NbBundle.getMessage(
this.getClass(), 
"AddImageWizardAddingProgressPanel.stateStarted.progressBarText"), 0, Color.black);
 
  203     void setStateFinished() {
 
  205         getComponent().setStateFinished();
 
  215     public final void addChangeListener(ChangeListener l) {
 
  216         synchronized (listeners) {
 
  227     public final void removeChangeListener(ChangeListener l) {
 
  228         synchronized (listeners) {
 
  237     protected final void fireChangeEvent() {
 
  238         Iterator<ChangeListener> it;
 
  239         synchronized (listeners) {
 
  240             it = 
new HashSet<>(listeners).iterator();
 
  242         ChangeEvent ev = 
new ChangeEvent(
this);
 
  243         while (it.hasNext()) {
 
  244             it.next().stateChanged(ev);
 
  255     public void readSettings(WizardDescriptor settings) {
 
  258         settings.setOptions(
new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
 
  260             getComponent().setStateFinished();
 
  264     void resetReadyToIngest() {
 
  265         this.readyToIngest = 
false;
 
  268     void setIngestJobSettings(IngestJobSettings ingestSettings) {
 
  269         showWarnings(ingestSettings);
 
  270         this.readyToIngest = 
true;
 
  271         this.ingestJobSettings = ingestSettings;
 
  281     public void storeSettings(WizardDescriptor settings) {
 
  295     void addErrors(String errorString, 
boolean critical) {
 
  296         getComponent().showErrors(errorString, critical);
 
  303     private void startIngest() {
 
  304         if (!newContents.isEmpty() && readyToIngest && !ingested) {
 
  306             if (dsProcessor != null && !dsProcessor.supportsIngestStream()) {
 
  307                 IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettings);
 
  313     private static void showWarnings(IngestJobSettings ingestJobSettings) {
 
  314         List<String> warnings = ingestJobSettings.getWarnings();
 
  315         if (warnings.isEmpty() == 
false) {
 
  316             StringBuilder warningMessage = 
new StringBuilder();
 
  317             for (String warning : warnings) {
 
  318                 warningMessage.append(warning).append(
"\n");
 
  320             JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), warningMessage.toString());
 
  333     void startDataSourceProcessing(DataSourceProcessor dsp, Host selectedHost) {
 
  334         if (dsProcessor == null) {  
 
  335             final UUID dataSourceId = UUID.randomUUID();
 
  342                 cleanupTask = addImageAction.new CleanupTask() {
 
  344                     void cleanup() throws Exception {
 
  345                         WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
 
  346                         cancelDataSourceProcessing(dataSourceId);
 
  348                         WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 
  352                 cleanupTask.enable();
 
  355                     Case.getCurrentCaseThrows().notifyAddingDataSource(dataSourceId);
 
  356                 } 
catch (NoCurrentCaseException ex) {
 
  357                     Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  360                 DataSourceProcessorCallback cbObj = 
new DataSourceProcessorCallback() {
 
  362                     public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
 
  363                         dataSourceProcessorDone(dataSourceId, result, errList, contents);
 
  368                 if (dsProcessor.supportsIngestStream()) {
 
  370                     readyToIngest = 
false;
 
  371                     dsProcessor.runWithIngestStream(selectedHost, ingestJobSettings, getDSPProgressMonitorImpl(), cbObj);
 
  373                     dsProcessor.run(selectedHost, getDSPProgressMonitorImpl(), cbObj);
 
  383     private void cancelDataSourceProcessing(UUID dataSourceId) {
 
  384         dsProcessor.cancel();
 
  391     private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
 
  393         cleanupTask.disable();
 
  397         if (PlatformUtil.isWindowsOS() == 
true) {
 
  398             java.awt.Toolkit.getDefaultToolkit().beep(); 
 
  400         AddImageWizardAddingProgressVisual panel = getComponent();
 
  402             Window w = SwingUtilities.getWindowAncestor(panel);
 
  411         if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
 
  412             getComponent().setProgressBarTextAndColor(
 
  413                     NbBundle.getMessage(
this.getClass(), 
"AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
 
  415             getComponent().setProgressBarTextAndColor(
 
  416                     NbBundle.getMessage(
this.getClass(), 
"AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
 
  420         boolean critErr = 
false;
 
  421         if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
 
  424         for (String err : errList) {
 
  426             addErrors(err, critErr);
 
  428         final Level level = critErr ? Level.SEVERE : Level.WARNING;
 
  432             for (String err : errList) {
 
  433                 Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(level, 
"DatasourceID: {0} Error Message: {1}", 
new Object[]{dataSourceId.toString(), err});
 
  437                 if (!contents.isEmpty()) {
 
  438                     Case.getCurrentCaseThrows().notifyDataSourceAdded(contents.get(0), dataSourceId);
 
  440                     Case.getCurrentCaseThrows().notifyFailedAddingDataSource(dataSourceId);
 
  442             } 
catch (NoCurrentCaseException ex) {
 
  443                 Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  449             newContents.addAll(contents);
 
void setIndeterminate(final boolean indeterminate)
void setProgressText(final String text)
void setProgressMax(final int max)
void setProgress(final int progress)