From 19f4bec0c03b06184820acf121d888147912ce77 Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 14 Aug 2015 16:15:58 -0400 Subject: [PATCH 01/22] menu shows up! (twice) --- Core/src/org/sleuthkit/autopsy/core/layer.xml | 7 ++ .../autopsy/ingest/Bundle.properties | 1 + .../autopsy/ingest/RunIngestAction.java | 73 +++++++++++++++++++ .../autopsy/ingest/UpdateIngestImages.java | 66 +++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java create mode 100755 Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 2f36280e7a..8ad4410fb4 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -203,6 +203,13 @@ + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties index a30199c86c..3c02595872 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties @@ -1,4 +1,5 @@ OpenIDE-Module-Name=Ingest +Menu/Tools/RunIngestModules=Run Ingest Modules CTL_IngestMessageTopComponent=Messages HINT_IngestMessageTopComponent=Messages windows IngestMessageDetailsPanel.backButton.text= diff --git a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java new file mode 100755 index 0000000000..c820d89c28 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java @@ -0,0 +1,73 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.ingest; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JMenuItem; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionRegistration; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; +import org.openide.util.actions.CallableSystemAction; +import org.openide.util.actions.Presenter; + +@ActionID( + category = "Tools", + id = "org.sleuthkit.autopsy.ingest.RunIngestAction" +) +@ActionRegistration( + displayName = "#CTL_RunIngestAction" +) +@ActionReference(path = "Menu/Tools", position = 750) +@Messages("CTL_RunIngestAction=Run Ingest") +public final class RunIngestAction extends CallableSystemAction implements Presenter.Menu, ActionListener { + + static public RunIngestAction getInstance() { + return new RunIngestAction(); + } + + /** + * This method does nothing. Use the actionPerformed instead of this method. + */ + @Override + public void performAction() { + getMenuPresenter(); + } + + /** + * Gets the name of this action. This may be presented as an item in a menu. + * + * @return actionName + */ + @Override + public String getName() { + return NbBundle.getMessage(RunIngestAction.class, "RunIngestModulesMenu.getName.text"); + } + + /** + * Gets the HelpCtx associated with implementing object + * + * @return HelpCtx or HelpCtx.DEFAULT_HELP + */ + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + public JMenuItem getMenuPresenter() { + JMenuItem sublist = new UpdateIngestImages(); + sublist.setVisible(true); + return sublist; + } + + @Override + public void actionPerformed(ActionEvent e) { + } +} diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java new file mode 100755 index 0000000000..536fe39ccf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java @@ -0,0 +1,66 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.ingest; + +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JSeparator; +import org.openide.awt.DynamicMenuContent; + +/** + * This class is used to change / update the list of open images for ingest modules + * dynamically. + */ +class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { + + @Override + public JComponent[] getMenuPresenters() { + int length = 2; + JComponent[] comps = new JComponent[length + 2]; // + 2 for separator and clear menu + + // if it has the recent menus, add them to the component list + for (int i = 0; i < length; i++) { + String action = "action " + i; + JMenuItem menuItem = new JMenuItem(action); + menuItem.setActionCommand(action.toUpperCase()); + comps[i] = menuItem; + } + + // if it has recent case, create clear menu + if (true) { + comps[length] = new JSeparator(); + JMenuItem clearMenu = new JMenuItem("unclear"); + comps[length + 1] = clearMenu; + } // otherwise, just create a disabled empty menu + else { + comps = new JComponent[1]; + JMenuItem emptyMenu = new JMenuItem("unempty"); + comps[0] = emptyMenu; + comps[0].setEnabled(false); + } + return comps; + } + + @Override + public JComponent[] synchMenuPresenters(JComponent[] jcs) { + return getMenuPresenters(); + } + + +} From 660763b19da30a022b8bb3d9724737f077692abd Mon Sep 17 00:00:00 2001 From: momo Date: Mon, 17 Aug 2015 10:27:08 -0400 Subject: [PATCH 02/22] list populated correctly --- Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java | 1 - Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java index c820d89c28..588892aae4 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java @@ -24,7 +24,6 @@ import org.openide.util.actions.Presenter; @ActionRegistration( displayName = "#CTL_RunIngestAction" ) -@ActionReference(path = "Menu/Tools", position = 750) @Messages("CTL_RunIngestAction=Run Ingest") public final class RunIngestAction extends CallableSystemAction implements Presenter.Menu, ActionListener { diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java index 536fe39ccf..f54cbf7168 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java @@ -24,8 +24,7 @@ import javax.swing.JSeparator; import org.openide.awt.DynamicMenuContent; /** - * This class is used to change / update the list of open images for ingest modules - * dynamically. + * This class is used to populate the list of open images to run ingest on them */ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { From eb2cb472cac43fa486422c8efed467be012892df Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 21 Aug 2015 12:01:42 -0400 Subject: [PATCH 03/22] listing open images --- .../autopsy/ingest/UpdateIngestImages.java | 48 ++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java index f54cbf7168..0ff835030f 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java @@ -18,10 +18,16 @@ */ package org.sleuthkit.autopsy.ingest; +import java.util.ArrayList; +import java.util.List; import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JSeparator; import org.openide.awt.DynamicMenuContent; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; /** * This class is used to populate the list of open images to run ingest on them @@ -30,29 +36,39 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { @Override public JComponent[] getMenuPresenters() { - int length = 2; - JComponent[] comps = new JComponent[length + 2]; // + 2 for separator and clear menu + List images = new ArrayList<>(); + JComponent[] comps = new JComponent[1]; + SleuthkitCase sk = null; + try { + sk = Case.getCurrentCase().getSleuthkitCase(); + } catch (IllegalStateException ex) { + // create a disabled empty menu + comps = new JComponent[1]; + JMenuItem emptyMenu = new JMenuItem("unempty"); + comps[0] = emptyMenu; + comps[0].setEnabled(false); + return comps; + } + try { + images = sk.getImages(); + } catch (TskCoreException e) { + System.out.println("Exception getting images: " + e.getMessage()); + } + comps = new JComponent[images.size()]; // + 2 for separator and clear menu // if it has the recent menus, add them to the component list - for (int i = 0; i < length; i++) { - String action = "action " + i; + for (int i = 0; i < images.size(); i++) { + String action = images.get(i).getName(); JMenuItem menuItem = new JMenuItem(action); menuItem.setActionCommand(action.toUpperCase()); comps[i] = menuItem; } - // if it has recent case, create clear menu - if (true) { - comps[length] = new JSeparator(); - JMenuItem clearMenu = new JMenuItem("unclear"); - comps[length + 1] = clearMenu; - } // otherwise, just create a disabled empty menu - else { - comps = new JComponent[1]; - JMenuItem emptyMenu = new JMenuItem("unempty"); - comps[0] = emptyMenu; - comps[0].setEnabled(false); - } +// if (true) { +// comps[images.size()] = new JSeparator(); +// JMenuItem clearMenu = new JMenuItem("unclear"); +// comps[images.size() + 1] = clearMenu; +// } return comps; } From 54f8b4124f397238eeca7937bc29ca87c379c32a Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 21 Aug 2015 12:05:38 -0400 Subject: [PATCH 04/22] added action to images --- .../autopsy/ingest/MenuImageAction.java | 54 +++++++++++++++++++ .../autopsy/ingest/UpdateIngestImages.java | 1 + 2 files changed, 55 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java diff --git a/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java b/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java new file mode 100755 index 0000000000..0b51c37ddf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java @@ -0,0 +1,54 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2014 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.ingest; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Collections; +import javax.swing.JPanel; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.Image; + +/** + * This class is used to add the action to the recent case menu item. When the + * the recent case menu is pressed, it should open that selected case. + */ +class MenuImageAction implements ActionListener { + + Image image; + private JPanel caller; // for error handling + + /** + * the constructor + */ + public MenuImageAction(Image image) { + this.image = image; + } + + /** + * Opens the recent case. + * + * @param e the action event + */ + @Override + public void actionPerformed(ActionEvent e) { + final RunIngestModulesDialog ingestDialog = new RunIngestModulesDialog(Collections.singletonList(image)); + ingestDialog.display(); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java index 0ff835030f..e226c5c0b4 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java @@ -61,6 +61,7 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { String action = images.get(i).getName(); JMenuItem menuItem = new JMenuItem(action); menuItem.setActionCommand(action.toUpperCase()); + menuItem.addActionListener(new MenuImageAction(images.get(i))); comps[i] = menuItem; } From 95c34e1fa8e1d3a42e3e6eb81550debfddbb909f Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 21 Aug 2015 12:28:44 -0400 Subject: [PATCH 05/22] comments and cleanup --- .../autopsy/casemodule/UpdateRecentCases.java | 2 +- .../autopsy/ingest/Bundle.properties | 1 + .../autopsy/ingest/MenuImageAction.java | 8 +-- .../autopsy/ingest/RunIngestAction.java | 31 +++++++++-- .../autopsy/ingest/UpdateIngestImages.java | 55 +++++++++++++------ 5 files changed, 68 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java b/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java index 147337965b..1a6c65022c 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java @@ -60,7 +60,7 @@ class UpdateRecentCases extends JMenuItem implements DynamicMenuContent { menuItem.setActionCommand(caseName[i].toUpperCase()); menuItem.addActionListener(new RecentItems(caseName[i], casePath[i])); comps[i] = menuItem; - hasRecentCase = hasRecentCase || true; + hasRecentCase = true; } } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties index 3c02595872..8e966f1326 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties @@ -100,3 +100,4 @@ IngestJobTableModel.colName.rootQueued=Root Queued IngestJobTableModel.colName.dsQueued=DS Queued ModuleTableModel.colName.module=Module ModuleTableModel.colName.duration=Duration +UpdateIngestImages.menuItem.empty=-Empty- diff --git a/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java b/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java index 0b51c37ddf..bdcb1dd2d4 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java @@ -21,18 +21,16 @@ package org.sleuthkit.autopsy.ingest; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collections; -import javax.swing.JPanel; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; /** - * This class is used to add the action to the recent case menu item. When the - * the recent case menu is pressed, it should open that selected case. + * This class is used to add the action to the run ingest modules menu item. + * When the image is pressed, it should open the wizard for ingest modules. */ class MenuImageAction implements ActionListener { Image image; - private JPanel caller; // for error handling /** * the constructor @@ -42,7 +40,7 @@ class MenuImageAction implements ActionListener { } /** - * Opens the recent case. + * Runs the ingest modules wizard on the image. * * @param e the action event */ diff --git a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java index 588892aae4..e703de0704 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.ingest; @@ -9,7 +22,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JMenuItem; import org.openide.awt.ActionID; -import org.openide.awt.ActionReference; import org.openide.awt.ActionRegistration; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; @@ -32,7 +44,7 @@ public final class RunIngestAction extends CallableSystemAction implements Prese } /** - * This method does nothing. Use the actionPerformed instead of this method. + * Call getMenuPresenters to create images sublist */ @Override public void performAction() { @@ -59,6 +71,12 @@ public final class RunIngestAction extends CallableSystemAction implements Prese return HelpCtx.DEFAULT_HELP; } + /** + * Create a sublist of images updated by UpdateIngestImages + * Each has an action to perform Ingest Modules on it. + * + * @return the images sublist created. + */ @Override public JMenuItem getMenuPresenter() { JMenuItem sublist = new UpdateIngestImages(); @@ -66,6 +84,9 @@ public final class RunIngestAction extends CallableSystemAction implements Prese return sublist; } + /** + * This method does nothing, use performAction instead. + */ @Override public void actionPerformed(ActionEvent e) { } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java index e226c5c0b4..e520d8b1cc 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java @@ -22,8 +22,8 @@ import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; import javax.swing.JMenuItem; -import javax.swing.JSeparator; import org.openide.awt.DynamicMenuContent; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.SleuthkitCase; @@ -33,46 +33,65 @@ import org.sleuthkit.datamodel.TskCoreException; * This class is used to populate the list of open images to run ingest on them */ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { - - @Override + + static boolean hasImages = false; + + /** + * Creates main menu/popup menu items. It's called each time a popup menu + * is constructed and just once for the main menu. + * Main menu updates happen through the synchMenuPresenters() method. + * + * @return + */ + @Override public JComponent[] getMenuPresenters() { List images = new ArrayList<>(); JComponent[] comps = new JComponent[1]; - SleuthkitCase sk = null; + try { - sk = Case.getCurrentCase().getSleuthkitCase(); + SleuthkitCase sk = Case.getCurrentCase().getSleuthkitCase(); + images = sk.getImages(); } catch (IllegalStateException ex) { - // create a disabled empty menu + // No open Cases, create a disabled empty menu comps = new JComponent[1]; - JMenuItem emptyMenu = new JMenuItem("unempty"); + JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(UpdateIngestImages.class, "UpdateIngestImages.menuItem.empty")); comps[0] = emptyMenu; comps[0].setEnabled(false); return comps; - } - try { - images = sk.getImages(); } catch (TskCoreException e) { System.out.println("Exception getting images: " + e.getMessage()); } - comps = new JComponent[images.size()]; // + 2 for separator and clear menu + comps = new JComponent[images.size()]; - // if it has the recent menus, add them to the component list + // Add Images to the component list for (int i = 0; i < images.size(); i++) { String action = images.get(i).getName(); JMenuItem menuItem = new JMenuItem(action); menuItem.setActionCommand(action.toUpperCase()); menuItem.addActionListener(new MenuImageAction(images.get(i))); comps[i] = menuItem; + hasImages = true; + } + // If no images are open, create a disabled empty menu + if (!hasImages) { + comps = new JComponent[1]; + JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(UpdateIngestImages.class, "UpdateIngestImages.menuItem.empty")); + comps[0] = emptyMenu; + comps[0].setEnabled(false); } - -// if (true) { -// comps[images.size()] = new JSeparator(); -// JMenuItem clearMenu = new JMenuItem("unclear"); -// comps[images.size() + 1] = clearMenu; -// } return comps; } + /** + * Updates main menu presenters. This method is called only by the main menu + * processing. + * + * @param jcs the previously used menu items returned by previous call to + * getMenuPresenters() or synchMenuPresenters() + * + * @return menu a new set of items to show in menu. Can be either an updated + * old set of instances or a completely new one. + */ @Override public JComponent[] synchMenuPresenters(JComponent[] jcs) { return getMenuPresenters(); From 8cc9a1a1535328bc298a75709f2e674dca0b2c6a Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 21 Aug 2015 14:46:34 -0400 Subject: [PATCH 06/22] refactor empty to new method --- .../autopsy/ingest/UpdateIngestImages.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java index e520d8b1cc..a21922ccfd 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java @@ -33,9 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; * This class is used to populate the list of open images to run ingest on them */ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { - - static boolean hasImages = false; - + /** * Creates main menu/popup menu items. It's called each time a popup menu * is constructed and just once for the main menu. @@ -53,11 +51,7 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { images = sk.getImages(); } catch (IllegalStateException ex) { // No open Cases, create a disabled empty menu - comps = new JComponent[1]; - JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(UpdateIngestImages.class, "UpdateIngestImages.menuItem.empty")); - comps[0] = emptyMenu; - comps[0].setEnabled(false); - return comps; + return getEmpty(); } catch (TskCoreException e) { System.out.println("Exception getting images: " + e.getMessage()); } @@ -70,17 +64,22 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { menuItem.setActionCommand(action.toUpperCase()); menuItem.addActionListener(new MenuImageAction(images.get(i))); comps[i] = menuItem; - hasImages = true; } // If no images are open, create a disabled empty menu - if (!hasImages) { - comps = new JComponent[1]; - JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(UpdateIngestImages.class, "UpdateIngestImages.menuItem.empty")); - comps[0] = emptyMenu; - comps[0].setEnabled(false); + if (images.isEmpty()) { + return getEmpty(); } return comps; } + + // returns a disabled empty menu + private JComponent[] getEmpty() { + JComponent[] comps = new JComponent[1]; + JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(UpdateIngestImages.class, "UpdateIngestImages.menuItem.empty")); + comps[0] = emptyMenu; + comps[0].setEnabled(false); + return comps; + } /** * Updates main menu presenters. This method is called only by the main menu From a89183f8634acded7821899a50d5d17dc541b47a Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 10 Sep 2015 11:27:52 -0400 Subject: [PATCH 07/22] catching and ignoring report modules with null or empty names --- .../autopsy/report/Bundle.properties | 1 + .../autopsy/report/ReportVisualPanel1.java | 57 ++++++++++++++++--- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties index c7f862b1fc..38a3ede765 100644 --- a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties @@ -3,6 +3,7 @@ CTL_ReportWizardAction=Run Report ArtifactSelectionDialog.titleLabel.text=Select which artifacts you would like to report on: ArtifactSelectionDialog.okButton.text=OK ReportVisualPanel1.reportModulesLabel.text=Report Modules: +ReportVisualPanel1.initModules.invalidWarning=Encountered an invalid Report Module DefaultReportConfigurationPanel.infoLabel.text=This report will be configured on the next screen. ReportVisualPanel2.dataLabel.text=Select which data to report on: ReportVisualPanel2.deselectAllButton.text=Deselect All diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index acd49f029e..ea300ba101 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -27,6 +27,7 @@ import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JRadioButton; @@ -34,8 +35,11 @@ import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.actions.OpenPythonModulesFolderAction; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.python.JythonModuleLoader; import org.sleuthkit.autopsy.report.ReportHTML; @@ -64,23 +68,55 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { // Initialize the list of ReportModules private void initModules() { for (TableReportModule module : Lookup.getDefault().lookupAll(TableReportModule.class)) { - tableModules.add(module); - modules.add(module); + if(validModule(module)) { + tableModules.add(module); + modules.add(module); + } else { + // log + logger.log(Level.WARNING, "Invalid TableReportModule"); // NON_NLS + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( + NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), + NotifyDescriptor.ERROR_MESSAGE)); + } } for (GeneralReportModule module : Lookup.getDefault().lookupAll(GeneralReportModule.class)) { - generalModules.add(module); - modules.add(module); + if(validModule(module)) { + generalModules.add(module); + modules.add(module); + } else { + // log + logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( + NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), + NotifyDescriptor.ERROR_MESSAGE)); + } } for (GeneralReportModule module : JythonModuleLoader.getGeneralReportModules()) { - generalModules.add(module); - modules.add(module); + if(validModule(module)) { + generalModules.add(module); + modules.add(module); + } else { + //log + logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( + NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), + NotifyDescriptor.ERROR_MESSAGE)); + } } for (FileReportModule module : Lookup.getDefault().lookupAll(FileReportModule.class)) { - fileModules.add(module); - modules.add(module); + if(validModule(module)) { + fileModules.add(module); + modules.add(module); + } else { + //log + logger.log(Level.WARNING, "Invalid FileReportModule"); // NON_NLS + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( + NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), + NotifyDescriptor.ERROR_MESSAGE)); + } } Collections.sort(modules, new Comparator() { @@ -116,6 +152,11 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { selectedIndex = 0; modulesJList.setSelectedIndex(selectedIndex); } + + // Make sure that the report module has a valid non-null name. + private boolean validModule(ReportModule module) { + return module != null && module.getName() != null && !module.getName().isEmpty(); + } @Override public String getName() { From 4f45e5c0ff574e33194f60ff0d1d1c7ae7c20d77 Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 10 Sep 2015 12:36:17 -0400 Subject: [PATCH 08/22] use friendly warning message instead of error popup --- .../autopsy/report/Bundle.properties | 3 +- .../autopsy/report/ReportVisualPanel1.java | 51 ++++++++----------- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties index 38a3ede765..586eeb598d 100644 --- a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties @@ -3,7 +3,8 @@ CTL_ReportWizardAction=Run Report ArtifactSelectionDialog.titleLabel.text=Select which artifacts you would like to report on: ArtifactSelectionDialog.okButton.text=OK ReportVisualPanel1.reportModulesLabel.text=Report Modules: -ReportVisualPanel1.initModules.invalidWarning=Encountered an invalid Report Module +ReportVisualPanel1.invalidModuleWarning=Encountered an invalid Report Module +ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule=Report Module will not be displayed. DefaultReportConfigurationPanel.infoLabel.text=This report will be configured on the next screen. ReportVisualPanel2.dataLabel.text=Select which data to report on: ReportVisualPanel2.deselectAllButton.text=Deselect All diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index ea300ba101..62bce66cb2 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -35,18 +35,17 @@ import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import org.openide.DialogDisplayer; -import org.openide.NotifyDescriptor; import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.actions.OpenPythonModulesFolderAction; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.ingest.IngestMessage; +import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.python.JythonModuleLoader; -import org.sleuthkit.autopsy.report.ReportHTML; final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { private static final Logger logger = Logger.getLogger(ReportVisualPanel1.class.getName()); + private final IngestServices services = IngestServices.getInstance(); private ReportWizardPanel1 wizPanel; private List modules = new ArrayList<>(); private List generalModules = new ArrayList<>(); @@ -68,54 +67,38 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { // Initialize the list of ReportModules private void initModules() { for (TableReportModule module : Lookup.getDefault().lookupAll(TableReportModule.class)) { - if(validModule(module)) { + if (validModule(module)) { tableModules.add(module); modules.add(module); } else { - // log - logger.log(Level.WARNING, "Invalid TableReportModule"); // NON_NLS - DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( - NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), - NotifyDescriptor.ERROR_MESSAGE)); + postWarningMessage(module); } } for (GeneralReportModule module : Lookup.getDefault().lookupAll(GeneralReportModule.class)) { - if(validModule(module)) { + if (validModule(module)) { generalModules.add(module); modules.add(module); } else { - // log - logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS - DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( - NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), - NotifyDescriptor.ERROR_MESSAGE)); + postWarningMessage(module); } } for (GeneralReportModule module : JythonModuleLoader.getGeneralReportModules()) { - if(validModule(module)) { + if (validModule(module)) { generalModules.add(module); modules.add(module); } else { - //log - logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS - DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( - NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), - NotifyDescriptor.ERROR_MESSAGE)); + postWarningMessage(module); } } for (FileReportModule module : Lookup.getDefault().lookupAll(FileReportModule.class)) { - if(validModule(module)) { + if (validModule(module)) { fileModules.add(module); modules.add(module); } else { - //log - logger.log(Level.WARNING, "Invalid FileReportModule"); // NON_NLS - DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( - NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.initModules.invalidWarning", module), - NotifyDescriptor.ERROR_MESSAGE)); + postWarningMessage(module); } } @@ -152,12 +135,22 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { selectedIndex = 0; modulesJList.setSelectedIndex(selectedIndex); } - + // Make sure that the report module has a valid non-null name. private boolean validModule(ReportModule module) { return module != null && module.getName() != null && !module.getName().isEmpty(); } + private void postWarningMessage(ReportModule module) { + logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS + services.postMessage(IngestMessage.createWarningMessage( + (module != null) ? module.getClass().getSimpleName() : "null", // NON_NLS + NbBundle.getMessage(this.getClass(), + "ReportVisualPanel1.invalidModuleWarning"), + NbBundle.getMessage(this.getClass(), + "ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule"))); + } + @Override public String getName() { return NbBundle.getMessage(this.getClass(), "ReportVisualPanel1.getName.text"); From e67ee808d43018cf6ca7d23aabbc8127489a1fc4 Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 10 Sep 2015 12:53:47 -0400 Subject: [PATCH 09/22] adding class name to displayed message --- Core/src/org/sleuthkit/autopsy/report/Bundle.properties | 2 +- .../src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties index 586eeb598d..804e9b5466 100644 --- a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties @@ -4,7 +4,7 @@ ArtifactSelectionDialog.titleLabel.text=Select which artifacts you would like to ArtifactSelectionDialog.okButton.text=OK ReportVisualPanel1.reportModulesLabel.text=Report Modules: ReportVisualPanel1.invalidModuleWarning=Encountered an invalid Report Module -ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule=Report Module will not be displayed. +ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule=({0}) Report Module will not be displayed. DefaultReportConfigurationPanel.infoLabel.text=This report will be configured on the next screen. ReportVisualPanel2.dataLabel.text=Select which data to report on: ReportVisualPanel2.deselectAllButton.text=Deselect All diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 62bce66cb2..3b274025b1 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -142,13 +142,14 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { } private void postWarningMessage(ReportModule module) { + String moduleClassName = (module != null) ? module.getClass().getSimpleName() : "null"; // NON_NLS logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS services.postMessage(IngestMessage.createWarningMessage( - (module != null) ? module.getClass().getSimpleName() : "null", // NON_NLS + moduleClassName, NbBundle.getMessage(this.getClass(), "ReportVisualPanel1.invalidModuleWarning"), NbBundle.getMessage(this.getClass(), - "ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule"))); + "ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule", moduleClassName))); } @Override From 7e8940391624d4614df976bece5af7f6457de26c Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 10 Sep 2015 13:23:24 -0400 Subject: [PATCH 10/22] generalized warning message --- Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 3b274025b1..2a5c05f44b 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -143,7 +143,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { private void postWarningMessage(ReportModule module) { String moduleClassName = (module != null) ? module.getClass().getSimpleName() : "null"; // NON_NLS - logger.log(Level.WARNING, "Invalid GeneralReportModule"); // NON_NLS + logger.log(Level.WARNING, "Invalid ReportModule"); // NON_NLS services.postMessage(IngestMessage.createWarningMessage( moduleClassName, NbBundle.getMessage(this.getClass(), From 2ac9225b1a8fd7b3fb4d7883d94c0c50eb6a0a96 Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 11 Sep 2015 13:27:37 -0400 Subject: [PATCH 11/22] change back to error popup for null values --- .../sleuthkit/autopsy/report/Bundle.properties | 3 +-- .../autopsy/report/ReportVisualPanel1.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties index 804e9b5466..5e74024afe 100644 --- a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties @@ -3,8 +3,7 @@ CTL_ReportWizardAction=Run Report ArtifactSelectionDialog.titleLabel.text=Select which artifacts you would like to report on: ArtifactSelectionDialog.okButton.text=OK ReportVisualPanel1.reportModulesLabel.text=Report Modules: -ReportVisualPanel1.invalidModuleWarning=Encountered an invalid Report Module -ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule=({0}) Report Module will not be displayed. +ReportVisualPanel1.invalidModuleWarning=Encountered an invalid Report Module ({0}) DefaultReportConfigurationPanel.infoLabel.text=This report will be configured on the next screen. ReportVisualPanel2.dataLabel.text=Select which data to report on: ReportVisualPanel2.deselectAllButton.text=Deselect All diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 2a5c05f44b..5c104478f9 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -35,6 +35,8 @@ import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; @@ -127,7 +129,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { } indexOfHTMLReportModule++; } - swap(modules, indexOfHTMLReportModule, 0); + //swap(modules, indexOfHTMLReportModule, 0); modulesJList.getSelectionModel().addListSelectionListener(this); modulesJList.setCellRenderer(new ModuleCellRenderer()); @@ -138,18 +140,15 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { // Make sure that the report module has a valid non-null name. private boolean validModule(ReportModule module) { - return module != null && module.getName() != null && !module.getName().isEmpty(); + return module != null && module.getName() != null && module.getRelativeFilePath() != null; } private void postWarningMessage(ReportModule module) { String moduleClassName = (module != null) ? module.getClass().getSimpleName() : "null"; // NON_NLS logger.log(Level.WARNING, "Invalid ReportModule"); // NON_NLS - services.postMessage(IngestMessage.createWarningMessage( - moduleClassName, - NbBundle.getMessage(this.getClass(), - "ReportVisualPanel1.invalidModuleWarning"), - NbBundle.getMessage(this.getClass(), - "ReportVisualPanel1.ReportVisualPanelWillNotDisplayModule", moduleClassName))); + DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( + NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.invalidModuleWarning", moduleClassName), + NotifyDescriptor.ERROR_MESSAGE)); } @Override From c63081edd77507d05f151da7cab6290037364ad3 Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 11 Sep 2015 13:29:03 -0400 Subject: [PATCH 12/22] Don't display file path if it's empty --- Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java index ccb22c3f55..f53d374f49 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java @@ -151,7 +151,7 @@ class ReportGenerator { if (entry.getValue()) { TableReportModule module = entry.getKey(); String reportFilePath = module.getRelativeFilePath(); - if (reportFilePath != null) { + if (!reportFilePath.isEmpty()) { tableProgress.put(module, panel.addReport(module.getName(), reportPath + reportFilePath)); } else { tableProgress.put(module, panel.addReport(module.getName(), null)); @@ -165,7 +165,7 @@ class ReportGenerator { if (entry.getValue()) { GeneralReportModule module = entry.getKey(); String reportFilePath = module.getRelativeFilePath(); - if (reportFilePath != null) { + if (!reportFilePath.isEmpty()) { generalProgress.put(module, panel.addReport(module.getName(), reportPath + reportFilePath)); } else { generalProgress.put(module, panel.addReport(module.getName(), null)); @@ -179,7 +179,7 @@ class ReportGenerator { if (entry.getValue()) { FileReportModule module = entry.getKey(); String reportFilePath = module.getRelativeFilePath(); - if (reportFilePath != null) { + if (!reportFilePath.isEmpty()) { fileProgress.put(module, panel.addReport(module.getName(), reportPath + reportFilePath)); } else { fileProgress.put(module, panel.addReport(module.getName(), null)); From 554f071cfb474d6293c3e62a4d5642b8e29bdc8e Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 11 Sep 2015 13:57:37 -0400 Subject: [PATCH 13/22] uncomment test code --- Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 5c104478f9..581df8a3e7 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -129,7 +129,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { } indexOfHTMLReportModule++; } - //swap(modules, indexOfHTMLReportModule, 0); + swap(modules, indexOfHTMLReportModule, 0); modulesJList.getSelectionModel().addListSelectionListener(this); modulesJList.setCellRenderer(new ModuleCellRenderer()); From 4e0e47a33a6c73456b449d6c31a922d5cd85ed2e Mon Sep 17 00:00:00 2001 From: momo Date: Fri, 11 Sep 2015 13:59:54 -0400 Subject: [PATCH 14/22] add class name to logger --- Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 581df8a3e7..7227f5a349 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -145,7 +145,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { private void postWarningMessage(ReportModule module) { String moduleClassName = (module != null) ? module.getClass().getSimpleName() : "null"; // NON_NLS - logger.log(Level.WARNING, "Invalid ReportModule"); // NON_NLS + logger.log(Level.WARNING, "Invalid ReportModule: {0}", moduleClassName); // NON_NLS DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.invalidModuleWarning", moduleClassName), NotifyDescriptor.ERROR_MESSAGE)); From 318fa6e4884b679db1369925ac5eea743efce6f7 Mon Sep 17 00:00:00 2001 From: mhmdfy Date: Mon, 14 Sep 2015 12:20:01 -0400 Subject: [PATCH 15/22] add getTotalJobs back to startUp() for more insurance --- .../autopsy/modules/hashdatabase/HashDbIngestModule.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java index a6b440de33..2416001856 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbIngestModule.java @@ -87,6 +87,9 @@ public class HashDbIngestModule implements FileIngestModule { updateEnabledHashSets(hashDbManager.getKnownFileHashSets(), knownHashSets); if (refCounter.incrementAndGet(jobId) == 1) { + // initialize job totals + getTotalsForIngestJobs(jobId); + // if first module for this job then post error msgs if needed if (knownBadHashSets.isEmpty()) { From 4665a8e0c8af6d4dd918e811a2c917c178743b15 Mon Sep 17 00:00:00 2001 From: mhmdfy Date: Mon, 14 Sep 2015 14:38:08 -0400 Subject: [PATCH 16/22] if getName() is empty -> error popup and don't display the module --- Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 7227f5a349..2113f7992a 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -140,7 +140,8 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { // Make sure that the report module has a valid non-null name. private boolean validModule(ReportModule module) { - return module != null && module.getName() != null && module.getRelativeFilePath() != null; + return module != null && module.getName() != null && !module.getName().isEmpty() + && module.getRelativeFilePath() != null; } private void postWarningMessage(ReportModule module) { From e247a56fed4dba456c09a682c8e6a898217708cf Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 15 Sep 2015 14:49:32 -0400 Subject: [PATCH 17/22] replace separate queries for events with tags and hash hits with additional group_concat columns --- .../autopsy/timeline/db/EventDB.java | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/db/EventDB.java b/Core/src/org/sleuthkit/autopsy/timeline/db/EventDB.java index 1b6c5943fb..3c3ba4069a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/db/EventDB.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/db/EventDB.java @@ -1064,9 +1064,12 @@ public class EventDB { String timeZone = TimeLineController.getTimeZone().get().equals(TimeZone.getDefault()) ? ", 'localtime'" : ""; // NON-NLS String typeColumn = typeColumnHelper(useSubTypes); - //compose query string + //compose query string, new-lines only for nicer formatting if printing the entire query String query = "SELECT strftime('" + strfTimeFormat + "',time , 'unixepoch'" + timeZone + ") AS interval," // NON-NLS - + " group_concat(events.event_id) as event_ids, min(time), max(time), " + typeColumn + ", " + descriptionColumn // NON-NLS + + "\n group_concat(events.event_id) as event_ids," + + "\n group_concat(CASE WHEN hash_hit = 1 THEN event_id ELSE NULL END) as hash_hits," + + "\n group_concat(CASE WHEN tagged = 1 THEN event_id ELSE NULL END) as taggeds," + + "\n min(time), max(time), " + typeColumn + ", " + descriptionColumn // NON-NLS + "\n FROM events" + useHashHitTablesHelper(filter) + useTagTablesHelper(filter) // NON-NLS + "\n WHERE time >= " + start + " AND time < " + end + " AND " + SQLHelper.getSQLWhere(filter) // NON-NLS + "\n GROUP BY interval, " + typeColumn + " , " + descriptionColumn // NON-NLS @@ -1074,6 +1077,7 @@ public class EventDB { // perform query and map results to AggregateEvent objects List events = new ArrayList<>(); + DBLock.lock(); try (Statement createStatement = con.createStatement(); @@ -1110,23 +1114,8 @@ public class EventDB { String description = rs.getString(SQLHelper.getDescriptionColumn(descriptionLOD)); EventType type = useSubTypes ? RootEventType.allTypes.get(rs.getInt("sub_type")) : BaseTypes.values()[rs.getInt("base_type")];// NON-NLS - Set hashHits = new HashSet<>(); - String hashHitQuery = "SELECT group_concat(event_id) FROM events WHERE event_id IN (" + eventIDsString + ") AND hash_hit = 1";// NON-NLS - try (Statement stmt = con.createStatement(); - ResultSet hashHitsRS = stmt.executeQuery(hashHitQuery)) { - while (hashHitsRS.next()) { - hashHits = SQLHelper.unGroupConcat(hashHitsRS.getString("group_concat(event_id)"), Long::valueOf);// NON-NLS - } - } - - Set tagged = new HashSet<>(); - String taggedQuery = "SELECT group_concat(event_id) FROM events WHERE event_id IN (" + eventIDsString + ") AND tagged = 1";// NON-NLS - try (Statement stmt = con.createStatement(); - ResultSet taggedRS = stmt.executeQuery(taggedQuery)) { - while (taggedRS.next()) { - tagged = SQLHelper.unGroupConcat(taggedRS.getString("group_concat(event_id)"), Long::valueOf);// NON-NLS - } - } + Set hashHits = SQLHelper.unGroupConcat(rs.getString("hash_hits"), Long::valueOf); + Set tagged = SQLHelper.unGroupConcat(rs.getString("taggeds"), Long::valueOf); return new AggregateEvent(interval, type, eventIDs, hashHits, tagged, description, descriptionLOD); From 8bc876a390f42c76166e4ed63a540a7922e0586b Mon Sep 17 00:00:00 2001 From: momo Date: Wed, 16 Sep 2015 16:45:30 -0400 Subject: [PATCH 18/22] Making sure to read all data and not skipping decimals --- .../e01verify/E01VerifyIngestModule.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java index d0a813b61b..6c43ac7cf4 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java @@ -23,6 +23,7 @@ import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import javax.xml.bind.DatatypeConverter; import org.openide.util.NbBundle; +import org.python.bouncycastle.util.Arrays; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.DataSourceIngestModule; import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; @@ -48,7 +49,6 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { private MessageDigest messageDigest; private boolean verified = false; - private boolean skipped = false; private String calculatedHash = ""; private String storedHash = ""; private IngestJobContext context; @@ -75,8 +75,10 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { @Override public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) { String imgName = dataSource.getName(); + + // Skip non-images if (!(dataSource instanceof Image)) { - logger.log(Level.INFO, "Skipping disk image image {0}", imgName); //NON-NLS + logger.log(Level.INFO, "Skipping non-image {0}", imgName); //NON-NLS services.postMessage(IngestMessage.createMessage(MessageType.INFO, E01VerifierModuleFactory.getModuleName(), NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.process.skipNonEwf", @@ -95,16 +97,17 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { return ProcessResult.OK; } - if ((img.getMd5() != null) && !img.getMd5().isEmpty()) { - storedHash = img.getMd5().toLowerCase(); - logger.log(Level.INFO, "Hash value stored in {0}: {1}", new Object[]{imgName, storedHash}); //NON-NLS - } else { + // Report an error for null or empty MD5 + if ((img.getMd5() == null) || img.getMd5().isEmpty()) { services.postMessage(IngestMessage.createMessage(MessageType.ERROR, E01VerifierModuleFactory.getModuleName(), NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.process.noStoredHash", imgName))); return ProcessResult.ERROR; } + + storedHash = img.getMd5().toLowerCase(); + logger.log(Level.INFO, "Hash value stored in {0}: {1}", new Object[]{imgName, storedHash}); //NON-NLS logger.log(Level.INFO, "Starting hash verification of {0}", img.getName()); //NON-NLS services.postMessage(IngestMessage.createMessage(MessageType.INFO, E01VerifierModuleFactory.getModuleName(), @@ -126,7 +129,8 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { long chunkSize = 64 * img.getSsize(); chunkSize = (chunkSize == 0) ? DEFAULT_CHUNK_SIZE : chunkSize; - int totalChunks = (int) Math.ceil(size / chunkSize); + // Casting to double to capture decimals + int totalChunks = (int) Math.ceil((double)size / (double)chunkSize); logger.log(Level.INFO, "Total chunks = {0}", totalChunks); //NON-NLS int read; @@ -148,7 +152,10 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { logger.log(Level.SEVERE, msg, ex); return ProcessResult.ERROR; } - messageDigest.update(data); + + // Only update with the read bytes. + byte[] subData = Arrays.copyOfRange(data, 0, read); + messageDigest.update(subData); statusHelper.progress(i); } From ba7c0d6958d9e47470222d1f0756b245d4cea951 Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 17 Sep 2015 10:29:14 -0400 Subject: [PATCH 19/22] optimizing bytes list --- .../modules/e01verify/E01VerifyIngestModule.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java index 6c43ac7cf4..c4b1df80b2 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/e01verify/E01VerifyIngestModule.java @@ -134,7 +134,7 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { logger.log(Level.INFO, "Total chunks = {0}", totalChunks); //NON-NLS int read; - byte[] data; + byte[] data = new byte[(int) chunkSize]; statusHelper.switchToDeterminate(totalChunks); // Read in byte size chunks and update the hash value with the data. @@ -142,7 +142,6 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { if (context.dataSourceIngestIsCancelled()) { return ProcessResult.OK; } - data = new byte[(int) chunkSize]; try { read = img.read(data, i * chunkSize, chunkSize); } catch (TskCoreException ex) { @@ -154,8 +153,12 @@ public class E01VerifyIngestModule implements DataSourceIngestModule { } // Only update with the read bytes. - byte[] subData = Arrays.copyOfRange(data, 0, read); - messageDigest.update(subData); + if(read == chunkSize) { + messageDigest.update(data); + } else { + byte[] subData = Arrays.copyOfRange(data, 0, read); + messageDigest.update(subData); + } statusHelper.progress(i); } From 226045b138dad8bb2cedfef6bf2b146c4979232f Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 17 Sep 2015 13:38:56 -0400 Subject: [PATCH 20/22] refactor class names --- .../autopsy/casemodule/UpdateRecentCases.java | 2 +- .../org/sleuthkit/autopsy/ingest/Bundle.properties | 2 +- .../org/sleuthkit/autopsy/ingest/RunIngestAction.java | 6 +++--- ...nuImageAction.java => RunIngestModulesAction.java} | 8 ++++---- .../autopsy/ingest/RunIngestModulesDialog.java | 2 +- ...{UpdateIngestImages.java => RunIngestSubMenu.java} | 11 +++++------ 6 files changed, 15 insertions(+), 16 deletions(-) rename Core/src/org/sleuthkit/autopsy/ingest/{MenuImageAction.java => RunIngestModulesAction.java} (88%) rename Core/src/org/sleuthkit/autopsy/ingest/{UpdateIngestImages.java => RunIngestSubMenu.java} (90%) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java b/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java index 1a6c65022c..b57f20abdf 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties index 8e966f1326..6ee8e785f8 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties @@ -100,4 +100,4 @@ IngestJobTableModel.colName.rootQueued=Root Queued IngestJobTableModel.colName.dsQueued=DS Queued ModuleTableModel.colName.module=Module ModuleTableModel.colName.duration=Duration -UpdateIngestImages.menuItem.empty=-Empty- +RunIngestSubMenu.menuItem.empty=-Empty- diff --git a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java index e703de0704..0bcd23b8b9 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -72,14 +72,14 @@ public final class RunIngestAction extends CallableSystemAction implements Prese } /** - * Create a sublist of images updated by UpdateIngestImages + * Create a sublist of images updated by RunIngestSubMenu * Each has an action to perform Ingest Modules on it. * * @return the images sublist created. */ @Override public JMenuItem getMenuPresenter() { - JMenuItem sublist = new UpdateIngestImages(); + JMenuItem sublist = new RunIngestSubMenu(); sublist.setVisible(true); return sublist; } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesAction.java similarity index 88% rename from Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java rename to Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesAction.java index bdcb1dd2d4..50a2319529 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/MenuImageAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2014 Basis Technology Corp. + * Copyright 2011-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,8 +19,8 @@ package org.sleuthkit.autopsy.ingest; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.Collections; +import javax.swing.AbstractAction; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; @@ -28,14 +28,14 @@ import org.sleuthkit.datamodel.Image; * This class is used to add the action to the run ingest modules menu item. * When the image is pressed, it should open the wizard for ingest modules. */ -class MenuImageAction implements ActionListener { +final class RunIngestModulesAction extends AbstractAction { Image image; /** * the constructor */ - public MenuImageAction(Image image) { + public RunIngestModulesAction(Image image) { this.image = image; } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesDialog.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesDialog.java index 4b81506603..da491fd22a 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesDialog.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestModulesDialog.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2014 Basis Technology Corp. + * Copyright 2013-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestSubMenu.java similarity index 90% rename from Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java rename to Core/src/org/sleuthkit/autopsy/ingest/RunIngestSubMenu.java index a21922ccfd..f4db5d47e8 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/UpdateIngestImages.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/RunIngestSubMenu.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2015 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,7 +32,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * This class is used to populate the list of open images to run ingest on them */ -class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { +final class RunIngestSubMenu extends JMenuItem implements DynamicMenuContent { /** * Creates main menu/popup menu items. It's called each time a popup menu @@ -44,7 +44,6 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { @Override public JComponent[] getMenuPresenters() { List images = new ArrayList<>(); - JComponent[] comps = new JComponent[1]; try { SleuthkitCase sk = Case.getCurrentCase().getSleuthkitCase(); @@ -55,14 +54,14 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { } catch (TskCoreException e) { System.out.println("Exception getting images: " + e.getMessage()); } - comps = new JComponent[images.size()]; + JComponent[] comps = new JComponent[images.size()]; // Add Images to the component list for (int i = 0; i < images.size(); i++) { String action = images.get(i).getName(); JMenuItem menuItem = new JMenuItem(action); menuItem.setActionCommand(action.toUpperCase()); - menuItem.addActionListener(new MenuImageAction(images.get(i))); + menuItem.addActionListener(new RunIngestModulesAction(images.get(i))); comps[i] = menuItem; } // If no images are open, create a disabled empty menu @@ -75,7 +74,7 @@ class UpdateIngestImages extends JMenuItem implements DynamicMenuContent { // returns a disabled empty menu private JComponent[] getEmpty() { JComponent[] comps = new JComponent[1]; - JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(UpdateIngestImages.class, "UpdateIngestImages.menuItem.empty")); + JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(RunIngestSubMenu.class, "RunIngestSubMenu.menuItem.empty")); comps[0] = emptyMenu; comps[0].setEnabled(false); return comps; From 77f1aae789d13c4ea5da8f6754a77f968f459958 Mon Sep 17 00:00:00 2001 From: momo Date: Thu, 17 Sep 2015 13:52:55 -0400 Subject: [PATCH 21/22] rename methods, remove null check --- .../autopsy/report/ReportVisualPanel1.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java index 2113f7992a..9b6acfd092 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel1.java @@ -40,14 +40,11 @@ import org.openide.NotifyDescriptor; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.ingest.IngestMessage; -import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.python.JythonModuleLoader; final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { private static final Logger logger = Logger.getLogger(ReportVisualPanel1.class.getName()); - private final IngestServices services = IngestServices.getInstance(); private ReportWizardPanel1 wizPanel; private List modules = new ArrayList<>(); private List generalModules = new ArrayList<>(); @@ -69,38 +66,38 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { // Initialize the list of ReportModules private void initModules() { for (TableReportModule module : Lookup.getDefault().lookupAll(TableReportModule.class)) { - if (validModule(module)) { + if (moduleIsValid(module)) { tableModules.add(module); modules.add(module); } else { - postWarningMessage(module); + popupWarning(module); } } for (GeneralReportModule module : Lookup.getDefault().lookupAll(GeneralReportModule.class)) { - if (validModule(module)) { + if (moduleIsValid(module)) { generalModules.add(module); modules.add(module); } else { - postWarningMessage(module); + popupWarning(module); } } for (GeneralReportModule module : JythonModuleLoader.getGeneralReportModules()) { - if (validModule(module)) { + if (moduleIsValid(module)) { generalModules.add(module); modules.add(module); } else { - postWarningMessage(module); + popupWarning(module); } } for (FileReportModule module : Lookup.getDefault().lookupAll(FileReportModule.class)) { - if (validModule(module)) { + if (moduleIsValid(module)) { fileModules.add(module); modules.add(module); } else { - postWarningMessage(module); + popupWarning(module); } } @@ -139,13 +136,13 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { } // Make sure that the report module has a valid non-null name. - private boolean validModule(ReportModule module) { - return module != null && module.getName() != null && !module.getName().isEmpty() + private boolean moduleIsValid(ReportModule module) { + return module.getName() != null && !module.getName().isEmpty() && module.getRelativeFilePath() != null; } - private void postWarningMessage(ReportModule module) { - String moduleClassName = (module != null) ? module.getClass().getSimpleName() : "null"; // NON_NLS + private void popupWarning(ReportModule module) { + String moduleClassName = module.getClass().getSimpleName(); logger.log(Level.WARNING, "Invalid ReportModule: {0}", moduleClassName); // NON_NLS DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.invalidModuleWarning", moduleClassName), From 084d977f3d15a16818dfe696aab151e546784b00 Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 17 Sep 2015 17:03:21 -0400 Subject: [PATCH 22/22] replace Exception.printStackTrace with proper loggign, plus minor cleanup and comment improvements --- .../autopsy/timeline/FXMLConstructor.java | 41 +++++++++++++++---- .../datamodel/eventtype/MiscTypes.java | 34 ++++++++++----- .../timeline/explorernodes/EventNode.java | 17 +++++--- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/FXMLConstructor.java b/Core/src/org/sleuthkit/autopsy/timeline/FXMLConstructor.java index cdf6a38455..0c90af7f27 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/FXMLConstructor.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/FXMLConstructor.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2013-15 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,10 +21,12 @@ package org.sleuthkit.autopsy.timeline; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.logging.Level; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import org.apache.commons.lang3.StringUtils; -import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ThreadConfined; /** * This class supports programmer productivity by abstracting frequently used @@ -34,32 +36,53 @@ import org.openide.util.Exceptions; * at * http://stackoverflow.com/questions/11734885/javafx2-very-poor-performance-when-adding-custom-made-fxmlpanels-to-gridpane. * + * NOTE: As described in the link above above, using FXMLConstructor will be + * inefficient if FXML is used as a template for many similar items. In that use + * case, it is much faster to build the entire hierarchy in Java. This class is + * intended only to remove the boilerplate initialization code when defining a + * relatively static layout + * * TODO: find a way to move this to CoreUtils and remove duplicate verison in * image analyzer */ public class FXMLConstructor { - static public void construct(Node n, String fxmlFileName) { - final String name = "nbres:/" + StringUtils.replace(n.getClass().getPackage().getName(), ".", "/") + "/" + fxmlFileName; // NON-NLS - System.out.println(name); + private static final Logger LOGGER = Logger.getLogger(FXMLConstructor.class.getName()); + + /** + * Load an fxml file and initialize a node with it. Since this manipulates + * the node, it must be called on the JFX thread. + * + * + * @param node a node to initialize from a loaded FXML + * @param fxmlFileName the the file name of the FXML to load, relative to + * the package that the class of node is defined in. + */ + @ThreadConfined(type = ThreadConfined.ThreadType.JFX) + static public void construct(Node node, String fxmlFileName) { + final String name = "nbres:/" + StringUtils.replace(node.getClass().getPackage().getName(), ".", "/") + "/" + fxmlFileName; // NON-NLS try { FXMLLoader fxmlLoader = new FXMLLoader(new URL(name)); - fxmlLoader.setRoot(n); - fxmlLoader.setController(n); + fxmlLoader.setRoot(node); + fxmlLoader.setController(node); try { fxmlLoader.load(); } catch (IOException exception) { + LOGGER.log(Level.SEVERE, "FXMLConstructor was unable to load FXML, falling back on default Class Loader, and trying again.", exception); try { fxmlLoader.setClassLoader(FXMLLoader.getDefaultClassLoader()); fxmlLoader.load(); } catch (IOException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.SEVERE, "FXMLConstructor was unable to load FXML, node initialization may not be complete.", ex); } } } catch (MalformedURLException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.SEVERE, "FXMLConstructor was unable to load FXML, node initialization may not be complete.", ex); } } + + private FXMLConstructor() { + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/eventtype/MiscTypes.java b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/eventtype/MiscTypes.java index ef57868a1d..6f59c8f981 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/eventtype/MiscTypes.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/eventtype/MiscTypes.java @@ -23,10 +23,11 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.BiFunction; +import java.util.logging.Level; import javafx.scene.image.Image; import org.apache.commons.lang3.StringUtils; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -57,7 +58,7 @@ public enum MiscTypes implements EventType, ArtifactEventType { BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME), new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION), - (BlackboardArtifact artf, Map attrMap) -> { + (artf, attrMap) -> { final BlackboardAttribute latStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START); final BlackboardAttribute longStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START); final BlackboardAttribute latEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END); @@ -129,18 +130,16 @@ public enum MiscTypes implements EventType, ArtifactEventType { BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE), new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL), - (BlackboardArtifact t, - Map u) -> { + (artifact, attributeMap) -> { try { - AbstractFile f = t.getSleuthkitCase().getAbstractFileById(t.getObjectID()); - if (f != null) { - return f.getName(); + AbstractFile file = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()); + if (file != null) { + return file.getName(); } - return " error loading file name"; // NON-NLS } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - return " error loading file name"; // NON-NLS + Logger.getLogger(MiscTypes.class.getName()).log(Level.SEVERE, "Exif event type failed to look up backing file name", ex); } + return " error loading file name"; // NON-NLS }), DEVICES_ATTACHED(NbBundle.getMessage(MiscTypes.class, "MiscTypes.devicesAttached.name"), "usb_devices.png", // NON-NLS BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED, @@ -185,26 +184,41 @@ public enum MiscTypes implements EventType, ArtifactEventType { private final BiFunction, String> shortExtractor; + /** + * {@inheritDoc } + */ @Override public BiFunction, String> getFullExtractor() { return longExtractor; } + /** + * {@inheritDoc } + */ @Override public BiFunction, String> getMedExtractor() { return medExtractor; } + /** + * {@inheritDoc } + */ @Override public BiFunction, String> getShortExtractor() { return shortExtractor; } + /** + * {@inheritDoc } + */ @Override public BlackboardAttribute.ATTRIBUTE_TYPE getDateTimeAttrubuteType() { return dateTimeAttributeType; } + /** + * {@inheritDoc } + */ @Override public EventTypeZoomLevel getZoomLevel() { return EventTypeZoomLevel.SUB_TYPE; diff --git a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java index 83e8801532..82e0531b46 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java @@ -22,6 +22,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.logging.Level; import javafx.beans.Observable; import javax.swing.Action; import org.joda.time.DateTime; @@ -29,8 +30,8 @@ import org.joda.time.DateTimeZone; import org.openide.nodes.Children; import org.openide.nodes.PropertySupport; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; @@ -46,6 +47,8 @@ import org.sleuthkit.datamodel.Content; */ class EventNode extends DisplayableItemNode { + private static final Logger LOGGER = Logger.getLogger(EventNode.class.getName()); + private final TimeLineEvent e; EventNode(TimeLineEvent eventById, AbstractFile file, BlackboardArtifact artifact) { @@ -75,7 +78,7 @@ class EventNode extends DisplayableItemNode { try { timePropery.setValue(getDateTimeString()); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.SEVERE, "unexpected error setting date/time property on EventNode explorer node", ex); } }); @@ -105,7 +108,7 @@ class EventNode extends DisplayableItemNode { final List factoryActions = DataModelActionsFactory.getActions(content, artifact != null); actionsList.addAll(factoryActions); - return actionsList.toArray(new Action[0]); + return actionsList.toArray(new Action[actionsList.size()]); } @Override @@ -118,7 +121,11 @@ class EventNode extends DisplayableItemNode { throw new UnsupportedOperationException("Not supported yet."); // NON-NLS //To change body of generated methods, choose Tools | Templates. } - class TimeProperty extends PropertySupport.ReadWrite { + /** + * We use TimeProperty instead of a normal NodeProperty to correctly display + * the date/time when the user changes the timezone setting. + */ + private class TimeProperty extends PropertySupport.ReadWrite { private String value; @@ -127,7 +134,7 @@ class EventNode extends DisplayableItemNode { return false; } - public TimeProperty(String name, String displayName, String shortDescription, String value) { + TimeProperty(String name, String displayName, String shortDescription, String value) { super(name, String.class, displayName, shortDescription); setValue("suppressCustomEditor", Boolean.TRUE); // remove the "..." (editing) button NON-NLS this.value = value;