From dec241a2782c4815ecb4016ffef05dbea8b4ae29 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 17 Jul 2015 09:15:27 -0400 Subject: [PATCH] Move case opening and closing off the EDT --- .../sleuthkit/autopsy/casemodule/Case.java | 59 +++++++----- .../autopsy/casemodule/CaseCloseAction.java | 23 ++++- .../autopsy/casemodule/CaseOpenAction.java | 56 +++++++++++- .../casemodule/NewCaseWizardAction.java | 87 +++++++++++++++++- .../casemodule/NewCaseWizardPanel2.java | 7 +- .../casemodule/OpenRecentCasePanel.java | 89 +++++++++++++------ .../autopsy/casemodule/RecentItems.java | 44 ++++++++- .../autopsy/corecomponents/Installer.java | 49 +++++++--- 8 files changed, 342 insertions(+), 72 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 1ac03b2859..4bb658d222 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -44,6 +44,7 @@ import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.SystemAction; @@ -523,20 +524,24 @@ public class Case { String dbPath = caseDir + File.separator + "autopsy.db"; //NON-NLS db = SleuthkitCase.openCase(dbPath); if (null != db.getBackupDatabasePath()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", - db.getBackupDatabasePath()), - NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"), - JOptionPane.INFORMATION_MESSAGE); + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", + db.getBackupDatabasePath()), + NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"), + JOptionPane.INFORMATION_MESSAGE); + }); } } else { db = SleuthkitCase.openCase(xmlcm.getDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), caseDir); if (null != db.getBackupDatabasePath()) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", - db.getBackupDatabasePath()), - NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"), - JOptionPane.INFORMATION_MESSAGE); + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", + db.getBackupDatabasePath()), + NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"), + JOptionPane.INFORMATION_MESSAGE); + }); } } @@ -786,7 +791,9 @@ public class Case { name = newCaseName; // change the local value RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath); // update the recent case eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldCaseName, newCaseName)); - updateMainWindowTitle(newCaseName); + SwingUtilities.invokeLater(() -> { + updateMainWindowTitle(newCaseName); + }); } catch (Exception e) { throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseName.exception.msg"), e); } @@ -1474,25 +1481,35 @@ public class Case { if (toChangeTo.hasData()) { // open all top components - CoreComponentControl.openCoreWindows(); + SwingUtilities.invokeLater(() -> { + CoreComponentControl.openCoreWindows(); + }); } else { // close all top components - CoreComponentControl.closeCoreWindows(); + SwingUtilities.invokeLater(() -> { + CoreComponentControl.closeCoreWindows(); + }); } } if (IngestManager.getInstance().isRunningInteractively()) { - updateMainWindowTitle(currentCase.name); + SwingUtilities.invokeLater(() -> { + updateMainWindowTitle(currentCase.name); + }); } else { - Frame f = WindowManager.getDefault().getMainWindow(); - f.setTitle(Case.getAppName()); // set the window name to just application name + SwingUtilities.invokeLater(() -> { + Frame f = WindowManager.getDefault().getMainWindow(); + f.setTitle(Case.getAppName()); // set the window name to just application name + }); } } else { // case is closed if (IngestManager.getInstance().isRunningInteractively()) { // close all top components first - CoreComponentControl.closeCoreWindows(); - + SwingUtilities.invokeLater(() -> { + CoreComponentControl.closeCoreWindows(); + }); + // disable these menus CallableSystemAction.get(AddImageAction.class).setEnabled(false); // Add Image menu CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu @@ -1503,8 +1520,10 @@ public class Case { //clear pending notifications MessageNotifyUtil.Notify.clear(); - Frame f = WindowManager.getDefault().getMainWindow(); - f.setTitle(Case.getAppName()); // set the window name to just application name + SwingUtilities.invokeLater(() -> { + Frame f = WindowManager.getDefault().getMainWindow(); + f.setTitle(Case.getAppName()); // set the window name to just application name + }); //try to force gc to happen System.gc(); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java index ad0b4cc952..efb5a5ca27 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java @@ -27,6 +27,7 @@ import java.util.logging.Level;import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.SwingWorker; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; @@ -70,6 +71,26 @@ import org.openide.util.actions.Presenter; return; } + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + try{ + Case result = Case.getCurrentCase(); + result.closeCase(); + } catch (CaseActionException | IllegalStateException ex){ + Logger.getLogger(CaseCloseAction.class.getName()).log(Level.SEVERE, "Error closing case.", ex); //NON-NLS + } + return null; + } + + @Override + protected void done() { + StartupWindowProvider.getInstance().open(); + } + }.execute(); + + /* Case result = Case.getCurrentCase(); try { result.closeCase(); @@ -82,7 +103,7 @@ import org.openide.util.actions.Presenter; public void run() { StartupWindowProvider.getInstance().open(); } - }); + });*/ } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java index f767efcf09..fc70b02d7e 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java @@ -23,9 +23,12 @@ import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JFileChooser; import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; import org.openide.util.NbBundle; @@ -76,7 +79,7 @@ public final class CaseOpenAction implements ActionListener { int retval = fc.showOpenDialog(WindowManager.getDefault().getMainWindow()); if (retval == JFileChooser.APPROVE_OPTION) { - String path = fc.getSelectedFile().getPath(); + final String path = fc.getSelectedFile().getPath(); String dirPath = fc.getSelectedFile().getParent(); ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator))); // check if the file exists @@ -96,6 +99,55 @@ public final class CaseOpenAction implements ActionListener { // no need to show the error message to the user. logger.log(Level.WARNING, "Error closing startup window.", ex); //NON-NLS } + + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + // Create case. + try{ + Case.open(path); + } catch (CaseActionException ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.msg", path, + ex.getMessage()), + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + + + StartupWindowProvider.getInstance().open(); + }); + logger.log(Level.WARNING, "Error opening case in folder " + path, ex); //NON-NLS + } + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (ExecutionException | InterruptedException ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.msg", path, + ex.getMessage()), + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + + + StartupWindowProvider.getInstance().open(); + }); + logger.log(Level.WARNING, "Error opening case in folder " + path, ex); //NON-NLS + } + } + }.execute(); + + /* try { Case.open(path); // open the case } catch (CaseActionException ex) { @@ -109,7 +161,7 @@ public final class CaseOpenAction implements ActionListener { logger.log(Level.WARNING, "Error opening case in folder " + path, ex); //NON-NLS StartupWindowProvider.getInstance().open(); - } + }*/ } } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java index bc9cdea275..a6c9335da3 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java @@ -24,7 +24,10 @@ import java.awt.Dialog; import java.io.File; import java.text.MessageFormat; import java.util.logging.Level; +import java.util.concurrent.ExecutionException; import javax.swing.JComponent; +import javax.swing.SwingWorker; +import javax.swing.SwingUtilities; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; @@ -81,7 +84,7 @@ import org.sleuthkit.datamodel.TskData.DbType; * The method to perform new case creation */ private void newCaseAction() { - WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels()); + final WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels()); // {0} will be replaced by WizardDesriptor.Panel.getComponent().getName() wizardDescriptor.setTitleFormat(new MessageFormat("{0}")); wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text")); @@ -89,7 +92,73 @@ import org.sleuthkit.datamodel.TskData.DbType; dialog.setVisible(true); dialog.toFront(); + if(wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION){ + new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + // Create case. + + String caseNumber = (String) wizardDescriptor.getProperty("caseNumber"); //NON-NLS + String examiner = (String) wizardDescriptor.getProperty("caseExaminer"); //NON-NLS + final String caseName = (String) wizardDescriptor.getProperty("caseName"); //NON-NLS + String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS + CaseType caseType = CaseType.values()[(int)wizardDescriptor.getProperty("caseType")]; //NON-NLS + + try { + Case.create(createdDirectory, caseName, caseNumber, examiner, caseType); + } catch (Exception ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), + "CaseCreateAction.msgDlg.cantCreateCase.msg")+" "+caseName, + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + }); + } + return null; + } + + @Override + protected void done() { + try { + get(); + CaseType currentCaseType = CaseType.values()[(int)wizardDescriptor.getProperty("caseType")]; //NON-NLS + CaseDbConnectionInfo info = UserPreferences.getDatabaseConnectionInfo(); + if ((currentCaseType==CaseType.SINGLE_USER_CASE) || ((info.getDbType() != DbType.SQLITE) && info.canConnect())) { + AddImageAction addImageAction = SystemAction.get(AddImageAction.class); + addImageAction.actionPerformed(null); + } else { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.databaseProblem1.text"), + NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.databaseProblem2.text"), + JOptionPane.ERROR_MESSAGE); + doFailedCaseCleanup(wizardDescriptor); + } + + + } catch (ExecutionException | InterruptedException ex) { + final String caseName = (String) wizardDescriptor.getProperty("caseName"); //NON-NLS + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), + "CaseCreateAction.msgDlg.cantCreateCase.msg")+" "+caseName, + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + }); + doFailedCaseCleanup(wizardDescriptor); + } + } + }.execute(); + + + } else { + new Thread(() -> { + doFailedCaseCleanup(wizardDescriptor); + }).start(); + } + + /* boolean finished = wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION; // check if it finishes (it's not cancelled) boolean isCancelled = wizardDescriptor.getValue() == WizardDescriptor.CANCEL_OPTION; // check if the "Cancel" button is pressed @@ -125,8 +194,22 @@ import org.sleuthkit.datamodel.TskData.DbType; Case.deleteCaseDirectory(new File(createdDirectory)); } } - panels = null; // reset the panel + panels = null; // reset the panel*/ } + + private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor){ + String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS + // if there's case opened, close the case + if (Case.existsCurrentCase()) { + // close the previous case if there's any + CaseCloseAction closeCase = SystemAction.get(CaseCloseAction.class); + closeCase.actionPerformed(null); + } + if (createdDirectory != null) { + logger.log(Level.INFO, "Deleting a created case directory due to isCancelled set, dir: " + createdDirectory); //NON-NLS + Case.deleteCaseDirectory(new File(createdDirectory)); + } + } /** * Initialize panels representing individual wizard's steps and sets diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java index 98a972a5af..30a96650f6 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java @@ -171,11 +171,14 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel() { + + @Override + protected Void doInBackground() throws Exception { + // Create case. + try{ + Case.open(casePath); + } catch (CaseActionException ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.msg", caseName, + ex.getMessage()), + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + }); + logger.log(Level.WARNING, "Error: couldn't open case: " + caseName, ex); //NON-NLS + } + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (ExecutionException | InterruptedException ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.msg", caseName, + ex.getMessage()), + NbBundle.getMessage(this.getClass(), + "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + }); + logger.log(Level.WARNING, "Error: couldn't open case: " + caseName, ex); //NON-NLS + } + } + }.execute(); } } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java b/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java index 43de7bbb7f..43ed9cf134 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java @@ -23,9 +23,12 @@ import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; @@ -35,8 +38,8 @@ import org.sleuthkit.autopsy.coreutils.Logger; */ class RecentItems implements ActionListener { - String caseName; - String casePath; + final String caseName; + final String casePath; private JPanel caller; // for error handling /** the constructor */ @@ -76,6 +79,41 @@ class RecentItems implements ActionListener { } } else { + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + // Create case. + try{ + Case.open(casePath); + } catch (CaseActionException ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.msg", casePath, + ex.getMessage()), NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + }); + Logger.getLogger(RecentItems.class.getName()).log(Level.WARNING, "Error: Couldn't open recent case at " + casePath, ex); //NON-NLS + } + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (ExecutionException | InterruptedException ex) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.msg", casePath, + ex.getMessage()), NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), + JOptionPane.ERROR_MESSAGE); + }); + Logger.getLogger(RecentItems.class.getName()).log(Level.WARNING, "Error opening recent case. ", ex); //NON-NLS + } + } + }.execute(); + /* try { Case.open(casePath); // open the case } catch (CaseActionException ex) { @@ -84,7 +122,7 @@ class RecentItems implements ActionListener { ex.getMessage()), NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), JOptionPane.ERROR_MESSAGE); Logger.getLogger(RecentItems.class.getName()).log(Level.WARNING, "Error: Couldn't open recent case at " + casePath, ex); //NON-NLS - } + }*/ } } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Installer.java b/Core/src/org/sleuthkit/autopsy/corecomponents/Installer.java index d38e58525e..95c7422f28 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Installer.java @@ -24,10 +24,12 @@ import java.util.Collection; import java.util.Map; import java.util.TreeMap; import java.util.logging.Level; +import java.util.concurrent.ExecutionException; import javax.swing.BorderFactory; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.SwingWorker; import org.netbeans.spi.sendopts.OptionProcessor; import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI; import org.openide.modules.ModuleInstall; @@ -74,13 +76,32 @@ public class Installer extends ModuleInstall { for (OptionProcessor processor : processors) { if (processor instanceof OpenFromArguments) { OpenFromArguments argsProcessor = (OpenFromArguments) processor; - String caseFile = argsProcessor.getDefaultArg(); + final String caseFile = argsProcessor.getDefaultArg(); if (caseFile != null && !caseFile.equals("") && caseFile.endsWith(".aut") && new File(caseFile).exists()) { //NON-NLS - try { - Case.open(caseFile); - return; - } catch (Exception e) { - } + + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + // Create case. + try{ + Case.open(caseFile); + } catch(Exception ex){ + logger.log(Level.WARNING, "Error opening case. ", ex); //NON-NLS + } + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (ExecutionException | InterruptedException ex) { + logger.log(Level.WARNING, "Error opening case. ", ex); //NON-NLS + } + } + }.execute(); + return; } } } @@ -99,13 +120,15 @@ public class Installer extends ModuleInstall { @Override public void close() { - try { - if (Case.isCaseOpen()) - Case.getCurrentCase().closeCase(); - } - catch (CaseActionException ex) { - logger.log(Level.WARNING, "Error closing case. ", ex); //NON-NLS - } + new Thread(() -> { + try { + if (Case.isCaseOpen()) + Case.getCurrentCase().closeCase(); + } + catch (CaseActionException | IllegalStateException ex) { + logger.log(Level.WARNING, "Error closing case. ", ex); //NON-NLS + } + }).start(); } private void setupLAF() {