From 77277fd409f3687d8f04b09d0306a96b849948a1 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 28 Mar 2018 16:16:16 +0200 Subject: [PATCH 01/29] Revert "disable the CVT for custom release" This reverts commit c6965985144f9c40273ef03d3705c5622d912786. --- .../AccountDeviceInstanceNode.java | 4 ++-- .../communications/CVTTopComponent.form | 18 ++++++++++++++---- .../communications/CVTTopComponent.java | 7 ++++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 81bb781771..40cb15d27d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -102,8 +102,8 @@ final class AccountDeviceInstanceNode extends AbstractNode { @Override public Action[] getActions(boolean context) { ArrayList actions = new ArrayList<>(Arrays.asList(super.getActions(context))); -// actions.add(PinAccountsAction.getInstance()); -// actions.add(ResetAndPinAccountsAction.getInstance()); + actions.add(PinAccountsAction.getInstance()); + actions.add(ResetAndPinAccountsAction.getInstance()); return actions.toArray(new Action[actions.size()]); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 89e2ae4905..055719c488 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -1,10 +1,6 @@
- - - - @@ -72,6 +68,20 @@ + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index a33816b3fd..09052d9d9e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -71,7 +71,7 @@ public final class CVTTopComponent extends TopComponent { * via an Eventbus */ CVTEvents.getCVTEventBus().register(this); -// CVTEvents.getCVTEventBus().register(vizPanel); + CVTEvents.getCVTEventBus().register(vizPanel); CVTEvents.getCVTEventBus().register(accountsBrowser); } @@ -88,13 +88,14 @@ public final class CVTTopComponent extends TopComponent { // //GEN-BEGIN:initComponents private void initComponents() { - vizPanel = new VisualizationPanel(); browseVisualizeTabPane = new JTabbedPane(); accountsBrowser = new AccountsBrowser(); + vizPanel = new VisualizationPanel(); filtersPane = new FiltersPanel(); browseVisualizeTabPane.setFont(new Font("Tahoma", 0, 18)); // NOI18N browseVisualizeTabPane.addTab(NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1"), new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N + browseVisualizeTabPane.addTab(NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.vizPanel.TabConstraints.tabTitle_1"), new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), vizPanel); // NOI18N filtersPane.setMinimumSize(new Dimension(256, 495)); @@ -105,7 +106,7 @@ public final class CVTTopComponent extends TopComponent { .addGap(6, 6, 6) .addComponent(filtersPane, GroupLayout.PREFERRED_SIZE, 265, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(browseVisualizeTabPane, GroupLayout.DEFAULT_SIZE, 786, Short.MAX_VALUE) + .addComponent(browseVisualizeTabPane, GroupLayout.PREFERRED_SIZE, 786, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) From d6f020acec888516072532d1457c72b31e5dd8a2 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 28 Mar 2018 16:23:43 +0200 Subject: [PATCH 02/29] don't show seconday relationships --- .../communications/CommunicationsGraph.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java index 49c3627e08..f274ab00d7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java @@ -279,8 +279,8 @@ final class CommunicationsGraph extends mxGraph { if (isCancelled()) { break; } - final List relatedAccountDeviceInstances = - commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter); + final List relatedAccountDeviceInstances + = commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter); relatedAccounts.put(adiKey.getAccountDeviceInstance(), adiKey); getOrCreateVertex(adiKey); @@ -299,14 +299,20 @@ final class CommunicationsGraph extends mxGraph { int total = relationshipCounts.size(); int k = 0; + String progressText = ""; progress.switchToDeterminate("", 0, total); for (Map.Entry entry : relationshipCounts.entrySet()) { Long count = entry.getValue(); AccountPair relationshipKey = entry.getKey(); AccountDeviceInstanceKey account1 = relatedAccounts.get(relationshipKey.getFirst()); AccountDeviceInstanceKey account2 = relatedAccounts.get(relationshipKey.getSecond()); - mxCell addEdge = addOrUpdateEdge(count, account1, account2); - progress.progress(addEdge.getId(), k++); + + if (pinnedAccountModel.isAccountPinned(account1) + || pinnedAccountModel.isAccountPinned(account2)) { + mxCell addEdge = addOrUpdateEdge(count, account1, account2); + progressText = addEdge.getId(); + } + progress.progress(progressText, k++); } } catch (TskCoreException tskCoreException) { logger.log(Level.SEVERE, "Error", tskCoreException); From 5d9e2228e07621ca229fde17dbd776e533d50976 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 29 Mar 2018 15:01:08 +0200 Subject: [PATCH 03/29] don't prompt for too many accounts --- .../autopsy/communications/VisualizationPanel.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 77eabb55c7..06343ddfd3 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -328,13 +328,8 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (worker.isCancelled()) { graph.resetGraph(); rebuildGraph(); - } else if (graph.getModel().getChildCount(graph.getDefaultParent()) < 64) { - applyOrganicLayout(10); } else { - JOptionPane.showMessageDialog(this, - "Too many accounts, layout aborted.", - "Autopsy", - JOptionPane.WARNING_MESSAGE); + applyOrganicLayout(10); } } }); @@ -651,7 +646,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider // Updates the display graph.getModel().endUpdate(); setCursor(Cursor.getDefaultCursor()); - + }//GEN-LAST:event_clearVizButtonActionPerformed private void applyOrganicLayout(int iterations) { From c326c1245f2c9be03283a305a1e40ada1d5a819c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 4 Apr 2018 14:47:58 +0200 Subject: [PATCH 04/29] change default to fast organic --- .../sleuthkit/autopsy/communications/VisualizationPanel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 06343ddfd3..cd75ab5185 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -62,7 +62,6 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JSplitPane; @@ -329,7 +328,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.resetGraph(); rebuildGraph(); } else { - applyOrganicLayout(10); + morph(fastOrganicLayout); } } }); From 642981ff697af65efac3b92aa8f8a94f2d46f8fd Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 29 Mar 2018 15:58:34 +0200 Subject: [PATCH 05/29] show applied layout in bold --- .../communications/CommunicationsGraph.java | 4 +- .../communications/VisualizationPanel.form | 22 +-- .../communications/VisualizationPanel.java | 173 ++++++++++-------- 3 files changed, 113 insertions(+), 86 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java index f274ab00d7..ddeb89ada6 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java @@ -278,13 +278,13 @@ final class CommunicationsGraph extends mxGraph { for (final AccountDeviceInstanceKey adiKey : pinnedAccountModel.getPinnedAccounts()) { if (isCancelled()) { break; - } + } + //get accounts related to pinned account final List relatedAccountDeviceInstances = commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter); relatedAccounts.put(adiKey.getAccountDeviceInstance(), adiKey); getOrCreateVertex(adiKey); - //get accounts related to pinned account for (final AccountDeviceInstance relatedADI : relatedAccountDeviceInstances) { final long adiRelationshipsCount = commsManager.getRelationshipSourcesCount(relatedADI, currentFilter); final AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, currentFilter, adiRelationshipsCount); diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form index 9d5722443e..3fb2b658d9 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form @@ -68,15 +68,15 @@ + + + - - - @@ -222,11 +222,11 @@ - - + + @@ -241,11 +241,11 @@ - - + + @@ -260,11 +260,11 @@ - - + + @@ -279,11 +279,11 @@ - - + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index cd75ab5185..a19ccb3f8d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -41,6 +41,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; +import java.awt.Font; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -56,6 +57,7 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.concurrent.Future; +import java.util.function.Consumer; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ImageIcon; @@ -142,8 +144,12 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final PinnedAccountModel pinnedAccountModel; private final LockedVertexModel lockedVertexModel; + private final List layoutButtons; + public VisualizationPanel() { initComponents(); + this.layoutButtons = Arrays.asList(circleLayoutButton, fastOrganicLayoutButton, organicLayoutButton, hierarchyLayoutButton); + graph = new CommunicationsGraph(); pinnedAccountModel = graph.getPinnedAccountModel(); lockedVertexModel = graph.getLockedVertexModel(); @@ -173,83 +179,13 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getView().addListener(mxEvent.SCALE, scaleListener); graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, scaleListener); - graphComponent.getGraphControl().addMouseWheelListener(new MouseAdapter() { - /** - * Translate mouse wheel events into zooming. - * - * @param event The MouseWheelEvent - */ - @Override - public void mouseWheelMoved(final MouseWheelEvent event) { - super.mouseWheelMoved(event); - if (event.getPreciseWheelRotation() > 0) { - graphComponent.zoomIn(); - } else if (event.getPreciseWheelRotation() < 0) { - graphComponent.zoomOut(); - } - } - }); + final GraphMouseListener graphMouseListener = new GraphMouseListener(); - graphComponent.getGraphControl().addMouseListener(new MouseAdapter() { - /** - * Right click handler: show context menu. - * - * @param event The MouseEvent - */ - @Override - public void mouseClicked(final MouseEvent event) { - super.mouseClicked(event); - if (SwingUtilities.isRightMouseButton(event)) { - final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY()); - if (cellAt != null && cellAt.isVertex()) { - final JPopupMenu jPopupMenu = new JPopupMenu(); - final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); + graphComponent.getGraphControl().addMouseWheelListener(graphMouseListener); + graphComponent.getGraphControl().addMouseListener(graphMouseListener); - if (lockedVertexModel.isVertexLocked(cellAt)) { - jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock " + cellAt.getId(), unlockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.unlockVertex(cellAt); - } - })); - } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Lock " + cellAt.getId(), lockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.lockVertex(cellAt); - } - })); - } - if (pinnedAccountModel.isAccountPinned(adiKey)) { - jPopupMenu.add(new JMenuItem(new AbstractAction("Unpin " + cellAt.getId(), unpinIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - handleUnPinEvent(new CVTEvents.UnpinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()))); - } - })); - } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Pin " + cellAt.getId(), addPinIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), false)); - } - })); - jPopupMenu.add(new JMenuItem(new AbstractAction("Pin only " + cellAt.getId(), pinIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), true)); - } - })); - } - jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY()); - } - } - } - }); final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM); - splitPane.setRightComponent(messageBrowser); - proxyLookup = new ProxyLookup( messageBrowser.getLookup(), ExplorerUtils.createLookup(vizEM, getActionMap())); @@ -261,6 +197,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); + } @Override @@ -621,18 +558,35 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider }//GEN-LAST:event_zoomOutButtonActionPerformed private void circleLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_circleLayoutButtonActionPerformed + makeButtonBold(circleLayoutButton); morph(circleLayout); }//GEN-LAST:event_circleLayoutButtonActionPerformed private void organicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_organicLayoutButtonActionPerformed + makeButtonBold(organicLayoutButton); applyOrganicLayout(10); }//GEN-LAST:event_organicLayoutButtonActionPerformed private void fastOrganicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_fastOrganicLayoutButtonActionPerformed + makeButtonBold(fastOrganicLayoutButton); morph(fastOrganicLayout); }//GEN-LAST:event_fastOrganicLayoutButtonActionPerformed + /** + * Sets only the given button to have bold text. + * + * @param layoutButton The button to make bold. + */ + private void makeButtonBold(JButton layoutButton) { + layoutButtons.forEach((JButton t) -> { + t.setFont(t.getFont().deriveFont(Font.PLAIN)); + }); + + layoutButton.setFont(layoutButton.getFont().deriveFont(Font.BOLD)); + } + private void hierarchyLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_hierarchyLayoutButtonActionPerformed + makeButtonBold(hierarchyLayoutButton); morph(hierarchicalLayout); }//GEN-LAST:event_hierarchyLayoutButtonActionPerformed @@ -901,4 +855,77 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + + private class GraphMouseListener extends MouseAdapter { + + /** + * Translate mouse wheel events into zooming. + * + * @param event The MouseWheelEvent + */ + @Override + public void mouseWheelMoved(final MouseWheelEvent event) { + super.mouseWheelMoved(event); + if (event.getPreciseWheelRotation() > 0) { + graphComponent.zoomIn(); + } else if (event.getPreciseWheelRotation() < 0) { + graphComponent.zoomOut(); + } + } + + /** + * Right click handler: show context menu. + * + * @param event The MouseEvent + */ + @Override + public void mouseClicked(final MouseEvent event) { + super.mouseClicked(event); + if (SwingUtilities.isRightMouseButton(event)) { + final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY()); + if (cellAt != null && cellAt.isVertex()) { + final JPopupMenu jPopupMenu = new JPopupMenu(); + final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); + + if (lockedVertexModel.isVertexLocked(cellAt)) { + jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock " + cellAt.getId(), unlockIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.unlockVertex(cellAt); + } + })); + } else { + jPopupMenu.add(new JMenuItem(new AbstractAction("Lock " + cellAt.getId(), lockIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.lockVertex(cellAt); + } + })); + } + if (pinnedAccountModel.isAccountPinned(adiKey)) { + jPopupMenu.add(new JMenuItem(new AbstractAction("Unpin " + cellAt.getId(), unpinIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + handleUnPinEvent(new CVTEvents.UnpinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()))); + } + })); + } else { + jPopupMenu.add(new JMenuItem(new AbstractAction("Pin " + cellAt.getId(), addPinIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), false)); + } + })); + jPopupMenu.add(new JMenuItem(new AbstractAction("Pin only " + cellAt.getId(), pinIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), true)); + } + })); + } + jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY()); + } + } + } + } } From 268308874eb2dc1a1085405e34cadce0f85e9621 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 4 Apr 2018 14:07:30 +0200 Subject: [PATCH 06/29] refactoring layout buttons --- .../communications/VisualizationPanel.form | 12 -- .../communications/VisualizationPanel.java | 112 +++++++----------- 2 files changed, 46 insertions(+), 78 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form index 3fb2b658d9..a847f700c7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form @@ -166,9 +166,6 @@ - - - @@ -179,9 +176,6 @@ - - - @@ -192,9 +186,6 @@ - - - @@ -205,9 +196,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index a19ccb3f8d..965832b3bd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -22,6 +22,7 @@ import com.google.common.eventbus.Subscribe; import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxFastOrganicLayout; +import com.mxgraph.layout.mxGraphLayout; import com.mxgraph.layout.mxIGraphLayout; import com.mxgraph.layout.mxOrganicLayout; import com.mxgraph.model.mxCell; @@ -54,10 +55,14 @@ import java.text.DecimalFormat; import java.util.Arrays; import static java.util.Collections.singleton; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.concurrent.Future; +import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ImageIcon; @@ -137,27 +142,23 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxFastOrganicLayout fastOrganicLayout; private final mxCircleLayout circleLayout; private final mxOrganicLayout organicLayout; - private final mxHierarchicalLayout hierarchicalLayout; + private final mxHierarchicalLayout hierarchyLayout; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; private final PinnedAccountModel pinnedAccountModel; private final LockedVertexModel lockedVertexModel; - private final List layoutButtons; + private final Map layoutButtons = new HashMap<>(); + private mxGraphLayout currentLayout; public VisualizationPanel() { initComponents(); - this.layoutButtons = Arrays.asList(circleLayoutButton, fastOrganicLayoutButton, organicLayoutButton, hierarchyLayoutButton); - graph = new CommunicationsGraph(); + pinnedAccountModel = graph.getPinnedAccountModel(); lockedVertexModel = graph.getLockedVertexModel(); - - fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); - circleLayout = new mxCircleLayoutImpl(graph); - organicLayout = new mxOrganicLayoutImpl(graph); - hierarchicalLayout = new mxHierarchicalLayoutImpl(graph); + graphComponent = new mxGraphComponent(graph); graphComponent.setAutoExtend(true); @@ -197,9 +198,32 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); + + fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); + circleLayout = new mxCircleLayoutImpl(graph); + organicLayout = new mxOrganicLayoutImpl(graph); + organicLayout.setMaxIterations(10); + hierarchyLayout = new mxHierarchicalLayoutImpl(graph); + //local method to configure layout buttons + BiConsumer configure = (layoutButton, layout) -> { + layoutButtons.put(layout, layoutButton); + layoutButton.addActionListener(event -> applyLayout(layout)); + }; + //configure layout buttons. + configure.accept(circleLayoutButton, circleLayout); + configure.accept(organicLayoutButton, organicLayout); + configure.accept(fastOrganicLayoutButton, fastOrganicLayout); + configure.accept(hierarchyLayoutButton, hierarchyLayout); + + applyLayout(circleLayout); } + /** + * + * @param layoutButton the value of layoutButton + * @param layout the value of layout + */ @Override public Lookup getLookup() { @@ -264,6 +288,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (worker.isCancelled()) { graph.resetGraph(); rebuildGraph(); + morph(organicLayout); } else { morph(fastOrganicLayout); } @@ -350,11 +375,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider borderLayoutPanel.setLayout(new BorderLayout()); + jTextArea1.setBackground(new Color(240, 240, 240)); jTextArea1.setColumns(20); jTextArea1.setLineWrap(true); jTextArea1.setRows(5); jTextArea1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextArea1.text")); // NOI18N - jTextArea1.setBackground(new Color(240, 240, 240)); GroupLayout placeHolderPanelLayout = new GroupLayout(placeHolderPanel); placeHolderPanel.setLayout(placeHolderPanelLayout); @@ -379,49 +404,29 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider hierarchyLayoutButton.setFocusable(false); hierarchyLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); hierarchyLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - hierarchyLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - hierarchyLayoutButtonActionPerformed(evt); - } - }); fastOrganicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fastOrganicLayoutButton.text")); // NOI18N fastOrganicLayoutButton.setFocusable(false); fastOrganicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); fastOrganicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - fastOrganicLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - fastOrganicLayoutButtonActionPerformed(evt); - } - }); organicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.organicLayoutButton.text")); // NOI18N organicLayoutButton.setFocusable(false); organicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); organicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - organicLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - organicLayoutButtonActionPerformed(evt); - } - }); circleLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.circleLayoutButton.text")); // NOI18N circleLayoutButton.setFocusable(false); circleLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); circleLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - circleLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - circleLayoutButtonActionPerformed(evt); - } - }); jSeparator1.setOrientation(SwingConstants.VERTICAL); zoomOutButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-out-red.png"))); // NOI18N zoomOutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.text")); // NOI18N + zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N zoomOutButton.setFocusable(false); zoomOutButton.setHorizontalTextPosition(SwingConstants.CENTER); - zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N zoomOutButton.setVerticalTextPosition(SwingConstants.BOTTOM); zoomOutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -431,9 +436,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider zoomInButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-in-green.png"))); // NOI18N zoomInButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.text")); // NOI18N + zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N zoomInButton.setFocusable(false); zoomInButton.setHorizontalTextPosition(SwingConstants.CENTER); - zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N zoomInButton.setVerticalTextPosition(SwingConstants.BOTTOM); zoomInButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -443,9 +448,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider zoomActualButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-actual.png"))); // NOI18N zoomActualButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.text")); // NOI18N + zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N zoomActualButton.setFocusable(false); zoomActualButton.setHorizontalTextPosition(SwingConstants.CENTER); - zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N zoomActualButton.setVerticalTextPosition(SwingConstants.BOTTOM); zoomActualButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -455,9 +460,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider fitZoomButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-fit.png"))); // NOI18N fitZoomButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.text")); // NOI18N + fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N fitZoomButton.setFocusable(false); fitZoomButton.setHorizontalTextPosition(SwingConstants.CENTER); - fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N fitZoomButton.setVerticalTextPosition(SwingConstants.BOTTOM); fitZoomButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -557,38 +562,18 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graphComponent.zoomOut(); }//GEN-LAST:event_zoomOutButtonActionPerformed - private void circleLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_circleLayoutButtonActionPerformed - makeButtonBold(circleLayoutButton); - morph(circleLayout); - }//GEN-LAST:event_circleLayoutButtonActionPerformed - - private void organicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_organicLayoutButtonActionPerformed - makeButtonBold(organicLayoutButton); - applyOrganicLayout(10); - }//GEN-LAST:event_organicLayoutButtonActionPerformed - - private void fastOrganicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_fastOrganicLayoutButtonActionPerformed - makeButtonBold(fastOrganicLayoutButton); - morph(fastOrganicLayout); - }//GEN-LAST:event_fastOrganicLayoutButtonActionPerformed - /** - * Sets only the given button to have bold text. * - * @param layoutButton The button to make bold. + * @param layoutButton the value of layoutButton + * @param layout the value of layout */ - private void makeButtonBold(JButton layoutButton) { - layoutButtons.forEach((JButton t) -> { - t.setFont(t.getFont().deriveFont(Font.PLAIN)); - }); - - layoutButton.setFont(layoutButton.getFont().deriveFont(Font.BOLD)); + private void applyLayout(mxGraphLayout layout) { + currentLayout = layout; + layoutButtons.forEach((layoutKey, button) + -> button.setFont(button.getFont().deriveFont(layoutKey == layout ? Font.BOLD : Font.PLAIN)) ); + morph(layout); } - private void hierarchyLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_hierarchyLayoutButtonActionPerformed - makeButtonBold(hierarchyLayoutButton); - morph(hierarchicalLayout); - }//GEN-LAST:event_hierarchyLayoutButtonActionPerformed private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); @@ -602,11 +587,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider }//GEN-LAST:event_clearVizButtonActionPerformed - private void applyOrganicLayout(int iterations) { - organicLayout.setMaxIterations(iterations); - morph(organicLayout); - } - private void fitGraph() { graphComponent.zoomTo(1, true); mxPoint translate = graph.getView().getTranslate(); From 08cc853fa8e8e447268ecde3c18f4f980508c11f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 4 Apr 2018 16:22:45 +0200 Subject: [PATCH 07/29] refactor to use LockedVertexLayoutWrapper --- .../communications/LockedVertexModel.java | 123 ++++++++++++++++ .../communications/VisualizationPanel.form | 6 +- .../communications/VisualizationPanel.java | 131 ++++-------------- 3 files changed, 151 insertions(+), 109 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index f26e9515b3..cde4eb5698 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -19,8 +19,13 @@ package org.sleuthkit.autopsy.communications; import com.google.common.eventbus.EventBus; +import com.mxgraph.layout.mxGraphLayout; import com.mxgraph.model.mxCell; +import com.mxgraph.util.mxPoint; +import com.mxgraph.util.mxRectangle; +import com.mxgraph.view.mxGraph; import java.util.HashSet; +import java.util.List; import java.util.Set; class LockedVertexModel { @@ -95,4 +100,122 @@ class LockedVertexModel { this.locked = locked; } } + + mxGraphLayout createLockedVertexWrapper(L layout) { + return new LockedVertexLayoutWrapper<>(layout, this); + } + + /** An mxGraphLayout that wrapps an other layout and ignores locked vertes. + * + * @param + */ + private static final class LockedVertexLayoutWrapper extends mxGraphLayout { + + private final L wrappedLayout; + private final LockedVertexModel lockedVertexModel; + + /** + * + * + * @param layout the value of graph + * @param lockedVertexModel the value of lockedVertexModel2 + */ + private LockedVertexLayoutWrapper(L layout, LockedVertexModel lockedVertexModel) { + super(layout.getGraph()); + this.lockedVertexModel = lockedVertexModel; + wrappedLayout = layout; + } + + @Override + public boolean isVertexIgnored(Object vertex) { + return wrappedLayout.isVertexIgnored(vertex) + || lockedVertexModel.isVertexLocked((mxCell) vertex); + } + + @Override + public mxRectangle setVertexLocation(Object vertex, double x, double y) { + if (isVertexIgnored(vertex)) { + return getVertexBounds(vertex); + } else { + return wrappedLayout.setVertexLocation(vertex, x, y); + } + } + + @Override + public void execute(Object parent) { + wrappedLayout.execute(parent); + } + + @Override + public void moveCell(Object cell, double x, double y) { + wrappedLayout.moveCell(cell, x, y); + } + + @Override + public mxGraph getGraph() { + return wrappedLayout.getGraph(); + } + + @Override + public Object getConstraint(Object key, Object cell) { + return wrappedLayout.getConstraint(key, cell); + } + + @Override + public Object getConstraint(Object key, Object cell, Object edge, boolean source) { + return wrappedLayout.getConstraint(key, cell, edge, source); + } + + @Override + public boolean isUseBoundingBox() { + return wrappedLayout.isUseBoundingBox(); + } + + @Override + public void setUseBoundingBox(boolean useBoundingBox) { + wrappedLayout.setUseBoundingBox(useBoundingBox); + } + + @Override + public boolean isVertexMovable(Object vertex) { + return wrappedLayout.isVertexMovable(vertex); + } + + @Override + public boolean isEdgeIgnored(Object edge) { + return wrappedLayout.isEdgeIgnored(edge); + } + + @Override + public void setEdgeStyleEnabled(Object edge, boolean value) { + wrappedLayout.setEdgeStyleEnabled(edge, value); + } + + @Override + public void setOrthogonalEdge(Object edge, boolean value) { + wrappedLayout.setOrthogonalEdge(edge, value); + } + + @Override + public mxPoint getParentOffset(Object parent) { + return wrappedLayout.getParentOffset(parent); + } + + @Override + public void setEdgePoints(Object edge, List points) { + wrappedLayout.setEdgePoints(edge, points); + } + + @Override + public mxRectangle getVertexBounds(Object vertex) { + return wrappedLayout.getVertexBounds(vertex); + } + + @Override + public void arrangeGroups(Object[] groups, int border) { + wrappedLayout.arrangeGroups(groups, border); + } + + } + } diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form index a847f700c7..deae56fd17 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form @@ -11,7 +11,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -120,7 +120,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 965832b3bd..a5175cfb4b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -21,10 +21,12 @@ package org.sleuthkit.autopsy.communications; import com.google.common.eventbus.Subscribe; import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; import com.mxgraph.layout.mxCircleLayout; +import com.mxgraph.layout.mxEdgeLabelLayout; import com.mxgraph.layout.mxFastOrganicLayout; import com.mxgraph.layout.mxGraphLayout; import com.mxgraph.layout.mxIGraphLayout; import com.mxgraph.layout.mxOrganicLayout; +import com.mxgraph.layout.mxParallelEdgeLayout; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxICell; import com.mxgraph.swing.handler.mxRubberband; @@ -61,8 +63,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Future; import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ImageIcon; @@ -139,10 +139,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxUndoManager undoManager = new mxUndoManager(); private final mxRubberband rubberband; - private final mxFastOrganicLayout fastOrganicLayout; - private final mxCircleLayout circleLayout; - private final mxOrganicLayout organicLayout; - private final mxHierarchicalLayout hierarchyLayout; + + private final mxGraphLayout fastOrganicLayout; + private final mxGraphLayout circleLayout; + private final mxGraphLayout organicLayout; + private final mxGraphLayout hierarchyLayout; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; @@ -158,7 +159,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider pinnedAccountModel = graph.getPinnedAccountModel(); lockedVertexModel = graph.getLockedVertexModel(); - graphComponent = new mxGraphComponent(graph); graphComponent.setAutoExtend(true); @@ -198,12 +198,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); - - fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); - circleLayout = new mxCircleLayoutImpl(graph); - organicLayout = new mxOrganicLayoutImpl(graph); - organicLayout.setMaxIterations(10); - hierarchyLayout = new mxHierarchicalLayoutImpl(graph); + + fastOrganicLayout = lockedVertexModel.createLockedVertexWrapper(new mxFastOrganicLayout(graph)); + hierarchyLayout = lockedVertexModel.createLockedVertexWrapper(new mxHierarchicalLayout(graph)); + circleLayout = lockedVertexModel.createLockedVertexWrapper(new mxCircleLayout(graph) { + { + setResetEdges(true); + } + }); + organicLayout = lockedVertexModel.createLockedVertexWrapper(new mxOrganicLayout(graph) { + { + setResetEdges(true); + setMaxIterations(10); + } + }); //local method to configure layout buttons BiConsumer configure = (layoutButton, layout) -> { @@ -502,7 +510,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider .add(hierarchyLayoutButton) .addPreferredGap(LayoutStyle.RELATED) .add(circleLayoutButton) - .addPreferredGap(LayoutStyle.RELATED) + .addPreferredGap(LayoutStyle.UNRELATED) .add(jSeparator2, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(jLabel2) @@ -516,7 +524,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider .add(zoomActualButton, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(fitZoomButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) - .addContainerGap(12, Short.MAX_VALUE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); toolbarLayout.setVerticalGroup(toolbarLayout.createParallelGroup(GroupLayout.LEADING) .add(toolbarLayout.createSequentialGroup() @@ -570,7 +578,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private void applyLayout(mxGraphLayout layout) { currentLayout = layout; layoutButtons.forEach((layoutKey, button) - -> button.setFont(button.getFont().deriveFont(layoutKey == layout ? Font.BOLD : Font.PLAIN)) ); + -> button.setFont(button.getFont().deriveFont(layoutKey == layout ? Font.BOLD : Font.PLAIN))); morph(layout); } @@ -727,96 +735,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } - final private class mxFastOrganicLayoutImpl extends mxFastOrganicLayout { - - mxFastOrganicLayoutImpl(mxGraph graph) { - super(graph); - } - - @Override - public boolean isVertexIgnored(Object vertex) { - return super.isVertexIgnored(vertex) - || lockedVertexModel.isVertexLocked((mxCell) vertex); - } - - @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { - if (isVertexIgnored(vertex)) { - return getVertexBounds(vertex); - } else { - return super.setVertexLocation(vertex, x, y); - } - } - } - - final private class mxCircleLayoutImpl extends mxCircleLayout { - - mxCircleLayoutImpl(mxGraph graph) { - super(graph); - setResetEdges(true); - } - - @Override - public boolean isVertexIgnored(Object vertex) { - return super.isVertexIgnored(vertex) - || lockedVertexModel.isVertexLocked((mxCell) vertex); - } - - @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { - if (isVertexIgnored(vertex)) { - return getVertexBounds(vertex); - } else { - return super.setVertexLocation(vertex, x, y); - } - } - } - - final private class mxOrganicLayoutImpl extends mxOrganicLayout { - - mxOrganicLayoutImpl(mxGraph graph) { - super(graph); - setResetEdges(true); - } - - @Override - public boolean isVertexIgnored(Object vertex) { - return super.isVertexIgnored(vertex) - || lockedVertexModel.isVertexLocked((mxCell) vertex); - } - - @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { - if (isVertexIgnored(vertex)) { - return getVertexBounds(vertex); - } else { - return super.setVertexLocation(vertex, x, y); - } - } - } - - final private class mxHierarchicalLayoutImpl extends mxHierarchicalLayout { - - mxHierarchicalLayoutImpl(mxGraph graph) { - super(graph); - } - - @Override - public boolean isVertexIgnored(Object vertex) { - return super.isVertexIgnored(vertex) - || lockedVertexModel.isVertexLocked((mxCell) vertex); - } - - @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { - if (isVertexIgnored(vertex)) { - return getVertexBounds(vertex); - } else { - return super.setVertexLocation(vertex, x, y); - } - } - } - private class CancelationListener implements ActionListener { private Future cancellable; @@ -908,4 +826,5 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } + } From f013514e3ebe0e4b658395ed74d30245fb9dff7f Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 4 Apr 2018 10:36:51 -0400 Subject: [PATCH 08/29] Added conflict clause to all INSTER SQL commands --- .../datamodel/AbstractSqlEamDb.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index b929956b1c..53f99e5ff8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -90,7 +90,8 @@ public abstract class AbstractSqlEamDb implements EamDb { Connection conn = connect(); PreparedStatement preparedStatement = null; - String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; + String sql = "INSERT INTO db_info (name, value) VALUES (?, ?) " + + getConflictClause(); try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setString(1, name); @@ -183,7 +184,8 @@ public abstract class AbstractSqlEamDb implements EamDb { String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, " + "examiner_name, examiner_email, examiner_phone, notes) " - + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); try { preparedStatement = conn.prepareStatement(sql); @@ -419,7 +421,8 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; - String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?)"; + String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) " + + getConflictClause(); try { preparedStatement = conn.prepareStatement(sql); @@ -543,7 +546,8 @@ public abstract class AbstractSqlEamDb implements EamDb { sql.append(tableName); sql.append("(case_id, data_source_id, value, file_path, known_status, comment) "); sql.append("VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "); - sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?)"); + sql.append("(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?) "); + sql.append(getConflictClause()); try { preparedStatement = conn.prepareStatement(sql.toString()); @@ -1529,7 +1533,8 @@ public abstract class AbstractSqlEamDb implements EamDb { Connection conn = connect(); ResultSet generatedKeys = null; PreparedStatement preparedStatement = null; - String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?)"; + String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) " + + getConflictClause(); try { preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); @@ -1735,7 +1740,8 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement1 = null; PreparedStatement preparedStatement2 = null; ResultSet resultSet = null; - String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?)"; + String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1"; try { @@ -1867,7 +1873,8 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; - String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?)"; + String sql = "INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) " + + getConflictClause(); try { preparedStatement = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(correlationType))); @@ -2038,9 +2045,9 @@ public abstract class AbstractSqlEamDb implements EamDb { String querySql; // if we have a known ID, use it, if not (is -1) let the db assign it. if (-1 == newType.getId()) { - insertSql = "INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?)"; + insertSql = "INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause(); } else { - insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)"; + insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause(); } querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?"; From 32868a97f1d49b0142ed703b1fbf016bcd6a0f7e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Thu, 5 Apr 2018 12:06:13 +0200 Subject: [PATCH 09/29] WIP - broken --- .../communications/AbstractCVTAction.java | 47 ++++++++++ .../AccountDeviceInstanceNode.java | 54 ----------- .../autopsy/communications/Bundle.properties | 3 - .../autopsy/communications/CVTEvents.java | 2 +- .../communications/PinAccountsAction.java | 55 +++++++++++ .../ResetAndPinAccountsAction.java | 59 ++++++++++++ .../communications/UnpinAccountsAction.java | 55 +++++++++++ .../communications/VisualizationPanel.java | 94 +++++++------------ 8 files changed, 251 insertions(+), 118 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java create mode 100644 Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java new file mode 100644 index 0000000000..c2b43f2041 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java @@ -0,0 +1,47 @@ +/* + * 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.communications; + +import java.util.Collection; +import javax.swing.AbstractAction; +import javax.swing.ImageIcon; +import javax.swing.JMenuItem; +import org.openide.util.Utilities; +import org.openide.util.actions.Presenter; + +/** + * + * + */ +abstract class AbstractCVTAction extends AbstractAction implements Presenter.Popup { + + /** + * Get the selected accounts that will be acted upon. + * + * @return The selected accounts + */ + Collection getSelectedAccounts() { + return Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); + } + + @Override + final public void putValue(String key, Object newValue) { + super.putValue(key, newValue); + } + + @Override + public JMenuItem getPopupPresenter() { + JMenuItem presenter = new JMenuItem(this); + presenter.setText(getActionDisplayName()); + presenter.setIcon(getIcon()); + return presenter; + } + + abstract String getActionDisplayName(); + + abstract ImageIcon getIcon(); + +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 40cb15d27d..044cec322f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -18,17 +18,13 @@ */ package org.sleuthkit.autopsy.communications; -import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import javax.swing.AbstractAction; import javax.swing.Action; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; -import org.openide.util.Utilities; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.Account; @@ -106,54 +102,4 @@ final class AccountDeviceInstanceNode extends AbstractNode { actions.add(ResetAndPinAccountsAction.getInstance()); return actions.toArray(new Action[actions.size()]); } - - /** - * Action that pins the selected AccountDeviceInstances to the - * visualization. - */ - static private class PinAccountsAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - private final static PinAccountsAction instance = new PinAccountsAction(); - - private static PinAccountsAction getInstance() { - return instance; - } - - private PinAccountsAction() { - super("Add Account(s) to Visualization"); - } - - @Override - public void actionPerformed(ActionEvent e) { - Collection lookupAll = - Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); - CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(lookupAll, false)); - } - } - - /** - * Action that pins the selected AccountDeviceInstances to the - * visualization. - */ - static private class ResetAndPinAccountsAction extends AbstractAction { - - private static final long serialVersionUID = 1L; - private final static ResetAndPinAccountsAction instance = new ResetAndPinAccountsAction(); - - private static ResetAndPinAccountsAction getInstance() { - return instance; - } - - private ResetAndPinAccountsAction() { - super("Visualize Account(s)"); - } - - @Override - public void actionPerformed(ActionEvent e) { - Collection lookupAll = - Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); - CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(lookupAll, true)); - } - } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 559e9bba86..ea3049f895 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -36,9 +36,6 @@ VisualizationPanel.zoomInButton.toolTipText=Zoom in VisualizationPanel.zoomInButton.text= VisualizationPanel.zoomOutButton.toolTipText=Zoom out VisualizationPanel.zoomOutButton.text= -# 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. VisualizationPanel.circleLayoutButton.text=Circle VisualizationPanel.organicLayoutButton.text=Organic VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java b/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java index e0f945bb69..54e5b8a1ef 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java @@ -79,7 +79,7 @@ final class CVTEvents { return accountDeviceInstances; } - public UnpinAccountsEvent(Set accountDeviceInstances) { + UnpinAccountsEvent(Collection accountDeviceInstances) { this.accountDeviceInstances = ImmutableSet.copyOf(accountDeviceInstances); } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java new file mode 100644 index 0000000000..d820373284 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java @@ -0,0 +1,55 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 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.communications; + +import java.awt.event.ActionEvent; +import javax.swing.ImageIcon; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle; + +@NbBundle.Messages({"PinAccountsAction.pluralText=Add Selected Accounts to Visualization", + "PinAccountsAction.singularText=Add Selected Account to Visualization"}) +final class PinAccountsAction extends AbstractCVTAction { + + static private final ImageIcon ICON = ImageUtilities.loadImageIcon( + "/org/sleuthkit/autopsy/communications/images/marker--plus.png", false); + private static final String SINGULAR_TEXT = Bundle.PinAccountsAction_singularText(); + private static final String PLURAL_TEXT = Bundle.PinAccountsAction_pluralText(); + + private static final PinAccountsAction instance = new PinAccountsAction(); + + static PinAccountsAction getInstance() { + return instance; + } + + @Override + public void actionPerformed(ActionEvent e) { + CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(getSelectedAccounts(), false)); + } + + @Override + protected String getActionDisplayName() { + return getSelectedAccounts().size() > 1 ? PLURAL_TEXT : SINGULAR_TEXT; + } + + @Override + ImageIcon getIcon() { + return ICON; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java new file mode 100644 index 0000000000..a42b2882ed --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java @@ -0,0 +1,59 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 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.communications; + +import java.awt.event.ActionEvent; +import javax.swing.ImageIcon; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle; + +/** + * + */ +@NbBundle.Messages(value = {"ResetAndPinAccountsAction.singularText=Visualize Only Selected Account", + "ResetAndPinAccountsAction.pluralText=Visualize Only Selected Accounts"}) +final class ResetAndPinAccountsAction extends AbstractCVTAction { + + private static final ImageIcon ICON = ImageUtilities.loadImageIcon( + "/org/sleuthkit/autopsy/communications/images/marker--pin.png", false); + private static final String SINGULAR_TEXT = Bundle.ResetAndPinAccountsAction_singularText(); + private static final String PLURAL_TEXT = Bundle.ResetAndPinAccountsAction_pluralText(); + + private static final ResetAndPinAccountsAction instance = new ResetAndPinAccountsAction(); + + static ResetAndPinAccountsAction getInstance() { + return instance; + } + + @Override + public void actionPerformed(ActionEvent e) { + CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(getSelectedAccounts(), true)); + } + + @Override + protected String getActionDisplayName() { + return getSelectedAccounts().size() > 1 ? PLURAL_TEXT : SINGULAR_TEXT; + } + + @Override + ImageIcon getIcon() { + return ICON; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java new file mode 100644 index 0000000000..357f5a0451 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java @@ -0,0 +1,55 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 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.communications; + +import java.awt.event.ActionEvent; +import javax.swing.ImageIcon; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle; + +@NbBundle.Messages({"UnpinAccountsAction.pluralText=Remove Selected Accounts", + "UnpinAccountsAction.singularText=Remove Selected Account"}) +final class UnpinAccountsAction extends AbstractCVTAction { + + static final private ImageIcon ICON = ImageUtilities.loadImageIcon( + "/org/sleuthkit/autopsy/communications/images/marker--minus.png", false); + private static final String SINGULAR_TEXT = Bundle.UnpinAccountsAction_singularText(); + private static final String PLURAL_TEXT = Bundle.UnpinAccountsAction_pluralText(); + + private static final UnpinAccountsAction instance = new UnpinAccountsAction(); + + static UnpinAccountsAction getInstance() { + return instance; + } + + @Override + public void actionPerformed(final ActionEvent event) { + CVTEvents.getCVTEventBus().post(new CVTEvents.UnpinAccountsEvent(getSelectedAccounts())); + } + + @Override + String getActionDisplayName() { + return getSelectedAccounts().size() > 1 ? PLURAL_TEXT : SINGULAR_TEXT; + } + + @Override + ImageIcon getIcon() { + return ICON; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index cd75ab5185..fa095fd0a8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -51,7 +51,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.text.DecimalFormat; import java.util.Arrays; -import static java.util.Collections.singleton; import java.util.EnumSet; import java.util.HashSet; import java.util.List; @@ -106,12 +105,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(VisualizationPanel.class.getName()); private static final String BASE_IMAGE_PATH = "/org/sleuthkit/autopsy/communications/images"; - static final private ImageIcon pinIcon - = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--pin.png")); - static final private ImageIcon addPinIcon - = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--plus.png")); - static final private ImageIcon unpinIcon - = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--minus.png")); static final private ImageIcon unlockIcon = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_unlocked.png")); static final private ImageIcon lockIcon @@ -132,6 +125,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxUndoManager undoManager = new mxUndoManager(); private final mxRubberband rubberband; + private final mxFastOrganicLayout fastOrganicLayout; private final mxCircleLayout circleLayout; private final mxOrganicLayout organicLayout; @@ -199,52 +193,40 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider @Override public void mouseClicked(final MouseEvent event) { super.mouseClicked(event); - if (SwingUtilities.isRightMouseButton(event)) { - final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY()); - if (cellAt != null && cellAt.isVertex()) { - final JPopupMenu jPopupMenu = new JPopupMenu(); - final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); + SwingUtilities.invokeLater(() -> { + if (SwingUtilities.isRightMouseButton(event)) { + final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY()); + if (cellAt != null && cellAt.isVertex()) { + final JPopupMenu jPopupMenu = new JPopupMenu(); + final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); - if (lockedVertexModel.isVertexLocked(cellAt)) { - jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock " + cellAt.getId(), unlockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.unlockVertex(cellAt); - } - })); - } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Lock " + cellAt.getId(), lockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.lockVertex(cellAt); - } - })); + if (lockedVertexModel.isVertexLocked(cellAt)) { + jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock", unlockIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.unlockVertex(cellAt); + } + })); + } else { + jPopupMenu.add(new JMenuItem(new AbstractAction("Lock", lockIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.lockVertex(cellAt); + } + })); + } + if (pinnedAccountModel.isAccountPinned(adiKey)) { + jPopupMenu.add(UnpinAccountsAction.getInstance().getPopupPresenter()); + } else { + jPopupMenu.add(PinAccountsAction.getInstance().getPopupPresenter()); + jPopupMenu.add(ResetAndPinAccountsAction.getInstance().getPopupPresenter()); + } + jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY()); } - if (pinnedAccountModel.isAccountPinned(adiKey)) { - jPopupMenu.add(new JMenuItem(new AbstractAction("Unpin " + cellAt.getId(), unpinIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - handleUnPinEvent(new CVTEvents.UnpinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()))); - } - })); - } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Pin " + cellAt.getId(), addPinIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), false)); - } - })); - jPopupMenu.add(new JMenuItem(new AbstractAction("Pin only " + cellAt.getId(), pinIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - handlePinEvent(new CVTEvents.PinAccountsEvent(singleton((AccountDeviceInstanceKey) cellAt.getValue()), true)); - } - })); - } - jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY()); } - } + }); } + }); final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM); @@ -255,7 +237,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider ExplorerUtils.createLookup(vizEM, getActionMap())); //feed selection to explorermanager - graph.getSelectionModel().addListener(null, new SelectionListener()); + graph.getSelectionModel().addListener(mxEvent.CHANGE, new SelectionListener()); final mxEventSource.mxIEventListener undoListener = (Object sender, mxEventObject evt) -> undoManager.undoableEditHappened((mxUndoableEdit) evt.getProperty("edit")); @@ -277,7 +259,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider rebuildGraph(); // Updates the display graph.getModel().endUpdate(); - } @Subscribe @@ -290,7 +271,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider rebuildGraph(); // Updates the display graph.getModel().endUpdate(); - } @Subscribe @@ -302,7 +282,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider rebuildGraph(); // Updates the display graph.getModel().endUpdate(); - } @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @@ -328,13 +307,12 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.resetGraph(); rebuildGraph(); } else { - morph(fastOrganicLayout); + morph(fastOrganicLayout); } } }); worker.execute(); - } } @@ -372,11 +350,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider }); } - @Override - public void removeNotify() { - super.removeNotify(); - } - /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -901,4 +874,5 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + } From a34cf8e53193d677a9bca655b4d3f424bbef52ed Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Thu, 5 Apr 2018 14:40:03 -0400 Subject: [PATCH 10/29] 3597: 5th test for file type filter test. --- .../autopsy/ingest/IngestFileFiltersTest.java | 78 ++++++++++++++++--- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java index 972c3488e8..ad51847434 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java @@ -48,6 +48,7 @@ import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ExtensionCon import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.FullNameCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition; +import org.sleuthkit.autopsy.modules.photoreccarver.PhotoRecCarverIngestModuleFactory; import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner; import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner.ProcessorCallback; import org.sleuthkit.autopsy.testutils.IngestJobRunner; @@ -133,11 +134,13 @@ public class IngestFileFiltersTest extends NbTestCase { HashMap rule = new HashMap<>(); rule.put("Rule", new Rule("testFileType", null, new MetaTypeCondition(MetaTypeCondition.Type.FILES), new ParentPathCondition("dir1"), null, null, null)); //Filter for dir1 and no unallocated space - FilesSet Files_Dirs_Unalloc_Ingest_Filter = new FilesSet("Filter", "Filter to find all files in dir1.", false, true, rule); + FilesSet dirFilter = new FilesSet("Filter", "Filter to find all files in dir1.", false, true, rule); try { Case openCase = Case.getOpenCase(); - runIngestJob(openCase.getDataSources(), Files_Dirs_Unalloc_Ingest_Filter); + ArrayList templates = new ArrayList<>(); + templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory())); + runIngestJob(openCase.getDataSources(), templates, dirFilter); FileManager fileManager = openCase.getServices().getFileManager(); List results = fileManager.findFiles("file.jpg", "dir1"); String mimeType = results.get(0).getMIMEType(); @@ -171,7 +174,9 @@ public class IngestFileFiltersTest extends NbTestCase { try { Case openCase = Case.getOpenCase(); - runIngestJob(openCase.getDataSources(), filesExtDirsFilter); + ArrayList templates = new ArrayList<>(); + templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory())); + runIngestJob(openCase.getDataSources(), templates, filesExtDirsFilter); FileManager fileManager = Case.getOpenCase().getServices().getFileManager(); List results = fileManager.findFiles("%%"); assertEquals(62, results.size()); @@ -200,7 +205,9 @@ public class IngestFileFiltersTest extends NbTestCase { try { Case openCase = Case.getOpenCase(); - runIngestJob(openCase.getDataSources(), filesExtDirsFilter); + ArrayList templates = new ArrayList<>(); + templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory())); + runIngestJob(openCase.getDataSources(), templates, filesExtDirsFilter); FileManager fileManager = Case.getOpenCase().getServices().getFileManager(); List results = fileManager.findFiles("%%"); assertEquals(62, results.size()); @@ -236,7 +243,10 @@ public class IngestFileFiltersTest extends NbTestCase { try { Case openCase = Case.getOpenCase(); - runIngestJob(openCase.getDataSources(), fullNameFilter); + ArrayList templates = new ArrayList<>(); + templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory())); + + runIngestJob(openCase.getDataSources(), templates, fullNameFilter); FileManager fileManager = Case.getOpenCase().getServices().getFileManager(); List results = fileManager.findFiles("%%"); assertEquals(62, results.size()); @@ -255,13 +265,51 @@ public class IngestFileFiltersTest extends NbTestCase { Assert.fail(ex); } } - private void runIngestJob(List datasources, FilesSet filter) { - FileTypeIdModuleFactory factory = new FileTypeIdModuleFactory(); - IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings(); - IngestModuleTemplate template = new IngestModuleTemplate(factory, settings); - template.setEnabled(true); - ArrayList templates = new ArrayList<>(); - templates.add(template); + + public void testCarvingWithExtRuleAndUnallocSpace() { + HashMap rules = new HashMap<>(); + rules.put("rule1", new Rule("FindJpgExtention", new ExtensionCondition("jpg"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null)); + rules.put("rule2", new Rule("FindGifExtention", new ExtensionCondition("gif"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null)); + + //Build the filter to find files with .jpg and .gif extension and unallocated space + FilesSet extensionFilter = new FilesSet("Filter", "Filter to files with .jpg and .gif extension.", false, false, rules); + + try { + Case openCase = Case.getOpenCase(); + ArrayList templates = new ArrayList<>(); + templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory())); + templates.add(getIngestModuleTemplate(new PhotoRecCarverIngestModuleFactory())); + runIngestJob(openCase.getDataSources(), templates, extensionFilter); + FileManager fileManager = Case.getOpenCase().getServices().getFileManager(); + List results = fileManager.findFiles("%%"); + assertEquals(70, results.size()); + int carvedJpgGifFiles = 0; + for (AbstractFile file : results) { + if (file.getNameExtension().equalsIgnoreCase("jpg") || file.getNameExtension().equalsIgnoreCase("gif")) { //Unalloc file and .jpg files in dir1, dir2, $CarvedFiles, root directory should have MIME type + String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId()); + assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty()); + + if (file.getParentPath().equalsIgnoreCase("/$CarvedFiles/")) { + carvedJpgGifFiles++; + } + } else if (file.getName().startsWith("Unalloc_")) { + String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId()); + assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty()); + } else { //All other files should not have MIME type. + String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId()); + assertTrue(errMsg, file.getMIMEType() == null); + } + } + //Make sure we have carved jpg/gif files + assertEquals(2, carvedJpgGifFiles); + + } catch (NoCurrentCaseException | TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + + private void runIngestJob(List datasources, ArrayList templates, FilesSet filter) { IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, filter); try { List errs = IngestJobRunner.runIngestJob(datasources, ingestJobSettings); @@ -275,4 +323,10 @@ public class IngestFileFiltersTest extends NbTestCase { } } + private IngestModuleTemplate getIngestModuleTemplate(IngestModuleFactoryAdapter factory) { + IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings(); + IngestModuleTemplate template = new IngestModuleTemplate(factory, settings); + template.setEnabled(true); + return template; + } } From 34106c0f72e1b6b8eff9c77552c2dc29de905a4a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 5 Apr 2018 14:55:25 -0400 Subject: [PATCH 11/29] Event subscribers now handled for all factory classes. --- .../sleuthkit/autopsy/datamodel/accounts/Accounts.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 3b6878ce23..a06d3eeeea 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -408,6 +408,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.addNotify(); } @@ -415,6 +416,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.removeNotify(); } @@ -569,6 +571,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.addNotify(); } @@ -576,6 +579,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.removeNotify(); } @@ -691,6 +695,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.addNotify(); } @@ -698,6 +703,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.removeNotify(); } @@ -901,6 +907,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.addNotify(); } @@ -908,6 +915,7 @@ final public class Accounts implements AutopsyVisitableItem { protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); + Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), pcl); super.removeNotify(); } From 37ed49b1b303d0a6da2888040dff2dbbd1f5e84f Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 6 Apr 2018 09:38:06 -0400 Subject: [PATCH 12/29] Switched from Java logger to Autopsy logger. --- .../casemodule/IngestJobInfoPanel.java | 3 +- .../AccountDeviceInstanceNodeFactory.java | 4 +- .../CoordinationService.java | 4 +- .../autopsy/datamodel/CreditCards.java | 10 +- .../autopsy/datamodel/accounts/Accounts.java | 2 +- .../FileSystemDetailsAction.java | 6 +- .../directorytree/FileSystemDetailsPanel.java | 4 +- .../ViewSourceArtifactAction.java | 2 +- .../ingest/IngestJobSettingsPanel.java | 2 +- .../autopsy/ingest/IngestMonitor.java | 10 +- .../autoingest/AutoIngestControlPanel.java | 22 +- .../autoingest/AutoIngestManager.java | 191 +++++++++--------- .../autoingest/AutoIngestSystemLogger.java | 12 +- .../autoingest/StatusDatabaseLogger.java | 76 +++---- .../autopsy/keywordsearch/KeywordSearch.java | 10 +- .../autopsy/testing/AutopsyTestCases.java | 4 +- .../autopsy/testing/RegressionTest.java | 6 +- 17 files changed, 186 insertions(+), 182 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index 8a496d8fac..e0b1ec8f01 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -25,12 +25,11 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.table.AbstractTableModel; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.datamodel.IngestJobInfo; import org.sleuthkit.datamodel.IngestModuleInfo; diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNodeFactory.java index 49ae86d62b..c0043d9ba1 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNodeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNodeFactory.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2017-18 Basis Technology Corp. + * Copyright 2017-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,9 +21,9 @@ package org.sleuthkit.autopsy.communications; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; -import java.util.logging.Logger; import org.openide.nodes.ChildFactory; import org.openide.nodes.Node; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; diff --git a/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java b/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java index 9b2afff6b4..f52ed088ae 100644 --- a/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java +++ b/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,8 +25,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.ThreadSafe; import org.apache.curator.RetryPolicy; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java b/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java index d353df6c88..7582846866 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/CreditCards.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,12 +25,12 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.Optional; import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.concurrent.GuardedBy; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; import org.apache.commons.lang3.StringUtils; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.datamodel.accounts.BINRange; @@ -108,7 +108,7 @@ public class CreditCards { Optional getScheme(); } - private static final Logger LOGGER = Logger.getLogger(CreditCards.class.getName()); + private static final Logger logger = Logger.getLogger(CreditCards.class.getName()); /** @@ -166,12 +166,12 @@ public class CreditCards { binRanges.put(Range.closed(binRange.getBINstart(), binRange.getBINend()), binRange); } catch (NumberFormatException numberFormatException) { - LOGGER.log(Level.WARNING, "Failed to parse BIN range: " + record.toString(), numberFormatException); //NON-NLS + logger.log(Level.WARNING, "Failed to parse BIN range: " + record.toString(), numberFormatException); //NON-NLS } binsLoaded = true; } } catch (IOException ex) { - LOGGER.log(Level.WARNING, "Failed to load BIN ranges form ranges.csv", ex); //NON-NLS + logger.log(Level.WARNING, "Failed to load BIN ranges form ranges.csv", ex); //NON-NLS MessageNotifyUtil.Notify.warn("Credit Card Number Discovery", "There was an error loading Bank Identification Number information. Accounts will not have their BINs identified."); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 3b6878ce23..72d2999a98 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -40,7 +40,6 @@ import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nonnull; @@ -60,6 +59,7 @@ import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.AutopsyItemVisitor; import org.sleuthkit.autopsy.datamodel.AutopsyVisitableItem; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java index a2c268a518..44d5fd91fc 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2017 Basis Technology Corp. + * Copyright 2017-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,17 +18,15 @@ */ package org.sleuthkit.autopsy.directorytree; -import java.awt.Dimension; -import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.JDialog; import javax.swing.JFrame; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Volume; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java index f896fa0dad..ce5b915b41 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.directorytree; import java.awt.event.ActionListener; import java.util.logging.Level; -import java.util.logging.Logger; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.FileSystem; import org.sleuthkit.datamodel.Volume; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewSourceArtifactAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewSourceArtifactAction.java index 04a2cccc2c..494908285b 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewSourceArtifactAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewSourceArtifactAction.java @@ -20,10 +20,10 @@ package org.sleuthkit.autopsy.directorytree; import java.awt.event.ActionEvent; import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.AbstractAction; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettingsPanel.java index 6a6d70677f..d03616d6f0 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobSettingsPanel.java @@ -27,7 +27,6 @@ import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.DefaultComboBoxModel; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -45,6 +44,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet; import org.sleuthkit.autopsy.modules.interestingitems.FilesSetDefsPanel; import org.sleuthkit.autopsy.modules.interestingitems.FilesSetPanel; diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java index e4c5c41340..1dc585a8f3 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java @@ -46,7 +46,7 @@ public final class IngestMonitor { public static final int DISK_FREE_SPACE_UNKNOWN = -1; private static final int INITIAL_INTERVAL_MS = 60000; //1 min. private static final int MAX_LOG_FILES = 3; - private static final java.util.logging.Logger MONITOR_LOGGER = java.util.logging.Logger.getLogger("monitor"); //NON-NLS + private static final java.util.logging.Logger monitorLogger = java.util.logging.Logger.getLogger("monitor"); //NON-NLS private final Logger logger = Logger.getLogger(IngestMonitor.class.getName()); private Timer timer; private MonitorTimerAction timerAction; @@ -63,8 +63,8 @@ public final class IngestMonitor { FileHandler monitorLogHandler = new FileHandler(PlatformUtil.getUserDirectory().getAbsolutePath() + "/var/log/monitor.log", 0, MAX_LOG_FILES); //NON-NLS monitorLogHandler.setFormatter(new SimpleFormatter()); monitorLogHandler.setEncoding(PlatformUtil.getLogFileEncoding()); - MONITOR_LOGGER.setUseParentHandlers(false); - MONITOR_LOGGER.addHandler(monitorLogHandler); + monitorLogger.setUseParentHandlers(false); + monitorLogger.addHandler(monitorLogHandler); } catch (IOException | SecurityException ex) { logger.log(Level.SEVERE, "Failed to create memory usage logger", ex); //NON-NLS } @@ -202,7 +202,7 @@ public final class IngestMonitor { IngestServices.getInstance().postMessage(IngestMessage.createManagerErrorMessage( NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.title", diskPath), NbBundle.getMessage(this.getClass(), "IngestMonitor.mgrErrMsg.lowDiskSpace.msg", diskPath))); - MONITOR_LOGGER.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS + monitorLogger.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS logger.log(Level.SEVERE, "Stopping ingest due to low disk space on {0}", diskPath); //NON-NLS } } @@ -211,7 +211,7 @@ public final class IngestMonitor { * Writes current message usage to the memory usage log. */ private void logMemoryUsage() { - MONITOR_LOGGER.log(Level.INFO, PlatformUtil.getAllMemUsageInfo()); + monitorLogger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo()); } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index d097882053..3b7d91331f 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -43,7 +43,6 @@ import java.io.File; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTable; @@ -60,6 +59,7 @@ import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.core.ServicesMonitor; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.NetworkUtils; import org.sleuthkit.autopsy.coreutils.PlatformUtil; @@ -141,7 +141,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { private static final int COMPLETED_TIME_COL_PREFERRED_WIDTH = 280; private static final String UPDATE_TASKS_THREAD_NAME = "AID-update-tasks-%d"; private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName(); - private static final Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger(); + private static final Logger sysLogger = AutoIngestSystemLogger.getLogger(); private static AutoIngestControlPanel instance; private final DefaultTableModel pendingTableModel; private final DefaultTableModel runningTableModel; @@ -333,7 +333,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { serviceStatus = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Down"); } } catch (ServicesMonitor.ServicesMonitorException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Dashboard error getting service status for %s", service), ex); + sysLogger.log(Level.SEVERE, String.format("Dashboard error getting service status for %s", service), ex); } return serviceStatus; } @@ -687,7 +687,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { manager.startUp(); autoIngestStarted = true; } catch (AutoIngestManager.AutoIngestManagerException ex) { - SYS_LOGGER.log(Level.SEVERE, "Dashboard error starting up auto ingest", ex); + sysLogger.log(Level.SEVERE, "Dashboard error starting up auto ingest", ex); tbStatusMessage.setText(NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.AutoIngestStartupError")); manager = null; @@ -712,7 +712,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { status = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Up"); } else if (status.equals(ServicesMonitor.ServiceStatus.DOWN.toString())) { status = NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.tbServicesStatusMessage.Message.Down"); - SYS_LOGGER.log(Level.SEVERE, "Connection to {0} is down", serviceDisplayName); //NON-NLS + sysLogger.log(Level.SEVERE, "Connection to {0} is down", serviceDisplayName); //NON-NLS } // if the status update is for an existing service who's status hasn't changed - do nothing. @@ -1187,7 +1187,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { job.getPriority()}); // PRIORITY } } catch (Exception ex) { - SYS_LOGGER.log(Level.SEVERE, "Dashboard error refreshing table", ex); + sysLogger.log(Level.SEVERE, "Dashboard error refreshing table", ex); } } @@ -1823,7 +1823,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { try { manager.prioritizeCase(caseName); } catch (AutoIngestManager.AutoIngestManagerException ex) { - SYS_LOGGER.log(Level.SEVERE, "Error prioritizing a case", ex); + sysLogger.log(Level.SEVERE, "Error prioritizing a case", ex); MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_casePrioritization()); } refreshTables(); @@ -1862,7 +1862,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { } } } catch (IOException ex) { - SYS_LOGGER.log(Level.SEVERE, "Dashboard error attempting to display case auto ingest log", ex); + sysLogger.log(Level.SEVERE, "Dashboard error attempting to display case auto ingest log", ex); Object[] options = {org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "DisplayLogDialog.okay")}; JOptionPane.showOptionDialog(this, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "DisplayLogDialog.cannotFindLog"), @@ -1883,7 +1883,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { try { manager.prioritizeJob(manifestFilePath); } catch (AutoIngestManager.AutoIngestManagerException ex) { - SYS_LOGGER.log(Level.SEVERE, "Error prioritizing a job", ex); + sysLogger.log(Level.SEVERE, "Error prioritizing a job", ex); MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_jobPrioritization()); } refreshTables(); @@ -1930,7 +1930,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { try { manager.deprioritizeCase(caseName); } catch (AutoIngestManager.AutoIngestManagerException ex) { - SYS_LOGGER.log(Level.SEVERE, "Error deprioritizing a case", ex); + sysLogger.log(Level.SEVERE, "Error deprioritizing a case", ex); MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_caseDeprioritization()); } refreshTables(); @@ -1949,7 +1949,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { try { manager.deprioritizeJob(manifestFilePath); } catch (AutoIngestManager.AutoIngestManagerException ex) { - SYS_LOGGER.log(Level.SEVERE, "Error deprioritizing a job", ex); + sysLogger.log(Level.SEVERE, "Error deprioritizing a job", ex); MessageNotifyUtil.Message.error(Bundle.AutoIngestControlPanel_errorMessage_jobDeprioritization()); } refreshTables(); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index cc162494ae..8a1228cde4 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -76,6 +76,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult; import static org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.NetworkUtils; import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEventException; @@ -137,7 +138,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private static final String JOB_STATUS_PUBLISHING_THREAD_NAME = "AIM-job-status-event-publisher-%d"; private static final long MAX_MISSED_JOB_STATUS_UPDATES = 10; private static final int DEFAULT_PRIORITY = 0; - private static final java.util.logging.Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger(); + private static final Logger sysLogger = AutoIngestSystemLogger.getLogger(); private static AutoIngestManager instance; private final AutopsyEventPublisher eventPublisher; private final Object scanMonitor; @@ -184,7 +185,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * designated input directory tree. */ private AutoIngestManager() { - SYS_LOGGER.log(Level.INFO, "Initializing auto ingest"); + sysLogger.log(Level.INFO, "Initializing auto ingest"); state = State.IDLE; eventPublisher = new AutopsyEventPublisher(); scanMonitor = new Object(); @@ -200,9 +201,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen completedJobs = new ArrayList<>(); try { RuntimeProperties.setRunningWithGUI(false); - SYS_LOGGER.log(Level.INFO, "Set running with desktop GUI runtime property to false"); + sysLogger.log(Level.INFO, "Set running with desktop GUI runtime property to false"); } catch (RuntimeProperties.RuntimePropertiesException ex) { - SYS_LOGGER.log(Level.SEVERE, "Failed to set running with desktop GUI runtime property to false", ex); + sysLogger.log(Level.SEVERE, "Failed to set running with desktop GUI runtime property to false", ex); } } @@ -213,7 +214,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * ingest. */ void startUp() throws AutoIngestManagerException { - SYS_LOGGER.log(Level.INFO, "Auto ingest starting"); + sysLogger.log(Level.INFO, "Auto ingest starting"); try { coordinationService = CoordinationService.getInstance(); } catch (CoordinationServiceException ex) { @@ -221,9 +222,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } try { eventPublisher.openRemoteEventChannel(EVENT_CHANNEL_NAME); - SYS_LOGGER.log(Level.INFO, "Opened auto ingest event channel"); + sysLogger.log(Level.INFO, "Opened auto ingest event channel"); } catch (AutopsyEventException ex) { - SYS_LOGGER.log(Level.SEVERE, "Failed to open auto ingest event channel", ex); + sysLogger.log(Level.SEVERE, "Failed to open auto ingest event channel", ex); throw new AutoIngestManagerException("Failed to open auto ingest event channel", ex); } rootInputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeImageFolder()); @@ -396,7 +397,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (State.RUNNING != state) { return; } - SYS_LOGGER.log(Level.INFO, "Auto ingest shutting down"); + sysLogger.log(Level.INFO, "Auto ingest shutting down"); state = State.SHUTTING_DOWN; try { eventPublisher.removeSubscriber(EVENT_LIST, instance); @@ -406,9 +407,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen cleanupJobs(); } catch (InterruptedException ex) { - SYS_LOGGER.log(Level.SEVERE, "Auto ingest interrupted during shut down", ex); + sysLogger.log(Level.SEVERE, "Auto ingest interrupted during shut down", ex); } - SYS_LOGGER.log(Level.INFO, "Auto ingest shut down"); + sysLogger.log(Level.INFO, "Auto ingest shut down"); state = State.IDLE; } @@ -420,10 +421,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen inputScanSchedulingExecutor.shutdownNow(); inputScanExecutor.shutdownNow(); while (!inputScanSchedulingExecutor.awaitTermination(30, TimeUnit.SECONDS)) { - SYS_LOGGER.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan scheduling executor to shut down, continuing to wait"); //NON-NLS + sysLogger.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan scheduling executor to shut down, continuing to wait"); //NON-NLS } while (!inputScanExecutor.awaitTermination(30, TimeUnit.SECONDS)) { - SYS_LOGGER.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan executor to shut down, continuing to wait"); //NON-NLS + sysLogger.log(Level.WARNING, "Auto ingest waited at least thirty seconds for input scan executor to shut down, continuing to wait"); //NON-NLS } } @@ -439,7 +440,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen jobProcessingExecutor.shutdown(); } while (!jobProcessingExecutor.awaitTermination(30, TimeUnit.SECONDS)) { - SYS_LOGGER.log(Level.WARNING, "Auto ingest waited at least thirty seconds for job processing executor to shut down, continuing to wait"); //NON-NLS + sysLogger.log(Level.WARNING, "Auto ingest waited at least thirty seconds for job processing executor to shut down, continuing to wait"); //NON-NLS } } @@ -506,11 +507,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (State.RUNNING != state) { return; } - SYS_LOGGER.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory); + sysLogger.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory); InputDirScanner scanner = new InputDirScanner(); scanner.scan(); - SYS_LOGGER.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory); + sysLogger.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory); } /** @@ -772,10 +773,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen updateCoordinationServiceManifestNode(completedJob); pendingJobs.add(completedJob); } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Coordination service error while reprocessing %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Coordination service error while reprocessing %s", manifestPath), ex); completedJobs.add(completedJob); } catch (InterruptedException ex) { - SYS_LOGGER.log(Level.SEVERE, "Unexpected interrupt while updating coordination service node data for {0}", manifestPath); + sysLogger.log(Level.SEVERE, "Unexpected interrupt while updating coordination service node data for {0}", manifestPath); completedJobs.add(completedJob); } } @@ -811,7 +812,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { metaData = new CaseMetadata(caseMetaDataFilePath); } catch (CaseMetadata.CaseMetadataException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Failed to get case metadata file %s for case %s at %s", caseMetaDataFilePath, caseName, caseDirectoryPath), ex); + sysLogger.log(Level.SEVERE, String.format("Failed to get case metadata file %s for case %s at %s", caseMetaDataFilePath, caseName, caseDirectoryPath), ex); return CaseDeletionResult.FAILED; } @@ -822,7 +823,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen scanner.scan(); Set manifestPaths = casesToManifests.get(caseName); if (null == manifestPaths) { - SYS_LOGGER.log(Level.SEVERE, String.format("No manifest paths found for case %s at %s", caseName, caseDirectoryPath)); + sysLogger.log(Level.SEVERE, String.format("No manifest paths found for case %s at %s", caseName, caseDirectoryPath)); return CaseDeletionResult.FAILED; } @@ -840,7 +841,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen return CaseDeletionResult.FAILED; } } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to acquire manifest lock for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to acquire manifest lock for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex); return CaseDeletionResult.FAILED; } } @@ -851,7 +852,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ Case.deleteCase(metaData); } catch (CaseActionException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Failed to physically delete case %s at %s", caseName, caseDirectoryPath), ex); + sysLogger.log(Level.SEVERE, String.format("Failed to physically delete case %s at %s", caseName, caseDirectoryPath), ex); return CaseDeletionResult.FAILED; } @@ -865,10 +866,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen deletedJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.DELETED); this.updateCoordinationServiceManifestNode(deletedJob); } catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) { - SYS_LOGGER.log(Level.WARNING, String.format("Invalid auto ingest job node data for %s", manifestPath), ex); + sysLogger.log(Level.WARNING, String.format("Invalid auto ingest job node data for %s", manifestPath), ex); return CaseDeletionResult.PARTIALLY_DELETED; } catch (InterruptedException | CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set delete flag on manifest data for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to set delete flag on manifest data for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex); return CaseDeletionResult.PARTIALLY_DELETED; } } @@ -895,7 +896,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { lock.release(); } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Failed to release manifest file lock when deleting case %s at %s", caseName, caseDirectoryPath), ex); + sysLogger.log(Level.SEVERE, String.format("Failed to release manifest file lock when deleting case %s at %s", caseName, caseDirectoryPath), ex); } } } @@ -944,7 +945,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen synchronized (jobsLock) { if (null != currentJob) { currentJob.cancel(); - SYS_LOGGER.log(Level.INFO, "Cancelling automated ingest for manifest {0}", currentJob.getManifest().getFilePath()); + sysLogger.log(Level.INFO, "Cancelling automated ingest for manifest {0}", currentJob.getManifest().getFilePath()); } } } @@ -965,7 +966,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (null != moduleHandle) { currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE, Date.from(Instant.now())); moduleHandle.cancel(); - SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()}); + sysLogger.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()}); } } } @@ -1015,7 +1016,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * input directory scan task executor. */ private InputDirScanSchedulingTask() { - SYS_LOGGER.log(Level.INFO, "Periodic input scan scheduling task started"); + sysLogger.log(Level.INFO, "Periodic input scan scheduling task started"); } /** @@ -1045,10 +1046,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (Thread.currentThread().isInterrupted()) { return null; } - SYS_LOGGER.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory); + sysLogger.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory); InputDirScanner scanner = new InputDirScanner(); scanner.scan(); - SYS_LOGGER.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory); + sysLogger.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory); setChanged(); notifyObservers(Event.INPUT_SCAN_COMPLETED); return null; @@ -1090,7 +1091,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * uncaught exceptions will propagate up to the calling * thread and may stop it from running. */ - SYS_LOGGER.log(Level.SEVERE, String.format("Error scanning the input directory %s", rootInputDirectory), ex); + sysLogger.log(Level.SEVERE, String.format("Error scanning the input directory %s", rootInputDirectory), ex); } } synchronized (scanMonitor) { @@ -1151,7 +1152,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen manifest = parser.parse(filePath); break; } catch (ManifestFileParserException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to parse %s with parser %s", filePath, parser.getClass().getCanonicalName()), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to parse %s with parser %s", filePath, parser.getClass().getCanonicalName()), ex); } } if (Thread.currentThread().isInterrupted()) { @@ -1205,21 +1206,21 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ break; default: - SYS_LOGGER.log(Level.SEVERE, "Unknown ManifestNodeData.ProcessingStatus"); + sysLogger.log(Level.SEVERE, "Unknown ManifestNodeData.ProcessingStatus"); break; } } catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Invalid auto ingest job node data for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Invalid auto ingest job node data for %s", manifestPath), ex); } } else { try { addNewPendingJob(manifest); } catch (AutoIngestJobException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Invalid manifest data for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Invalid manifest data for %s", manifestPath), ex); } } } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error transmitting node data for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error transmitting node data for %s", manifestPath), ex); return CONTINUE; } catch (InterruptedException ex) { Thread.currentThread().interrupt(); @@ -1231,7 +1232,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen // Catch all unhandled and unexpected exceptions. Otherwise one bad file // can stop the entire input folder scanning. Given that the exception is unexpected, // I'm hesitant to add logging which requires accessing or de-referencing data. - SYS_LOGGER.log(Level.SEVERE, "Unexpected exception in file visitor", ex); + sysLogger.log(Level.SEVERE, "Unexpected exception in file visitor", ex); return CONTINUE; } @@ -1288,7 +1289,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen updateCoordinationServiceManifestNode(job); } } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex); } } Path caseDirectory = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); @@ -1330,7 +1331,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen newPendingJobsList.add(job); } } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex); } } @@ -1361,7 +1362,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen String manifestPath = manifest.getFilePath().toString(); try (Lock manifestLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.MANIFESTS, manifestPath)) { if (null != manifestLock) { - SYS_LOGGER.log(Level.SEVERE, "Attempting crash recovery for {0}", manifestPath); + sysLogger.log(Level.SEVERE, "Attempting crash recovery for {0}", manifestPath); try { Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); @@ -1386,7 +1387,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { setCaseNodeDataErrorsOccurred(caseDirectoryPath); } catch (CaseNodeData.InvalidDataException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to get case node data for %s", caseDirectoryPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to get case node data for %s", caseDirectoryPath), ex); } } else { job.setErrorsOccurred(false); @@ -1398,7 +1399,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryWithRetry(); } catch (AutoIngestJobLoggerException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex); } } } else { @@ -1407,7 +1408,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryNoRetry(); } catch (AutoIngestJobLoggerException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex); } } } @@ -1419,7 +1420,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { updateCoordinationServiceManifestNode(job); } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifestPath), ex); return; } @@ -1435,12 +1436,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { manifestLock.release(); } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to release exclusive lock for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to release exclusive lock for %s", manifestPath), ex); } } } } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to get exclusive lock for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to get exclusive lock for %s", manifestPath), ex); } } @@ -1495,13 +1496,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen updateCoordinationServiceManifestNode(job); } } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex); + sysLogger.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifest.getFilePath()), ex); } } newCompletedJobsList.add(job); } else { - SYS_LOGGER.log(Level.WARNING, String.format("Job completed for %s, but cannot find case directory, ignoring job", nodeData.getManifestFilePath())); + sysLogger.log(Level.WARNING, String.format("Job completed for %s, but cannot find case directory, ignoring job", nodeData.getManifestFilePath())); } } @@ -1522,7 +1523,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ @Override public FileVisitResult visitFileFailed(Path file, IOException ex) throws IOException { - SYS_LOGGER.log(Level.SEVERE, String.format("Error while visiting %s during input directories scan", file.toString()), ex); + sysLogger.log(Level.SEVERE, String.format("Error while visiting %s during input directories scan", file.toString()), ex); if (Thread.currentThread().isInterrupted()) { return TERMINATE; } @@ -1607,7 +1608,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ @Override public void run() { - SYS_LOGGER.log(Level.INFO, "Job processing task started"); + sysLogger.log(Level.INFO, "Job processing task started"); while (true) { try { if (jobProcessingTaskFuture.isCancelled()) { @@ -1650,14 +1651,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } else { errorState = ErrorState.UNEXPECTED_EXCEPTION; } - SYS_LOGGER.log(Level.SEVERE, "Auto ingest system error", ex); + sysLogger.log(Level.SEVERE, "Auto ingest system error", ex); pauseForSystemError(); } } catch (InterruptedException ex) { break; } } - SYS_LOGGER.log(Level.INFO, "Job processing task stopped"); + sysLogger.log(Level.INFO, "Job processing task stopped"); } /** @@ -1666,7 +1667,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ private void requestPause() { synchronized (pauseLock) { - SYS_LOGGER.log(Level.INFO, "Job processing pause requested"); + sysLogger.log(Level.INFO, "Job processing pause requested"); pauseRequested = true; if (waitingForInputScan) { /* @@ -1689,7 +1690,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ private void requestResume() { synchronized (pauseLock) { - SYS_LOGGER.log(Level.INFO, "Job processing resume requested"); + sysLogger.log(Level.INFO, "Job processing resume requested"); pauseRequested = false; if (waitingForInputScan) { /* @@ -1719,12 +1720,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private void pauseIfRequested() throws InterruptedException { synchronized (pauseLock) { if (pauseRequested) { - SYS_LOGGER.log(Level.INFO, "Job processing paused by request"); + sysLogger.log(Level.INFO, "Job processing paused by request"); pauseRequested = false; setChanged(); notifyObservers(Event.PAUSED_BY_REQUEST); pauseLock.wait(); - SYS_LOGGER.log(Level.INFO, "Job processing resumed after pause request"); + sysLogger.log(Level.INFO, "Job processing resumed after pause request"); setChanged(); notifyObservers(Event.RESUMED); } @@ -1740,12 +1741,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ private void pauseForSystemError() throws InterruptedException { synchronized (pauseLock) { - SYS_LOGGER.log(Level.SEVERE, "Job processing paused for system error"); + sysLogger.log(Level.SEVERE, "Job processing paused for system error"); setChanged(); notifyObservers(Event.PAUSED_FOR_SYSTEM_ERROR); pauseLock.wait(); errorState = ErrorState.NONE; - SYS_LOGGER.log(Level.INFO, "Job processing resumed after system error"); + sysLogger.log(Level.INFO, "Job processing resumed after system error"); setChanged(); notifyObservers(Event.RESUMED); } @@ -1775,11 +1776,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ waitingForInputScan = true; } - SYS_LOGGER.log(Level.INFO, "Job processing waiting for input scan completion"); + sysLogger.log(Level.INFO, "Job processing waiting for input scan completion"); synchronized (scanMonitor) { scanMonitor.wait(); } - SYS_LOGGER.log(Level.INFO, "Job processing finished wait for input scan completion"); + sysLogger.log(Level.INFO, "Job processing finished wait for input scan completion"); synchronized (pauseLock) { waitingForInputScan = false; pauseIfRequested(); @@ -1845,7 +1846,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * job. */ private void processJobs() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, AutoIngestJobNodeData.InvalidDataException, CaseNodeData.InvalidDataException, JobMetricsCollectionException { - SYS_LOGGER.log(Level.INFO, "Started processing pending jobs queue"); + sysLogger.log(Level.INFO, "Started processing pending jobs queue"); Lock manifestLock = JobProcessingTask.this.dequeueAndLockNextJob(); while (null != manifestLock) { try { @@ -1895,20 +1896,20 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * while reading the lock data */ private Lock dequeueAndLockNextJob() throws CoordinationServiceException, InterruptedException { - SYS_LOGGER.log(Level.INFO, "Checking pending jobs queue for ready job, enforcing max jobs per case"); + sysLogger.log(Level.INFO, "Checking pending jobs queue for ready job, enforcing max jobs per case"); Lock manifestLock; synchronized (jobsLock) { manifestLock = dequeueAndLockNextJob(true); if (null != manifestLock) { - SYS_LOGGER.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath()); + sysLogger.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath()); } else { - SYS_LOGGER.log(Level.INFO, "No ready job"); - SYS_LOGGER.log(Level.INFO, "Checking pending jobs queue for ready job, not enforcing max jobs per case"); + sysLogger.log(Level.INFO, "No ready job"); + sysLogger.log(Level.INFO, "Checking pending jobs queue for ready job, not enforcing max jobs per case"); manifestLock = dequeueAndLockNextJob(false); if (null != manifestLock) { - SYS_LOGGER.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath()); + sysLogger.log(Level.INFO, "Dequeued job for {0}", currentJob.getManifest().getFilePath()); } else { - SYS_LOGGER.log(Level.INFO, "No ready job"); + sysLogger.log(Level.INFO, "No ready job"); } } } @@ -1980,7 +1981,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen currentJob = job; break; } catch (AutoIngestJobNodeData.InvalidDataException ex) { - SYS_LOGGER.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex); // JCTODO: Is this right? + sysLogger.log(Level.WARNING, String.format("Unable to use node data for %s", manifestPath), ex); // JCTODO: Is this right? } } } @@ -2047,7 +2048,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ private void processJob() throws CoordinationServiceException, SharedConfigurationException, ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException, CaseManagementException, AnalysisStartupException, FileExportException, AutoIngestJobLoggerException, InterruptedException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, CaseNodeData.InvalidDataException, JobMetricsCollectionException { Path manifestPath = currentJob.getManifest().getFilePath(); - SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath); + sysLogger.log(Level.INFO, "Started processing of {0}", manifestPath); currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING); currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING, Date.from(Instant.now())); currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME); @@ -2078,7 +2079,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen updateCoordinationServiceManifestNode(currentJob); boolean retry = (!currentJob.isCanceled() && !currentJob.isCompleted()); - SYS_LOGGER.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry}); + sysLogger.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry}); if (currentJob.isCanceled()) { Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); if (null != caseDirectoryPath) { @@ -2173,7 +2174,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private void updateConfiguration() throws SharedConfigurationException, InterruptedException { if (AutoIngestUserPreferences.getSharedConfigEnabled()) { Path manifestPath = currentJob.getManifest().getFilePath(); - SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath); + sysLogger.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath); currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now())); new SharedConfiguration().downloadConfiguration(); } @@ -2191,7 +2192,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException { Path manifestPath = currentJob.getManifest().getFilePath(); - SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath); + sysLogger.log(Level.INFO, "Checking services availability for {0}", manifestPath); currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES, Date.from(Instant.now())); if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) { throw new DatabaseServerDownException("Case database server is down"); @@ -2238,7 +2239,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private Case openCase() throws CoordinationServiceException, CaseManagementException, InterruptedException { Manifest manifest = currentJob.getManifest(); String caseName = manifest.getCaseName(); - SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()}); + sysLogger.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()}); currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE, Date.from(Instant.now())); /* * Acquire and hold a case name lock so that only one node at as @@ -2272,7 +2273,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } currentJob.setCaseDirectoryPath(caseDirectoryPath); Case caseForJob = Case.getOpenCase(); - SYS_LOGGER.log(Level.INFO, "Opened case {0} for {1}", new Object[]{caseForJob.getName(), manifest.getFilePath()}); + sysLogger.log(Level.INFO, "Opened case {0} for {1}", new Object[]{caseForJob.getName(), manifest.getFilePath()}); return caseForJob; } catch (KeywordSearchModuleException ex) { @@ -2417,14 +2418,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private AutoIngestDataSource identifyDataSource() throws AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException { Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); - SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath); + sysLogger.log(Level.INFO, "Identifying data source for {0} ", manifestPath); currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE, Date.from(Instant.now())); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); Path dataSourcePath = manifest.getDataSourcePath(); File dataSource = dataSourcePath.toFile(); if (!dataSource.exists()) { - SYS_LOGGER.log(Level.SEVERE, "Missing data source for {0}", manifestPath); + sysLogger.log(Level.SEVERE, "Missing data source for {0}", manifestPath); currentJob.setErrorsOccurred(true); setCaseNodeDataErrorsOccurred(caseDirectoryPath); jobLogger.logMissingDataSource(); @@ -2451,7 +2452,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private void runDataSourceProcessor(Case caseForJob, AutoIngestDataSource dataSource) throws InterruptedException, AutoIngestJobLoggerException, AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException, CaseNodeData.InvalidDataException, CoordinationServiceException { Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); - SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath); + sysLogger.log(Level.INFO, "Adding data source for {0} ", manifestPath); currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE, Date.from(Instant.now())); DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor(); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); @@ -2463,7 +2464,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { validDataSourceProcessors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(dataSource.getPath()); } catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) { - SYS_LOGGER.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath()); + sysLogger.log(Level.SEVERE, "Exception while determining best data source processor for {0}", dataSource.getPath()); // rethrow the exception. It will get caught & handled upstream and will result in AIM auto-pause. throw ex; } @@ -2474,7 +2475,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen setCaseNodeDataErrorsOccurred(caseDirectoryPath); currentJob.setErrorsOccurred(true); jobLogger.logFailedToIdentifyDataSource(); - SYS_LOGGER.log(Level.WARNING, "Unsupported data source {0} for {1}", new Object[]{dataSource.getPath(), manifestPath}); // NON-NLS + sysLogger.log(Level.WARNING, "Unsupported data source {0} for {1}", new Object[]{dataSource.getPath(), manifestPath}); // NON-NLS return; } @@ -2486,7 +2487,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId, ingestLock); caseForJob.notifyAddingDataSource(taskId); jobLogger.logDataSourceProcessorSelected(selectedProcessor.getDataSourceType()); - SYS_LOGGER.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()}); + sysLogger.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()}); selectedProcessor.process(dataSource.getDeviceId(), dataSource.getPath(), progressMonitor, callBack); ingestLock.wait(); @@ -2504,7 +2505,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen return; } // If we get to this point, none of the processors were successful - SYS_LOGGER.log(Level.SEVERE, "All data source processors failed to process {0}", dataSource.getPath()); + sysLogger.log(Level.SEVERE, "All data source processors failed to process {0}", dataSource.getPath()); jobLogger.logFailedToAddDataSource(); setCaseNodeDataErrorsOccurred(caseDirectoryPath); currentJob.setErrorsOccurred(true); @@ -2547,7 +2548,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen case NONCRITICAL_ERRORS: for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) { - SYS_LOGGER.log(Level.WARNING, "Non-critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage}); + sysLogger.log(Level.WARNING, "Non-critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage}); } jobLogger.logDataSourceAdded(); if (dataSource.getContent().isEmpty()) { @@ -2557,7 +2558,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen case CRITICAL_ERRORS: for (String errorMessage : dataSource.getDataSourceProcessorErrorMessages()) { - SYS_LOGGER.log(Level.SEVERE, "Critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage}); + sysLogger.log(Level.SEVERE, "Critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage}); } jobLogger.logFailedToAddDataSource(); break; @@ -2570,7 +2571,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * AutoIngestJob and calling cancel on the DSP, if not null, in * cancelCurrentJob. */ - SYS_LOGGER.log(Level.WARNING, "Cancellation while waiting for data source processor for {0}", manifestPath); + sysLogger.log(Level.WARNING, "Cancellation while waiting for data source processor for {0}", manifestPath); jobLogger.logDataSourceProcessorCancelled(); } } @@ -2595,7 +2596,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private void analyze(AutoIngestDataSource dataSource) throws AnalysisStartupException, AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException { Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); - SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath); + sysLogger.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath); currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE, Date.from(Instant.now())); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); @@ -2616,17 +2617,17 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * is shutting down. */ ingestLock.wait(); - SYS_LOGGER.log(Level.INFO, "Finished ingest modules analysis for {0} ", manifestPath); + sysLogger.log(Level.INFO, "Finished ingest modules analysis for {0} ", manifestPath); IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot(); for (IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot : jobSnapshot.getDataSourceSnapshots()) { if (!snapshot.isCancelled()) { List cancelledModules = snapshot.getCancelledDataSourceIngestModules(); if (!cancelledModules.isEmpty()) { - SYS_LOGGER.log(Level.WARNING, String.format("Ingest module(s) cancelled for %s", manifestPath)); + sysLogger.log(Level.WARNING, String.format("Ingest module(s) cancelled for %s", manifestPath)); currentJob.setErrorsOccurred(true); setCaseNodeDataErrorsOccurred(caseDirectoryPath); for (String module : snapshot.getCancelledDataSourceIngestModules()) { - SYS_LOGGER.log(Level.WARNING, String.format("%s ingest module cancelled for %s", module, manifestPath)); + sysLogger.log(Level.WARNING, String.format("%s ingest module cancelled for %s", module, manifestPath)); jobLogger.logIngestModuleCancelled(module); } } @@ -2644,14 +2645,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } } else if (!ingestJobStartResult.getModuleErrors().isEmpty()) { for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) { - SYS_LOGGER.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable()); + sysLogger.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable()); } currentJob.setErrorsOccurred(true); setCaseNodeDataErrorsOccurred(caseDirectoryPath); jobLogger.logIngestModuleStartupErrors(); throw new AnalysisStartupException(String.format("Error(s) during ingest module startup for %s", manifestPath)); } else { - SYS_LOGGER.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException()); + sysLogger.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException()); currentJob.setErrorsOccurred(true); setCaseNodeDataErrorsOccurred(caseDirectoryPath); jobLogger.logAnalysisStartupError(); @@ -2659,7 +2660,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } } else { for (String warning : settingsWarnings) { - SYS_LOGGER.log(Level.SEVERE, "Ingest job settings error for {0}: {1}", new Object[]{manifestPath, warning}); + sysLogger.log(Level.SEVERE, "Ingest job settings error for {0}: {1}", new Object[]{manifestPath, warning}); } currentJob.setErrorsOccurred(true); setCaseNodeDataErrorsOccurred(caseDirectoryPath); @@ -2732,7 +2733,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private void exportFiles(AutoIngestDataSource dataSource) throws FileExportException, AutoIngestJobLoggerException, InterruptedException, CaseNodeData.InvalidDataException, CoordinationServiceException { Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); - SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath); + sysLogger.log(Level.INFO, "Exporting files for {0}", manifestPath); currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES, Date.from(Instant.now())); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); @@ -2743,7 +2744,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen jobLogger.logFileExportCompleted(); } } catch (FileExportException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error doing file export for %s", manifestPath), ex); + sysLogger.log(Level.SEVERE, String.format("Error doing file export for %s", manifestPath), ex); currentJob.setErrorsOccurred(true); setCaseNodeDataErrorsOccurred(caseDirectoryPath); jobLogger.logFileExportError(); @@ -2916,7 +2917,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private final long MAX_SECONDS_WITHOUT_UPDATE = JOB_STATUS_EVENT_INTERVAL_SECONDS * MAX_MISSED_JOB_STATUS_UPDATES; private PeriodicJobStatusEventTask() { - SYS_LOGGER.log(Level.INFO, "Periodic status publishing task started"); + sysLogger.log(Level.INFO, "Periodic status publishing task started"); } @Override @@ -2949,7 +2950,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen try { StatusDatabaseLogger.logToStatusDatabase(message, isError); } catch (SQLException | UserPreferencesException ex) { - SYS_LOGGER.log(Level.WARNING, "Failed to update status database", ex); + sysLogger.log(Level.WARNING, "Failed to update status database", ex); } } } @@ -2975,7 +2976,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } } catch (Exception ex) { - SYS_LOGGER.log(Level.SEVERE, "Unexpected exception in PeriodicJobStatusEventTask", ex); //NON-NLS + sysLogger.log(Level.SEVERE, "Unexpected exception in PeriodicJobStatusEventTask", ex); //NON-NLS } } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestSystemLogger.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestSystemLogger.java index 184d5d350a..33c3c20c23 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestSystemLogger.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestSystemLogger.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2015 Basis Technology Corp. + * Copyright 2015-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,8 +25,8 @@ import java.sql.Timestamp; import java.util.logging.FileHandler; import java.util.logging.Formatter; import java.util.logging.LogRecord; -import java.util.logging.Logger; import javax.annotation.concurrent.GuardedBy; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; /** @@ -37,7 +37,7 @@ final class AutoIngestSystemLogger { private static final int LOG_SIZE = 50000000; // In bytes, zero is unlimited, set to roughly 10mb currently private static final int LOG_FILE_COUNT = 10; - private static final Logger LOGGER = Logger.getLogger("AutoIngest"); //NON-NLS + private static final Logger logger = Logger.getLogger("AutoIngest"); //NON-NLS private static final String NEWLINE = System.lineSeparator(); @GuardedBy("AutoIngestSystemLogger") private static boolean configured; @@ -74,14 +74,14 @@ final class AutoIngestSystemLogger { + stackTrace; } }); - LOGGER.addHandler(fileHandler); - LOGGER.setUseParentHandlers(false); + logger.addHandler(fileHandler); + logger.setUseParentHandlers(false); } catch (SecurityException | IOException ex) { throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS } configured = true; } - return LOGGER; + return logger; } /** diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/StatusDatabaseLogger.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/StatusDatabaseLogger.java index 2fa6db1457..f8921e112d 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/StatusDatabaseLogger.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/StatusDatabaseLogger.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2015 Basis Technology Corp. + * Copyright 2015-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,6 +26,7 @@ import java.sql.Statement; import java.util.logging.Level; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferencesException; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.NetworkUtils; import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences; @@ -33,72 +34,79 @@ import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreference * Write auto-ingest status updates to a database. */ public class StatusDatabaseLogger { + /** - * Log the current status to the database using the database - * parameters saved in AutoIngestUserPreferences. - * @param message Current status message - * @param isError true if we're in an error state, false otherwise - * @throws SQLException + * Log the current status to the database using the database parameters + * saved in AutoIngestUserPreferences. + * + * @param message Current status message + * @param isError true if we're in an error state, false otherwise + * + * @throws SQLException If a SQL data access error occurs. + * @throws UserPreferencesException If there's an issue reading the user + * preferences. */ - public static void logToStatusDatabase(String message, boolean isError) throws SQLException, UserPreferencesException{ - - try{ + public static void logToStatusDatabase(String message, boolean isError) throws SQLException, UserPreferencesException { + + try { Class.forName("org.postgresql.Driver"); - } catch (ClassNotFoundException ex){ - java.util.logging.Logger SYS_LOGGER = AutoIngestSystemLogger.getLogger(); - SYS_LOGGER.log(Level.WARNING, "Error loading postgresql driver", ex); + } catch (ClassNotFoundException ex) { + Logger sysLogger = AutoIngestSystemLogger.getLogger(); + sysLogger.log(Level.WARNING, "Error loading postgresql driver", ex); } - try (Connection connection = DriverManager.getConnection("jdbc:postgresql://" + try (Connection connection = DriverManager.getConnection("jdbc:postgresql://" + AutoIngestUserPreferences.getLoggingDatabaseHostnameOrIP() + ":" + AutoIngestUserPreferences.getLoggingPort() + "/" + AutoIngestUserPreferences.getLoggingDatabaseName(), - AutoIngestUserPreferences.getLoggingUsername(), + AutoIngestUserPreferences.getLoggingUsername(), AutoIngestUserPreferences.getLoggingPassword()); Statement statement = connection.createStatement();) { logToStatusDatabase(statement, message, isError); } } - + /** - * Log the current status to the database using an already - * configured Statement. + * Log the current status to the database using an already configured + * Statement. + * * @param statement SQL statement (must have already been created) * @param message Current status message * @param isError true if we're in an error state, false otherwise - * @throws SQLException + * + * @throws SQLException */ - public static void logToStatusDatabase(Statement statement, String message, boolean isError) throws SQLException{ - if((statement == null) || statement.isClosed()){ + public static void logToStatusDatabase(Statement statement, String message, boolean isError) throws SQLException { + if ((statement == null) || statement.isClosed()) { throw new SQLException("SQL Statement is null/closed"); } - + int status; - if(isError){ + if (isError) { status = 1; } else { status = 0; } - String timestamp = new java.text.SimpleDate‌​Format("yyyy-MM-dd HH:mm:ss").format(ne‌​w java.util.Date()); + String timestamp = new java.text.SimpleDate‌​Format("yyyy-MM-dd HH:mm:ss").format( ne‌​w java.util.Date()); - String checkForPreviousEntry = "SELECT * FROM statusUpdates WHERE tool='" + UserPreferences.getAppName() + "' AND " + - "node='" + NetworkUtils.getLocalHostName() + "'"; + String checkForPreviousEntry = "SELECT * FROM statusUpdates WHERE tool='" + UserPreferences.getAppName() + "' AND " + + "node='" + NetworkUtils.getLocalHostName() + "'"; ResultSet resultSet = statement.executeQuery(checkForPreviousEntry); String logMessage; - if(resultSet.next()){ - logMessage = "UPDATE statusUpdates SET reportTime='" + timestamp + - "', message='" + message + "', status=" + status + if (resultSet.next()) { + logMessage = "UPDATE statusUpdates SET reportTime='" + timestamp + + "', message='" + message + "', status=" + status + " WHERE tool='" + UserPreferences.getAppName() + "' AND node='" + NetworkUtils.getLocalHostName() + "'"; } else { - logMessage = "INSERT INTO statusUpdates (tool, node, reportTime, message, status) " + - "VALUES ('" + UserPreferences.getAppName() - + "', '" + NetworkUtils.getLocalHostName() + - "', '" + - timestamp + "', '" + message + "', '" + status + "')"; + logMessage = "INSERT INTO statusUpdates (tool, node, reportTime, message, status) " + + "VALUES ('" + UserPreferences.getAppName() + + "', '" + NetworkUtils.getLocalHostName() + + "', '" + + timestamp + "', '" + message + "', '" + status + "')"; } - statement.execute(logMessage); + statement.execute(logMessage); } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index b09ad5430e..6cfba771b5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,7 +39,7 @@ public class KeywordSearch { private static Server server; //we want a custom java.util.logging.Logger here for a reason //a separate logger from framework logs - private static final Logger TIKA_LOGGER = Logger.getLogger("Tika"); //NON-NLS + private static final Logger tikaLogger = Logger.getLogger("Tika"); //NON-NLS private static final org.sleuthkit.autopsy.coreutils.Logger logger = org.sleuthkit.autopsy.coreutils.Logger.getLogger(Case.class.getName()); // @@@ We should move this into TskData (or somewhere) because we are using @@ -70,9 +70,9 @@ public class KeywordSearch { 0, MAX_TIKA_LOG_FILES); tikaLogHandler.setFormatter(new SimpleFormatter()); tikaLogHandler.setEncoding(PlatformUtil.getLogFileEncoding()); - TIKA_LOGGER.addHandler(tikaLogHandler); + tikaLogger.addHandler(tikaLogHandler); //do not forward to the parent autopsy logger - TIKA_LOGGER.setUseParentHandlers(false); + tikaLogger.setUseParentHandlers(false); } catch (IOException | SecurityException ex) { logger.log(Level.SEVERE, "Error setting up tika logging", ex); //NON-NLS } @@ -84,7 +84,7 @@ public class KeywordSearch { } static Logger getTikaLogger() { - return TIKA_LOGGER; + return tikaLogger; } public static void addNumIndexedFilesChangeListener(PropertyChangeListener l) { diff --git a/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java b/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java index d1860120a6..b1ff751b77 100644 --- a/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java +++ b/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,7 +32,6 @@ import java.util.Date; import java.util.List; import java.util.Random; import java.util.logging.Level; -import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JDialog; import javax.swing.text.JTextComponent; @@ -58,6 +57,7 @@ import org.netbeans.jemmy.operators.JTreeOperator; import org.netbeans.jemmy.operators.JTreeOperator.NoSuchPathException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferencesException; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.datamodel.CaseDbConnectionInfo; diff --git a/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java b/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java index 0518da865b..87a24f5c85 100644 --- a/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java +++ b/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,11 +20,11 @@ package org.sleuthkit.autopsy.testing; import java.io.File; import java.io.IOException; -import java.util.logging.Logger; import junit.framework.Test; import junit.framework.TestCase; import org.netbeans.jemmy.Timeouts; import org.netbeans.junit.NbModuleSuite; +import org.sleuthkit.autopsy.coreutils.Logger; /** * This test expects the following system properties to be set: img_path: The @@ -41,7 +41,7 @@ import org.netbeans.junit.NbModuleSuite; public class RegressionTest extends TestCase { private static final Logger logger = Logger.getLogger(RegressionTest.class.getName()); - private static AutopsyTestCases autopsyTests = new AutopsyTestCases(Boolean.parseBoolean(System.getProperty("isMultiUser"))); + private static final AutopsyTestCases autopsyTests = new AutopsyTestCases(Boolean.parseBoolean(System.getProperty("isMultiUser"))); /** * Constructor required by JUnit From 1882690b727012cf0e4833d272360038716779ed Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 6 Apr 2018 15:55:44 +0200 Subject: [PATCH 13/29] refactor actions to support multiselect in VisualizationPanel via the ActionsGlobalContext lookup --- .../communications/AbstractCVTAction.java | 41 ++++++++--- .../communications/MessageBrowser.java | 4 +- .../autopsy/communications/SelectionNode.java | 18 +++-- .../communications/VisualizationPanel.java | 71 +++++++++---------- 4 files changed, 79 insertions(+), 55 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java index c2b43f2041..82cbe5e0f8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.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 2018 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.communications; @@ -14,7 +27,9 @@ import org.openide.util.actions.Presenter; /** * - * + * Base class for actions that act on the selected AccountDeviceInstanceKeys. + * getPopupPresenter() provides a JMenuItem that works (i.e., has an icon) in + * custom context menus and also in the Netbeans Explorer views. */ abstract class AbstractCVTAction extends AbstractAction implements Presenter.Popup { @@ -24,12 +39,8 @@ abstract class AbstractCVTAction extends AbstractAction implements Presenter.Pop * @return The selected accounts */ Collection getSelectedAccounts() { - return Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); - } - - @Override - final public void putValue(String key, Object newValue) { - super.putValue(key, newValue); + final Collection lookupAll = Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); + return lookupAll; } @Override @@ -40,8 +51,18 @@ abstract class AbstractCVTAction extends AbstractAction implements Presenter.Pop return presenter; } + /** + * The name/text of the action as displayed in a menu. + * + * @return The diaplay name of this action + */ abstract String getActionDisplayName(); + /** + * The icon to use for this icon. + * + * @return An ImageIcon used to represent this action. + */ abstract ImageIcon getIcon(); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 68309f5195..7c0bf99c62 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -151,10 +151,10 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov //Use lookup here? final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) selectedNodes[0]; - final Set accountDeviceInstances = new HashSet<>(); + final Set accountDeviceInstances = new HashSet<>(); for (final Node n : selectedNodes) { //Use lookup here? - accountDeviceInstances.add(((AccountDeviceInstanceNode) n).getAccountDeviceInstance()); + accountDeviceInstances.add(((AccountDeviceInstanceNode) n).getAccountDeviceInstanceKey()); } return SelectionNode.createFromAccounts(accountDeviceInstances, adiNode.getFilter(), adiNode.getCommsManager()); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java b/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java index 40739b49cc..be564c01cc 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java @@ -20,14 +20,18 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.logging.Level; +import java.util.stream.Collectors; import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -44,23 +48,27 @@ import org.sleuthkit.datamodel.TskCoreException; */ final class SelectionNode extends AbstractNode { - private SelectionNode(Children children) { - super(children); + SelectionNode(Children children, Lookup lookup) { + super(children, lookup); } static SelectionNode createFromAccountsAndRelationships( Set edgeRelationshipArtifacts, - Set accountDeviceInstances, + Set accountDeviceInstanceKeys, CommunicationsFilter filter, CommunicationsManager commsManager) { + Set accountDeviceInstances = accountDeviceInstanceKeys.stream() + .map(AccountDeviceInstanceKey::getAccountDeviceInstance) + .collect(Collectors.toSet()); + SelectionNode node = new SelectionNode(Children.create( new RelationshipChildren( edgeRelationshipArtifacts, accountDeviceInstances, commsManager, filter), - true)); + true), Lookups.fixed(accountDeviceInstanceKeys.toArray())); //This is not good for internationalization!!! String name = ""; @@ -82,7 +90,7 @@ final class SelectionNode extends AbstractNode { } static SelectionNode createFromAccounts( - Set accountDeviceInstances, + Set accountDeviceInstances, CommunicationsFilter filter, CommunicationsManager commsManager) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index fa095fd0a8..559bdf2bd5 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -193,48 +193,47 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider @Override public void mouseClicked(final MouseEvent event) { super.mouseClicked(event); - SwingUtilities.invokeLater(() -> { - if (SwingUtilities.isRightMouseButton(event)) { - final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY()); - if (cellAt != null && cellAt.isVertex()) { - final JPopupMenu jPopupMenu = new JPopupMenu(); - final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); + if (SwingUtilities.isRightMouseButton(event)) { + final mxCell cellAt = (mxCell) graphComponent.getCellAt(event.getX(), event.getY()); + if (cellAt != null && cellAt.isVertex()) { + final JPopupMenu jPopupMenu = new JPopupMenu(); + final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); - if (lockedVertexModel.isVertexLocked(cellAt)) { - jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock", unlockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.unlockVertex(cellAt); - } - })); - } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Lock", lockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.lockVertex(cellAt); - } - })); - } - if (pinnedAccountModel.isAccountPinned(adiKey)) { - jPopupMenu.add(UnpinAccountsAction.getInstance().getPopupPresenter()); - } else { - jPopupMenu.add(PinAccountsAction.getInstance().getPopupPresenter()); - jPopupMenu.add(ResetAndPinAccountsAction.getInstance().getPopupPresenter()); - } - jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY()); + if (lockedVertexModel.isVertexLocked(cellAt)) { + jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock", unlockIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.unlockVertex(cellAt); + } + })); + } else { + jPopupMenu.add(new JMenuItem(new AbstractAction("Lock", lockIcon) { + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.lockVertex(cellAt); + } + })); } + if (pinnedAccountModel.isAccountPinned(adiKey)) { + jPopupMenu.add(UnpinAccountsAction.getInstance().getPopupPresenter()); + } else { + jPopupMenu.add(PinAccountsAction.getInstance().getPopupPresenter()); + jPopupMenu.add(ResetAndPinAccountsAction.getInstance().getPopupPresenter()); + } + jPopupMenu.show(graphComponent.getGraphControl(), event.getX(), event.getY()); } - }); + } } - }); + final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM); splitPane.setRightComponent(messageBrowser); proxyLookup = new ProxyLookup( - messageBrowser.getLookup(), - ExplorerUtils.createLookup(vizEM, getActionMap())); + ExplorerUtils.createLookup(vizEM, getActionMap()), + messageBrowser.getLookup() + ); //feed selection to explorermanager graph.getSelectionModel().addListener(mxEvent.CHANGE, new SelectionListener()); @@ -246,7 +245,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Override - public Lookup getLookup() { return proxyLookup; } @@ -275,7 +273,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider @Subscribe void handleFilterEvent(final CVTEvents.FilterChangeEvent filterChangeEvent) { - graph.getModel().beginUpdate(); graph.clear(); currentFilter = filterChangeEvent.getNewFilter(); @@ -733,7 +730,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (selectionCells.length > 0) { mxICell[] selectedCells = Arrays.asList(selectionCells).toArray(new mxCell[selectionCells.length]); HashSet relationshipSources = new HashSet<>(); - HashSet adis = new HashSet<>(); + HashSet adis = new HashSet<>(); for (mxICell cell : selectedCells) { if (cell.isEdge()) { mxICell source = (mxICell) graph.getModel().getTerminal(cell, true); @@ -750,7 +747,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider logger.log(Level.SEVERE, " Error getting relationsips....", tskCoreException); } } else if (cell.isVertex()) { - adis.add(((AccountDeviceInstanceKey) cell.getValue()).getAccountDeviceInstance()); + adis.add((AccountDeviceInstanceKey) cell.getValue()); } } @@ -872,7 +869,5 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider cancellable.cancel(true); progress.finish(); } - } - } From 771ec1a9838ed095238a0a0b1eced34b11cc1f28 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 6 Apr 2018 15:08:36 -0400 Subject: [PATCH 14/29] 3598: 6th test for file filter tests --- .../autopsy/ingest/IngestFileFiltersTest.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java index ad51847434..e9cab64a20 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import static junit.framework.Assert.assertFalse; -import junit.framework.TestCase; import org.netbeans.junit.NbModuleSuite; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.CaseActionException; @@ -309,6 +308,35 @@ public class IngestFileFiltersTest extends NbTestCase { } } + public void testCarvingNoUnallocatedSpace() { + HashMap rules = new HashMap<>(); + rules.put("rule1", new Rule("FindJpgExtention", new ExtensionCondition("jpg"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null)); + rules.put("rule2", new Rule("FindGifExtention", new ExtensionCondition("gif"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null)); + + //Build the filter to find files with .jpg and .gif extension + FilesSet extensionFilter = new FilesSet("Filter", "Filter to files with .jpg and .gif extension.", false, true, rules); + + try { + Case openCase = Case.getOpenCase(); + ArrayList templates = new ArrayList<>(); + templates.add(getIngestModuleTemplate(new FileTypeIdModuleFactory())); + templates.add(getIngestModuleTemplate(new PhotoRecCarverIngestModuleFactory())); + IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, extensionFilter); + try { + List errs = IngestJobRunner.runIngestJob(openCase.getDataSources(), ingestJobSettings); + //Ingest fails because Carving wants unallocated space + assertEquals(1, errs.size()); + assertEquals("PhotoRec Carver", errs.get(0).getModuleDisplayName()); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } catch (NoCurrentCaseException | TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + private void runIngestJob(List datasources, ArrayList templates, FilesSet filter) { IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, filter); try { From 0cacfea4b367377291e35968b8e34d391427eb6b Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 6 Apr 2018 17:06:25 -0400 Subject: [PATCH 15/29] Added comment about use of standard Java Logger. --- .../autopsy/ingest/IngestMonitor.java | 47 ++++++++++--------- .../autopsy/keywordsearch/KeywordSearch.java | 6 +-- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java index 1dc585a8f3..764fc694ef 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestMonitor.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * + * * Copyright 2011-2018 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. @@ -38,14 +38,19 @@ import org.sleuthkit.autopsy.events.AutopsyEvent; /** * Monitors disk space and memory and cancels ingest if disk space runs low. *

- * Note: This should be a singleton and currently is used as such, with the - * only instance residing in the IngestManager class. + * Note: This should be a singleton and currently is used as such, with the only + * instance residing in the IngestManager class. */ public final class IngestMonitor { public static final int DISK_FREE_SPACE_UNKNOWN = -1; private static final int INITIAL_INTERVAL_MS = 60000; //1 min. private static final int MAX_LOG_FILES = 3; + + /* + * The monitorLogger used the standard Java Logger type for compact logs + * without the stack trace. + */ private static final java.util.logging.Logger monitorLogger = java.util.logging.Logger.getLogger("monitor"); //NON-NLS private final Logger logger = Logger.getLogger(IngestMonitor.class.getName()); private Timer timer; @@ -213,10 +218,11 @@ public final class IngestMonitor { private void logMemoryUsage() { monitorLogger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo()); } - + /** - * Writes current disk space usage of the drive where case dir resides to log. - */ + * Writes current disk space usage of the drive where case dir resides + * to log. + */ private void logDiskSpaceUsage() { final long freeSpace = root.getFreeSpace(); logger.log(Level.INFO, "Available disk space on drive where case dir resides is {0} (bytes)", freeSpace); //NON-NLS @@ -253,18 +259,17 @@ public final class IngestMonitor { private long getFreeSpace() throws SecurityException { // always return "UNKNOWN", see note below return DISK_FREE_SPACE_UNKNOWN; - - /* NOTE: use and accuracy of this code for network drives needs to be investigated and validated - final long freeSpace = root.getFreeSpace(); - if (0 == freeSpace) { - // Check for a network drive, some network filesystems always - // return zero. - final String monitoredPath = root.getAbsolutePath(); - if (monitoredPath.startsWith("\\\\") || monitoredPath.startsWith("//")) { - return DISK_FREE_SPACE_UNKNOWN; - } - } - return freeSpace;*/ + + /* + * NOTE: use and accuracy of this code for network drives needs to + * be investigated and validated final long freeSpace = + * root.getFreeSpace(); if (0 == freeSpace) { // Check for a network + * drive, some network filesystems always // return zero. final + * String monitoredPath = root.getAbsolutePath(); if + * (monitoredPath.startsWith("\\\\") || + * monitoredPath.startsWith("//")) { return DISK_FREE_SPACE_UNKNOWN; + * } } return freeSpace; + */ } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 6cfba771b5..10a7bef73c 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -23,10 +23,10 @@ import java.beans.PropertyChangeSupport; import java.io.IOException; import java.util.logging.FileHandler; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.logging.SimpleFormatter; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil; @@ -39,8 +39,8 @@ public class KeywordSearch { private static Server server; //we want a custom java.util.logging.Logger here for a reason //a separate logger from framework logs - private static final Logger tikaLogger = Logger.getLogger("Tika"); //NON-NLS - private static final org.sleuthkit.autopsy.coreutils.Logger logger = org.sleuthkit.autopsy.coreutils.Logger.getLogger(Case.class.getName()); + private static final java.util.logging.Logger tikaLogger = java.util.logging.Logger.getLogger("Tika"); //NON-NLS + private static final Logger logger = Logger.getLogger(Case.class.getName()); // @@@ We should move this into TskData (or somewhere) because we are using // this value in the results tree to display substring differently from regexp (KeywordHit.java) From f3161c7af6607d9156be14cf783efa486b973cdc Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 7 Apr 2018 14:56:15 +0200 Subject: [PATCH 16/29] multiselect for locking. Not updating the icon properly... --- .../communications/CommunicationsGraph.java | 28 ++--- .../communications/LockedVertexModel.java | 46 ++++--- .../communications/PinnedAccountModel.java | 7 +- .../communications/VisualizationPanel.java | 116 ++++++++++++++---- 4 files changed, 124 insertions(+), 73 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java index f274ab00d7..98d9aa7d88 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java @@ -38,6 +38,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; import java.util.logging.Level; import javax.swing.SwingWorker; import org.sleuthkit.autopsy.coreutils.Logger; @@ -84,17 +85,19 @@ final class CommunicationsGraph extends mxGraph { mxStylesheet.getDefaultEdgeStyle().put(mxConstants.STYLE_STARTARROW, mxConstants.NONE); } - /* Map from type specific account identifier to mxCell(vertex). */ + /** Map from type specific account identifier to mxCell(vertex). */ private final Map nodeMap = new HashMap<>(); - /* Map from relationship source (Content) to mxCell (edge). */ + /** Map from relationship source (Content) to mxCell (edge). */ private final Multimap edgeMap = MultimapBuilder.hashKeys().hashSetValues().build(); private final LockedVertexModel lockedVertexModel; private final PinnedAccountModel pinnedAccountModel; - CommunicationsGraph() { + CommunicationsGraph(PinnedAccountModel pinnedAccountModel, LockedVertexModel lockedVertexModel) { super(mxStylesheet); + this.pinnedAccountModel =pinnedAccountModel; + this.lockedVertexModel = lockedVertexModel; //set fixed properties of graph. setAutoSizeCells(true); setCellsCloneable(false); @@ -113,21 +116,6 @@ final class CommunicationsGraph extends mxGraph { setKeepEdgesInBackground(true); setResetEdgesOnMove(true); setHtmlLabels(true); - - lockedVertexModel = new LockedVertexModel(); - lockedVertexModel.registerhandler((LockedVertexModel.VertexLockEvent event) -> { - if (event.isVertexLocked()) { - getView().clear(event.getVertex(), true, true); - getView().validate(); - } else { - final mxCellState state = getView().getState(event.getVertex(), true); - getView().updateLabel(state); - getView().updateLabelBounds(state); - getView().updateBoundingBox(state); - } - }); - - pinnedAccountModel = new PinnedAccountModel(this); } /** @@ -299,7 +287,7 @@ final class CommunicationsGraph extends mxGraph { int total = relationshipCounts.size(); int k = 0; - String progressText = ""; + String progressText = ""; progress.switchToDeterminate("", 0, total); for (Map.Entry entry : relationshipCounts.entrySet()) { Long count = entry.getValue(); @@ -308,7 +296,7 @@ final class CommunicationsGraph extends mxGraph { AccountDeviceInstanceKey account2 = relatedAccounts.get(relationshipKey.getSecond()); if (pinnedAccountModel.isAccountPinned(account1) - || pinnedAccountModel.isAccountPinned(account2)) { + || pinnedAccountModel.isAccountPinned(account2)) { mxCell addEdge = addOrUpdateEdge(count, account1, account2); progressText = addEdge.getId(); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index f26e9515b3..ad189a8bea 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -18,12 +18,22 @@ */ package org.sleuthkit.autopsy.communications; +import com.google.common.collect.ImmutableSet; import com.google.common.eventbus.EventBus; import com.mxgraph.model.mxCell; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; -class LockedVertexModel { +/** + * Model of which vertices in a graph are locked ( not moveable by layout + * algorithms). + * + */ +final class LockedVertexModel { void registerhandler(EventHandler handler) { eventBus.register(handler); @@ -42,30 +52,26 @@ class LockedVertexModel { */ private final Set lockedVertices = new HashSet<>(); - LockedVertexModel() { - } - /** - * Lock the given vertex so that applying a layout algorithm doesn't move - * it. The user can still manually position the vertex. + * Lock the given vertices so that applying a layout algorithm doesn't move + * them. The user can still manually position the vertices. * * @param vertex The vertex to lock. */ - void lockVertex(mxCell vertex) { - lockedVertices.add(vertex); - eventBus.post(new VertexLockEvent(vertex, true)); - + void lock(Collection vertices) { + lockedVertices.addAll(vertices); + eventBus.post(new VertexLockEvent(true, vertices)); } /** - * Lock the given vertex so that applying a layout algorithm can move it. + * Unlock the given vertices so that applying a layout algorithm can move + * them. * * @param vertex The vertex to unlock. */ - void unlockVertex(mxCell vertex) { - lockedVertices.remove(vertex); - eventBus.post(new VertexLockEvent(vertex, false)); - + void unlock(Collection vertices) { + lockedVertices.removeAll(vertices); + eventBus.post(new VertexLockEvent(false, vertices)); } boolean isVertexLocked(mxCell vertex) { @@ -79,10 +85,10 @@ class LockedVertexModel { static class VertexLockEvent { - private final mxCell vertex; + private final Set vertices; - public mxCell getVertex() { - return vertex; + public Set getVertices() { + return vertices; } public boolean isVertexLocked() { @@ -90,8 +96,8 @@ class LockedVertexModel { } private final boolean locked; - VertexLockEvent(mxCell vertex, boolean locked) { - this.vertex = vertex; + VertexLockEvent(boolean locked, Collection< mxCell> vertices) { + this.vertices = ImmutableSet.copyOf(vertices); this.locked = locked; } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java b/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java index d5f7a7cc03..beff35173d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java @@ -25,17 +25,12 @@ import java.util.Set; class PinnedAccountModel { /** - * Set of AccountDeviceInstanceKeys that are 'Pinned' to this graph. Pinned + * Set of AccountDeviceInstanceKeys that are 'Pinned' to the graph. Pinned * accounts are shown regardless of filters, and accounts that are related * to pinned accounts and pass the filters are show. Pinning accounts is the * primary way to populate the graph. */ private final Set pinnedAccountDevices = new HashSet<>(); - private final CommunicationsGraph graph; - - PinnedAccountModel(CommunicationsGraph graph) { - this.graph = graph; - } boolean isAccountPinned(AccountDeviceInstanceKey account) { return pinnedAccountDevices.contains(account); diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 559bdf2bd5..d33ca867d7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -36,7 +36,9 @@ import com.mxgraph.util.mxPoint; import com.mxgraph.util.mxRectangle; import com.mxgraph.util.mxUndoManager; import com.mxgraph.util.mxUndoableEdit; +import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraph; +import com.mxgraph.view.mxGraphView; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; @@ -54,8 +56,11 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.Future; import java.util.logging.Level; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.AbstractAction; import javax.swing.ImageIcon; import javax.swing.JButton; @@ -83,7 +88,6 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator; -import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.Content; @@ -99,7 +103,6 @@ import org.sleuthkit.datamodel.TskCoreException; * CVTTopComponent when this tab is active allowing for context sensitive * actions to work correctly. */ -@NbBundle.Messages("VisualizationPanel.cancelButton.text=Cancel") final public class VisualizationPanel extends JPanel implements Lookup.Provider { private static final long serialVersionUID = 1L; @@ -110,6 +113,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider static final private ImageIcon lockIcon = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_locked.png")); + @NbBundle.Messages("VisualizationPanel.cancelButton.text=Cancel") private static final String CANCEL = Bundle.VisualizationPanel_cancelButton_text(); private final ExplorerManager vizEM = new ExplorerManager(); @@ -124,7 +128,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final CommunicationsGraph graph; private final mxUndoManager undoManager = new mxUndoManager(); - private final mxRubberband rubberband; + private final mxRubberband rubberband; //NOPMD We keep a referenec as insurance to prevent garbage collection private final mxFastOrganicLayout fastOrganicLayout; private final mxCircleLayout circleLayout; @@ -133,14 +137,13 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; - private final PinnedAccountModel pinnedAccountModel; - private final LockedVertexModel lockedVertexModel; + private final PinnedAccountModel pinnedAccountModel = new PinnedAccountModel(); + private final LockedVertexModel lockedVertexModel = new LockedVertexModel(); public VisualizationPanel() { initComponents(); - graph = new CommunicationsGraph(); - pinnedAccountModel = graph.getPinnedAccountModel(); - lockedVertexModel = graph.getLockedVertexModel(); + + graph = new CommunicationsGraph(pinnedAccountModel, lockedVertexModel); fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); circleLayout = new mxCircleLayoutImpl(graph); @@ -159,9 +162,26 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graphComponent.setBackground(Color.WHITE); borderLayoutPanel.add(graphComponent, BorderLayout.CENTER); - //install rubber band selection handler + //install rubber band other handlers rubberband = new mxRubberband(graphComponent); + lockedVertexModel.registerhandler((LockedVertexModel.VertexLockEvent event) -> { + final Set vertices = event.getVertices(); + mxGraphView view = graph.getView(); + if (event.isVertexLocked()) { + vertices.forEach(vertex -> view.clear(vertex, true, true)); + view.validate(); + } else { + vertices.forEach(vertex -> { + final mxCellState state = view.getState(vertex, true); + view.updateLabel(state); + view.updateLabelBounds(state); + view.updateBoundingBox(state); + }); + } + graphComponent.getGraphControl().repaint(); + }); + final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt) -> zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale())); graph.getView().addListener(mxEvent.SCALE, scaleListener); @@ -199,20 +219,16 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider final JPopupMenu jPopupMenu = new JPopupMenu(); final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); + Set selectedVertices + = Stream.of(graph.getSelectionModel().getCells()) + .map(mxCell.class::cast) + .filter(mxCell::isVertex) + .collect(Collectors.toSet()); + if (lockedVertexModel.isVertexLocked(cellAt)) { - jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock", unlockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.unlockVertex(cellAt); - } - })); + jPopupMenu.add(new JMenuItem(new UnlockAction(selectedVertices))); } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Lock", lockIcon) { - @Override - public void actionPerformed(final ActionEvent event) { - lockedVertexModel.lockVertex(cellAt); - } - })); + jPopupMenu.add(new JMenuItem(new LockAction(selectedVertices))); } if (pinnedAccountModel.isAccountPinned(adiKey)) { jPopupMenu.add(UnpinAccountsAction.getInstance().getPopupPresenter()); @@ -224,6 +240,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } + }); final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM); @@ -650,16 +667,18 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } + @NbBundle.Messages({"Visualization.computingLayout=Computing Layout"}) private void morph(mxIGraphLayout layout) { // layout using morphing graph.getModel().beginUpdate(); CancelationListener cancelationListener = new CancelationListener(); - ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, "Computing layout", new String[]{CANCEL}, CANCEL, cancelationListener); + ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, + Bundle.Visualization_computingLayout(), new String[]{CANCEL}, CANCEL, cancelationListener); SwingWorker morphWorker = new SwingWorker() { @Override protected Void doInBackground() { - progress.start("Computing layout"); + progress.start(Bundle.Visualization_computingLayout()); layout.execute(graph.getDefaultParent()); if (isCancelled()) { progress.finish(); @@ -719,6 +738,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private JButton zoomOutButton; // End of variables declaration//GEN-END:variables + /** + * Listens to graph selection model and updates ExplorerManager to reflect + * changes in selection. + */ final private class SelectionListener implements mxEventSource.mxIEventListener { @SuppressWarnings("unchecked") @@ -776,7 +799,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { return getVertexBounds(vertex); } else { @@ -799,7 +822,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { return getVertexBounds(vertex); } else { @@ -822,7 +845,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { return getVertexBounds(vertex); } else { @@ -844,7 +867,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Override - public mxRectangle setVertexLocation(Object vertex, double x, double y) { + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { return getVertexBounds(vertex); } else { @@ -870,4 +893,43 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider progress.finish(); } } + + @NbBundle.Messages({ + "VisualizationPanel.unlockAction.singularText=Unlock Selected Account", + "VisualizationPanel.unlockAction.pluralText=Unlock Selected Accounts",}) + private final class UnlockAction extends AbstractAction { + + private final Set selectedVertices; + + UnlockAction(Set selectedVertices) { + super(selectedVertices.size() > 1 ? Bundle.VisualizationPanel_unlockAction_pluralText() : Bundle.VisualizationPanel_unlockAction_singularText(), + unlockIcon); + this.selectedVertices = selectedVertices; + } + + @Override + + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.unlock(selectedVertices); + } + } + + @NbBundle.Messages({ + "VisualizationPanel.lockAction.singularText=Lock Selected Account", + "VisualizationPanel.lockAction.pluralText=Lock Selected Accounts"}) + private final class LockAction extends AbstractAction { + + private final Set selectedVertices; + + LockAction(Set selectedVertices) { + super(selectedVertices.size() > 1 ? Bundle.VisualizationPanel_lockAction_pluralText() : Bundle.VisualizationPanel_lockAction_singularText(), + lockIcon); + this.selectedVertices = selectedVertices; + } + + @Override + public void actionPerformed(final ActionEvent event) { + lockedVertexModel.lock(selectedVertices); + } + } } From b5a50fd62a0ad00291c6a0555a9843fce9aa0cf9 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 7 Apr 2018 15:49:25 +0200 Subject: [PATCH 17/29] fix repainting of lock icons --- .../autopsy/communications/EventHandler.java | 28 -------------- .../communications/LockedVertexModel.java | 24 ++++++++---- .../communications/VisualizationPanel.java | 37 +++++++++---------- 3 files changed, 33 insertions(+), 56 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/communications/EventHandler.java diff --git a/Core/src/org/sleuthkit/autopsy/communications/EventHandler.java b/Core/src/org/sleuthkit/autopsy/communications/EventHandler.java deleted file mode 100644 index f1acedf1cf..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/EventHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018 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.communications; - -/** - * - */ -public interface EventHandler { - - void handle(T event); -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index ad189a8bea..873866f3f5 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -21,11 +21,8 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.ImmutableSet; import com.google.common.eventbus.EventBus; import com.mxgraph.model.mxCell; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Set; /** @@ -35,11 +32,11 @@ import java.util.Set; */ final class LockedVertexModel { - void registerhandler(EventHandler handler) { + void registerhandler(Object handler) { eventBus.register(handler); } - void unregisterhandler(EventHandler handler) { + void unregisterhandler(Object handler) { eventBus.unregister(handler); } @@ -83,18 +80,29 @@ final class LockedVertexModel { lockedVertices.clear(); } - static class VertexLockEvent { + /** + * Event that represents a change in the locked state of one or more + * vertices. + */ + final static class VertexLockEvent { + private final boolean locked; private final Set vertices; + /** + * @return The vertices whose locked state has changed. + */ public Set getVertices() { return vertices; } - public boolean isVertexLocked() { + /** + * @return True if the vertices are locked, False if the vertices are + * unlocked. + */ + public boolean isLocked() { return locked; } - private final boolean locked; VertexLockEvent(boolean locked, Collection< mxCell> vertices) { this.vertices = ImmutableSet.copyOf(vertices); diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index d33ca867d7..e0fe563e81 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -165,22 +165,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider //install rubber band other handlers rubberband = new mxRubberband(graphComponent); - lockedVertexModel.registerhandler((LockedVertexModel.VertexLockEvent event) -> { - final Set vertices = event.getVertices(); - mxGraphView view = graph.getView(); - if (event.isVertexLocked()) { - vertices.forEach(vertex -> view.clear(vertex, true, true)); - view.validate(); - } else { - vertices.forEach(vertex -> { - final mxCellState state = view.getState(vertex, true); - view.updateLabel(state); - view.updateLabelBounds(state); - view.updateBoundingBox(state); - }); - } - graphComponent.getGraphControl().repaint(); - }); + lockedVertexModel.registerhandler(this); final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt) -> zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale())); @@ -267,7 +252,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Subscribe - void handleUnPinEvent(final CVTEvents.UnpinAccountsEvent pinEvent) { + void handle(LockedVertexModel.VertexLockEvent event) { + final Set vertices = event.getVertices(); + mxGraphView view = graph.getView(); + vertices.forEach(vertex -> { + final mxCellState state = view.getState(vertex, true); + view.updateLabel(state); + view.updateLabelBounds(state); + view.updateBoundingBox(state); + graphComponent.redraw(state); + }); + } + + @Subscribe + void handle(final CVTEvents.UnpinAccountsEvent pinEvent) { graph.getModel().beginUpdate(); pinnedAccountModel.unpinAccount(pinEvent.getAccountDeviceInstances()); graph.clear(); @@ -277,7 +275,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Subscribe - void handlePinEvent(final CVTEvents.PinAccountsEvent pinEvent) { + void handle(final CVTEvents.PinAccountsEvent pinEvent) { graph.getModel().beginUpdate(); if (pinEvent.isReplace()) { graph.resetGraph(); @@ -289,7 +287,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } @Subscribe - void handleFilterEvent(final CVTEvents.FilterChangeEvent filterChangeEvent) { + void handle(final CVTEvents.FilterChangeEvent filterChangeEvent) { graph.getModel().beginUpdate(); graph.clear(); currentFilter = filterChangeEvent.getNewFilter(); @@ -360,7 +358,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider logger.log(Level.SEVERE, "Error getting CommunicationsManager for the current case.", ex); } } - }); } From 1bec33604b401edffa5511c086ca0da6fe2ff77c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 7 Apr 2018 16:19:14 +0200 Subject: [PATCH 18/29] fix codacy warnings --- .../communications/AbstractCVTAction.java | 5 +--- .../autopsy/communications/CVTEvents.java | 1 - .../communications/CommunicationsGraph.java | 23 ++++++++----------- .../communications/LockedVertexModel.java | 18 ++++++++------- .../communications/MessageBrowser.java | 1 - .../communications/PinAccountsAction.java | 8 +++++-- .../communications/PinnedAccountModel.java | 14 +++++++++++ .../ResetAndPinAccountsAction.java | 6 ++--- .../autopsy/communications/SelectionNode.java | 9 ++++---- .../communications/UnpinAccountsAction.java | 4 ++++ .../communications/VisualizationPanel.java | 11 ++++++++- 11 files changed, 62 insertions(+), 38 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java b/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java index 82cbe5e0f8..ef751d262c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AbstractCVTAction.java @@ -26,7 +26,6 @@ import org.openide.util.Utilities; import org.openide.util.actions.Presenter; /** - * * Base class for actions that act on the selected AccountDeviceInstanceKeys. * getPopupPresenter() provides a JMenuItem that works (i.e., has an icon) in * custom context menus and also in the Netbeans Explorer views. @@ -39,8 +38,7 @@ abstract class AbstractCVTAction extends AbstractAction implements Presenter.Pop * @return The selected accounts */ Collection getSelectedAccounts() { - final Collection lookupAll = Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); - return lookupAll; + return Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class); } @Override @@ -64,5 +62,4 @@ abstract class AbstractCVTAction extends AbstractAction implements Presenter.Pop * @return An ImageIcon used to represent this action. */ abstract ImageIcon getIcon(); - } diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java b/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java index 54e5b8a1ef..6a6a60d3da 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTEvents.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.ImmutableSet; import com.google.common.eventbus.EventBus; import java.util.Collection; -import java.util.Set; import org.sleuthkit.datamodel.CommunicationsFilter; /** diff --git a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java index 98d9aa7d88..2cf04eacea 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java @@ -25,7 +25,6 @@ import com.google.common.collect.MultimapBuilder; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxICell; import com.mxgraph.util.mxConstants; -import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxStylesheet; import java.io.InputStream; @@ -38,7 +37,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; import java.util.logging.Level; import javax.swing.SwingWorker; import org.sleuthkit.autopsy.coreutils.Logger; @@ -96,7 +94,7 @@ final class CommunicationsGraph extends mxGraph { CommunicationsGraph(PinnedAccountModel pinnedAccountModel, LockedVertexModel lockedVertexModel) { super(mxStylesheet); - this.pinnedAccountModel =pinnedAccountModel; + this.pinnedAccountModel = pinnedAccountModel; this.lockedVertexModel = lockedVertexModel; //set fixed properties of graph. setAutoSizeCells(true); @@ -243,20 +241,20 @@ final class CommunicationsGraph extends mxGraph { */ private class RebuildWorker extends SwingWorker { - private final ProgressIndicator progress; + private final ProgressIndicator progressIndicator; private final CommunicationsManager commsManager; private final CommunicationsFilter currentFilter; RebuildWorker(ProgressIndicator progress, CommunicationsManager commsManager, CommunicationsFilter currentFilter) { - this.progress = progress; + this.progressIndicator = progress; this.currentFilter = currentFilter; this.commsManager = commsManager; } @Override - protected Void doInBackground() throws Exception { - progress.start("Loading accounts"); + protected Void doInBackground() { + progressIndicator.start("Loading accounts"); int progressCounter = 0; try { /** @@ -278,7 +276,7 @@ final class CommunicationsGraph extends mxGraph { final AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, currentFilter, adiRelationshipsCount); relatedAccounts.put(relatedADI, relatedADIKey); //store related accounts } - progress.progress(++progressCounter); + progressIndicator.progress(++progressCounter); } Set accounts = relatedAccounts.keySet(); @@ -286,9 +284,9 @@ final class CommunicationsGraph extends mxGraph { Map relationshipCounts = commsManager.getRelationshipCountsPairwise(accounts, currentFilter); int total = relationshipCounts.size(); - int k = 0; + int progress = 0; String progressText = ""; - progress.switchToDeterminate("", 0, total); + progressIndicator.switchToDeterminate("", 0, total); for (Map.Entry entry : relationshipCounts.entrySet()) { Long count = entry.getValue(); AccountPair relationshipKey = entry.getKey(); @@ -300,11 +298,10 @@ final class CommunicationsGraph extends mxGraph { mxCell addEdge = addOrUpdateEdge(count, account1, account2); progressText = addEdge.getId(); } - progress.progress(progressText, k++); + progressIndicator.progress(progressText, progress++); } } catch (TskCoreException tskCoreException) { logger.log(Level.SEVERE, "Error", tskCoreException); - } finally { } return null; @@ -320,7 +317,7 @@ final class CommunicationsGraph extends mxGraph { } catch (CancellationException ex) { logger.log(Level.INFO, "Graph visualization cancelled"); } finally { - progress.finish(); + progressIndicator.finish(); } } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index 873866f3f5..3ff5880b63 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -32,14 +32,6 @@ import java.util.Set; */ final class LockedVertexModel { - void registerhandler(Object handler) { - eventBus.register(handler); - } - - void unregisterhandler(Object handler) { - eventBus.unregister(handler); - } - private final EventBus eventBus = new EventBus(); /** @@ -49,6 +41,16 @@ final class LockedVertexModel { */ private final Set lockedVertices = new HashSet<>(); + + void registerhandler(Object handler) { + eventBus.register(handler); + } + + void unregisterhandler(Object handler) { + eventBus.unregister(handler); + } + + /** * Lock the given vertices so that applying a layout algorithm doesn't move * them. The user can still manually position the vertices. diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java index 7c0bf99c62..7b90357993 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -35,7 +35,6 @@ import org.sleuthkit.autopsy.corecomponents.DataResultPanel; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; -import org.sleuthkit.datamodel.AccountDeviceInstance; /** * The right hand side of the CVT. Has a DataResultPanel to show a listing of diff --git a/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java index d820373284..52136d1b1a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java @@ -23,6 +23,10 @@ import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; +/** + * Action that pins the AccountDevicesIntanceKeys in the ActionsGlobalContext to + * the visualizaion + */ @NbBundle.Messages({"PinAccountsAction.pluralText=Add Selected Accounts to Visualization", "PinAccountsAction.singularText=Add Selected Account to Visualization"}) final class PinAccountsAction extends AbstractCVTAction { @@ -31,7 +35,7 @@ final class PinAccountsAction extends AbstractCVTAction { "/org/sleuthkit/autopsy/communications/images/marker--plus.png", false); private static final String SINGULAR_TEXT = Bundle.PinAccountsAction_singularText(); private static final String PLURAL_TEXT = Bundle.PinAccountsAction_pluralText(); - + private static final PinAccountsAction instance = new PinAccountsAction(); static PinAccountsAction getInstance() { @@ -39,7 +43,7 @@ final class PinAccountsAction extends AbstractCVTAction { } @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent event) { CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(getSelectedAccounts(), false)); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java b/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java index beff35173d..f7fb7d1232 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/PinnedAccountModel.java @@ -19,9 +19,13 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.ImmutableSet; +import com.google.common.eventbus.EventBus; import java.util.HashSet; import java.util.Set; +/** + * Model of what accounts are pinned to a visualization. + */ class PinnedAccountModel { /** @@ -32,6 +36,16 @@ class PinnedAccountModel { */ private final Set pinnedAccountDevices = new HashSet<>(); + private final EventBus eventBus = new EventBus(); + + void registerhandler(Object handler) { + eventBus.register(handler); + } + + void unregisterhandler(Object handler) { + eventBus.unregister(handler); + } + boolean isAccountPinned(AccountDeviceInstanceKey account) { return pinnedAccountDevices.contains(account); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java index a42b2882ed..385ac3348b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java @@ -24,7 +24,8 @@ import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** - * + * Action that clears any pinned accounts and pins the AcountDevicesInstanceKeys + * in the ActionsGlobalContext to the visualization. */ @NbBundle.Messages(value = {"ResetAndPinAccountsAction.singularText=Visualize Only Selected Account", "ResetAndPinAccountsAction.pluralText=Visualize Only Selected Accounts"}) @@ -42,7 +43,7 @@ final class ResetAndPinAccountsAction extends AbstractCVTAction { } @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent event) { CVTEvents.getCVTEventBus().post(new CVTEvents.PinAccountsEvent(getSelectedAccounts(), true)); } @@ -55,5 +56,4 @@ final class ResetAndPinAccountsAction extends AbstractCVTAction { ImageIcon getIcon() { return ICON; } - } diff --git a/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java b/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java index be564c01cc..1618bb9ecc 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/SelectionNode.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -48,7 +47,7 @@ import org.sleuthkit.datamodel.TskCoreException; */ final class SelectionNode extends AbstractNode { - SelectionNode(Children children, Lookup lookup) { + private SelectionNode(Children children, Lookup lookup) { super(children, lookup); } @@ -130,9 +129,9 @@ final class SelectionNode extends AbstractNode { } @Override - protected Node createNodeForKey(Content t) { - if (t instanceof BlackboardArtifact) { - return new RelationshipNode((BlackboardArtifact) t); + protected Node createNodeForKey(Content content) { + if (content instanceof BlackboardArtifact) { + return new RelationshipNode((BlackboardArtifact) content); } else { throw new UnsupportedOperationException("Cannot create a RelationshipNode for non BlackboardArtifact content."); } diff --git a/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java index 357f5a0451..ba0bbc545b 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java @@ -23,6 +23,10 @@ import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; +/** + * Action that unpins the AcccountDeviceInstanceKeys in the ActionsGlobalContext + * form the visualization. + */ @NbBundle.Messages({"UnpinAccountsAction.pluralText=Remove Selected Accounts", "UnpinAccountsAction.singularText=Remove Selected Account"}) final class UnpinAccountsAction extends AbstractCVTAction { diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index e0fe563e81..9fca11992a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -873,7 +873,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } - private class CancelationListener implements ActionListener { + /** + * Listener that closes a ModalDialogProgreessIndicator when invoked. + */ + final private class CancelationListener implements ActionListener { private Future cancellable; private ModalDialogProgressIndicator progress; @@ -891,6 +894,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Action that un-locks the selected vertices. + */ @NbBundle.Messages({ "VisualizationPanel.unlockAction.singularText=Unlock Selected Account", "VisualizationPanel.unlockAction.pluralText=Unlock Selected Accounts",}) @@ -911,6 +917,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Action that locks the selected vertices. + */ @NbBundle.Messages({ "VisualizationPanel.lockAction.singularText=Lock Selected Account", "VisualizationPanel.lockAction.pluralText=Lock Selected Accounts"}) From f0e04d28f252238f88a270ca657e856151f40179 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 9 Apr 2018 11:32:14 +0200 Subject: [PATCH 19/29] log errors in layout SwingWorker --- .../communications/VisualizationPanel.java | 172 +++++++++--------- 1 file changed, 91 insertions(+), 81 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 9fca11992a..7d2c77dfce 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -57,6 +57,7 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.logging.Level; import java.util.stream.Collectors; @@ -104,7 +105,7 @@ import org.sleuthkit.datamodel.TskCoreException; * actions to work correctly. */ final public class VisualizationPanel extends JPanel implements Lookup.Provider { - + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(VisualizationPanel.class.getName()); private static final String BASE_IMAGE_PATH = "/org/sleuthkit/autopsy/communications/images"; @@ -112,21 +113,21 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_unlocked.png")); static final private ImageIcon lockIcon = new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_locked.png")); - + @NbBundle.Messages("VisualizationPanel.cancelButton.text=Cancel") private static final String CANCEL = Bundle.VisualizationPanel_cancelButton_text(); - + private final ExplorerManager vizEM = new ExplorerManager(); private final ExplorerManager gacEM = new ExplorerManager(); private final ProxyLookup proxyLookup; private Frame windowAncestor; - + private CommunicationsManager commsManager; private CommunicationsFilter currentFilter; - + private final mxGraphComponent graphComponent; private final CommunicationsGraph graph; - + private final mxUndoManager undoManager = new mxUndoManager(); private final mxRubberband rubberband; //NOPMD We keep a referenec as insurance to prevent garbage collection @@ -134,22 +135,22 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxCircleLayout circleLayout; private final mxOrganicLayout organicLayout; private final mxHierarchicalLayout hierarchicalLayout; - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; private final PinnedAccountModel pinnedAccountModel = new PinnedAccountModel(); private final LockedVertexModel lockedVertexModel = new LockedVertexModel(); - + public VisualizationPanel() { initComponents(); - + graph = new CommunicationsGraph(pinnedAccountModel, lockedVertexModel); - + fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); circleLayout = new mxCircleLayoutImpl(graph); organicLayout = new mxOrganicLayoutImpl(graph); hierarchicalLayout = new mxHierarchicalLayoutImpl(graph); - + graphComponent = new mxGraphComponent(graph); graphComponent.setAutoExtend(true); graphComponent.setAutoScroll(true); @@ -164,14 +165,14 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider //install rubber band other handlers rubberband = new mxRubberband(graphComponent); - + lockedVertexModel.registerhandler(this); - + final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt) -> zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale())); graph.getView().addListener(mxEvent.SCALE, scaleListener); graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, scaleListener); - + graphComponent.getGraphControl().addMouseWheelListener(new MouseAdapter() { /** * Translate mouse wheel events into zooming. @@ -188,7 +189,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } }); - + graphComponent.getGraphControl().addMouseListener(new MouseAdapter() { /** * Right click handler: show context menu. @@ -203,13 +204,13 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (cellAt != null && cellAt.isVertex()) { final JPopupMenu jPopupMenu = new JPopupMenu(); final AccountDeviceInstanceKey adiKey = (AccountDeviceInstanceKey) cellAt.getValue(); - + Set selectedVertices = Stream.of(graph.getSelectionModel().getCells()) .map(mxCell.class::cast) .filter(mxCell::isVertex) .collect(Collectors.toSet()); - + if (lockedVertexModel.isVertexLocked(cellAt)) { jPopupMenu.add(new JMenuItem(new UnlockAction(selectedVertices))); } else { @@ -225,13 +226,13 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } - + }); - + final MessageBrowser messageBrowser = new MessageBrowser(vizEM, gacEM); - + splitPane.setRightComponent(messageBrowser); - + proxyLookup = new ProxyLookup( ExplorerUtils.createLookup(vizEM, getActionMap()), messageBrowser.getLookup() @@ -241,16 +242,16 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getSelectionModel().addListener(mxEvent.CHANGE, new SelectionListener()); final mxEventSource.mxIEventListener undoListener = (Object sender, mxEventObject evt) -> undoManager.undoableEditHappened((mxUndoableEdit) evt.getProperty("edit")); - + graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); } - + @Override public Lookup getLookup() { return proxyLookup; } - + @Subscribe void handle(LockedVertexModel.VertexLockEvent event) { final Set vertices = event.getVertices(); @@ -263,7 +264,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graphComponent.redraw(state); }); } - + @Subscribe void handle(final CVTEvents.UnpinAccountsEvent pinEvent) { graph.getModel().beginUpdate(); @@ -273,7 +274,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider // Updates the display graph.getModel().endUpdate(); } - + @Subscribe void handle(final CVTEvents.PinAccountsEvent pinEvent) { graph.getModel().beginUpdate(); @@ -285,7 +286,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider // Updates the display graph.getModel().endUpdate(); } - + @Subscribe void handle(final CVTEvents.FilterChangeEvent filterChangeEvent) { graph.getModel().beginUpdate(); @@ -295,7 +296,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider // Updates the display graph.getModel().endUpdate(); } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void rebuildGraph() { if (pinnedAccountModel.isEmpty()) { @@ -308,7 +309,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (worker != null) { worker.cancel(true); } - + final CancelationListener cancelationListener = new CancelationListener(); final ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, "Loading Visualization", new String[]{CANCEL}, CANCEL, cancelationListener); worker = graph.rebuild(progress, commsManager, currentFilter); @@ -319,20 +320,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.resetGraph(); rebuildGraph(); } else { - morph(fastOrganicLayout); + animateLayout(fastOrganicLayout); } } }); - + worker.execute(); } } - + @Override public void addNotify() { super.addNotify(); windowAncestor = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, this); - + try { commsManager = Case.getOpenCase().getSleuthkitCase().getCommunicationsManager(); } catch (TskCoreException ex) { @@ -340,7 +341,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } catch (NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Can't get CommunicationsManager when there is no case open.", ex); } - + Case.addEventTypeSubscriber(EnumSet.of(CURRENT_CASE), evt -> { graph.getModel().beginUpdate(); try { @@ -605,7 +606,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider }//GEN-LAST:event_zoomOutButtonActionPerformed private void circleLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_circleLayoutButtonActionPerformed - morph(circleLayout); + animateLayout(circleLayout); }//GEN-LAST:event_circleLayoutButtonActionPerformed private void organicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_organicLayoutButtonActionPerformed @@ -613,11 +614,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider }//GEN-LAST:event_organicLayoutButtonActionPerformed private void fastOrganicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_fastOrganicLayoutButtonActionPerformed - morph(fastOrganicLayout); + animateLayout(fastOrganicLayout); }//GEN-LAST:event_fastOrganicLayoutButtonActionPerformed private void hierarchyLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_hierarchyLayoutButtonActionPerformed - morph(hierarchicalLayout); + animateLayout(hierarchicalLayout); }//GEN-LAST:event_hierarchyLayoutButtonActionPerformed private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed @@ -631,44 +632,44 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider setCursor(Cursor.getDefaultCursor()); }//GEN-LAST:event_clearVizButtonActionPerformed - + private void applyOrganicLayout(int iterations) { organicLayout.setMaxIterations(iterations); - morph(organicLayout); + animateLayout(organicLayout); } - + private void fitGraph() { graphComponent.zoomTo(1, true); mxPoint translate = graph.getView().getTranslate(); if (translate == null || Double.isNaN(translate.getX()) || Double.isNaN(translate.getY())) { translate = new mxPoint(); } - + mxRectangle boundsForCells = graph.getCellBounds(graph.getDefaultParent(), true, true, true); if (boundsForCells == null || Double.isNaN(boundsForCells.getWidth()) || Double.isNaN(boundsForCells.getHeight())) { boundsForCells = new mxRectangle(0, 0, 1, 1); } final mxPoint mxPoint = new mxPoint(translate.getX() - boundsForCells.getX(), translate.getY() - boundsForCells.getY()); - + graph.cellsMoved(graph.getChildCells(graph.getDefaultParent()), mxPoint.getX(), mxPoint.getY(), false, false); - + boundsForCells = graph.getCellBounds(graph.getDefaultParent(), true, true, true); if (boundsForCells == null || Double.isNaN(boundsForCells.getWidth()) || Double.isNaN(boundsForCells.getHeight())) { boundsForCells = new mxRectangle(0, 0, 1, 1); } - + final Dimension size = graphComponent.getSize(); final double widthFactor = size.getWidth() / boundsForCells.getWidth(); - + graphComponent.zoom(widthFactor); - + } - + @NbBundle.Messages({"Visualization.computingLayout=Computing Layout"}) - private void morph(mxIGraphLayout layout) { + private void animateLayout(mxIGraphLayout layout) { // layout using morphing graph.getModel().beginUpdate(); - + CancelationListener cancelationListener = new CancelationListener(); ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, Bundle.Visualization_computingLayout(), new String[]{CANCEL}, CANCEL, cancelationListener); @@ -685,10 +686,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider @Override public void updateAnimation() { fireEvent(new mxEventObject(mxEvent.EXECUTE)); - super.updateAnimation(); //To change body of generated methods, choose Tools | Templates. + super.updateAnimation(); } - }; + morph.addListener(mxEvent.EXECUTE, (Object sender, mxEventObject evt) -> { if (isCancelled()) { morph.stopAnimation(); @@ -703,10 +704,19 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } progress.finish(); }); - + morph.startAnimation(); return null; - + } + + @Override + protected void done() { + super.done(); + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, "Layout interupted", ex); + } } }; cancelationListener.configure(morphWorker, progress); @@ -740,7 +750,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider * changes in selection. */ final private class SelectionListener implements mxEventSource.mxIEventListener { - + @SuppressWarnings("unchecked") @Override public void invoke(Object sender, mxEventObject evt) { @@ -770,7 +780,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider adis.add((AccountDeviceInstanceKey) cell.getValue()); } } - + rootNode = SelectionNode.createFromAccountsAndRelationships(relationshipSources, adis, currentFilter, commsManager); selectedNodes = new Node[]{rootNode}; } @@ -782,19 +792,19 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } - + final private class mxFastOrganicLayoutImpl extends mxFastOrganicLayout { - + mxFastOrganicLayoutImpl(mxGraph graph) { super(graph); } - + @Override public boolean isVertexIgnored(Object vertex) { return super.isVertexIgnored(vertex) || lockedVertexModel.isVertexLocked((mxCell) vertex); } - + @Override public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { @@ -804,20 +814,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } - + final private class mxCircleLayoutImpl extends mxCircleLayout { - + mxCircleLayoutImpl(mxGraph graph) { super(graph); setResetEdges(true); } - + @Override public boolean isVertexIgnored(Object vertex) { return super.isVertexIgnored(vertex) || lockedVertexModel.isVertexLocked((mxCell) vertex); } - + @Override public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { @@ -827,20 +837,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } - + final private class mxOrganicLayoutImpl extends mxOrganicLayout { - + mxOrganicLayoutImpl(mxGraph graph) { super(graph); setResetEdges(true); } - + @Override public boolean isVertexIgnored(Object vertex) { return super.isVertexIgnored(vertex) || lockedVertexModel.isVertexLocked((mxCell) vertex); } - + @Override public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { @@ -850,19 +860,19 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } - + final private class mxHierarchicalLayoutImpl extends mxHierarchicalLayout { - + mxHierarchicalLayoutImpl(mxGraph graph) { super(graph); } - + @Override public boolean isVertexIgnored(Object vertex) { return super.isVertexIgnored(vertex) || lockedVertexModel.isVertexLocked((mxCell) vertex); } - + @Override public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x,y variable names are standard if (isVertexIgnored(vertex)) { @@ -877,15 +887,15 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider * Listener that closes a ModalDialogProgreessIndicator when invoked. */ final private class CancelationListener implements ActionListener { - + private Future cancellable; private ModalDialogProgressIndicator progress; - + void configure(Future cancellable, ModalDialogProgressIndicator progress) { this.cancellable = cancellable; this.progress = progress; } - + @Override public void actionPerformed(ActionEvent event) { progress.setCancelling("Cancelling..."); @@ -901,17 +911,17 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider "VisualizationPanel.unlockAction.singularText=Unlock Selected Account", "VisualizationPanel.unlockAction.pluralText=Unlock Selected Accounts",}) private final class UnlockAction extends AbstractAction { - + private final Set selectedVertices; - + UnlockAction(Set selectedVertices) { super(selectedVertices.size() > 1 ? Bundle.VisualizationPanel_unlockAction_pluralText() : Bundle.VisualizationPanel_unlockAction_singularText(), unlockIcon); this.selectedVertices = selectedVertices; } - + @Override - + public void actionPerformed(final ActionEvent event) { lockedVertexModel.unlock(selectedVertices); } @@ -924,15 +934,15 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider "VisualizationPanel.lockAction.singularText=Lock Selected Account", "VisualizationPanel.lockAction.pluralText=Lock Selected Accounts"}) private final class LockAction extends AbstractAction { - + private final Set selectedVertices; - + LockAction(Set selectedVertices) { super(selectedVertices.size() > 1 ? Bundle.VisualizationPanel_lockAction_pluralText() : Bundle.VisualizationPanel_lockAction_singularText(), lockIcon); this.selectedVertices = selectedVertices; } - + @Override public void actionPerformed(final ActionEvent event) { lockedVertexModel.lock(selectedVertices); From 662babede1bd431757f7979108d44cd4c395145b Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 9 Apr 2018 13:52:10 +0200 Subject: [PATCH 20/29] Revert "refactor to use LockedVertexLayoutWrapper" This reverts commit 08cc853fa8e8e447268ecde3c18f4f980508c11f. # Conflicts: # Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java # Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java --- .../communications/LockedVertexModel.java | 118 -------------- .../communications/VisualizationPanel.form | 6 +- .../communications/VisualizationPanel.java | 144 ++++++++++++++---- 3 files changed, 116 insertions(+), 152 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index 4a2b82dc43..251f6382f7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -20,14 +20,12 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.ImmutableSet; import com.google.common.eventbus.EventBus; -import com.mxgraph.layout.mxGraphLayout; import com.mxgraph.model.mxCell; import com.mxgraph.util.mxPoint; import com.mxgraph.util.mxRectangle; import com.mxgraph.view.mxGraph; import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Set; /** @@ -114,120 +112,4 @@ final class LockedVertexModel { this.locked = locked; } } - - mxGraphLayout createLockedVertexWrapper(mxGraphLayout layout) { - return new LockedVertexLayoutWrapper(layout, this); - } - - /** An mxGraphLayout that wrapps an other layout and ignores locked vertes. - * - * @param - */ - private static final class LockedVertexLayoutWrapper extends mxGraphLayout { - - private final mxGraphLayout wrappedLayout; - private final LockedVertexModel lockedVertexModel; - - /** - * - * - * @param layout The layout to wrap - * @param lockedVertexModel the value of lockedVertexModel2 - */ - private LockedVertexLayoutWrapper(mxGraphLayout layout, LockedVertexModel lockedVertexModel) { - super(layout.getGraph()); - this.lockedVertexModel = lockedVertexModel; - wrappedLayout = layout; - } - - @Override - public boolean isVertexIgnored(Object vertex) { - return wrappedLayout.isVertexIgnored(vertex) - || lockedVertexModel.isVertexLocked((mxCell) vertex); - } - - @Override - public mxRectangle setVertexLocation(Object vertex, double xCoord, double yCoord) { - if (isVertexIgnored(vertex)) { - return getVertexBounds(vertex); - } else { - return wrappedLayout.setVertexLocation(vertex, xCoord, yCoord); - } - } - - @Override - public void execute(Object parent) { - wrappedLayout.execute(parent); - } - - @Override - public void moveCell(Object cell, double xCoord, double yCoord) { - wrappedLayout.moveCell(cell, xCoord, yCoord); - } - - @Override - public mxGraph getGraph() { - return wrappedLayout.getGraph(); - } - - @Override - public Object getConstraint(Object key, Object cell) { - return wrappedLayout.getConstraint(key, cell); - } - - @Override - public Object getConstraint(Object key, Object cell, Object edge, boolean source) { - return wrappedLayout.getConstraint(key, cell, edge, source); - } - - @Override - public boolean isUseBoundingBox() { - return wrappedLayout.isUseBoundingBox(); - } - - @Override - public void setUseBoundingBox(boolean useBoundingBox) { - wrappedLayout.setUseBoundingBox(useBoundingBox); - } - - @Override - public boolean isVertexMovable(Object vertex) { - return wrappedLayout.isVertexMovable(vertex); - } - - @Override - public boolean isEdgeIgnored(Object edge) { - return wrappedLayout.isEdgeIgnored(edge); - } - - @Override - public void setEdgeStyleEnabled(Object edge, boolean value) { - wrappedLayout.setEdgeStyleEnabled(edge, value); - } - - @Override - public void setOrthogonalEdge(Object edge, boolean value) { - wrappedLayout.setOrthogonalEdge(edge, value); - } - - @Override - public mxPoint getParentOffset(Object parent) { - return wrappedLayout.getParentOffset(parent); - } - - @Override - public void setEdgePoints(Object edge, List points) { - wrappedLayout.setEdgePoints(edge, points); - } - - @Override - public mxRectangle getVertexBounds(Object vertex) { - return wrappedLayout.getVertexBounds(vertex); - } - - @Override - public void arrangeGroups(Object[] groups, int border) { - wrappedLayout.arrangeGroups(groups, border); - } - } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form index deae56fd17..a847f700c7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form @@ -11,7 +11,7 @@ - + @@ -106,7 +106,7 @@ - + @@ -120,7 +120,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index adcdecf7ba..25eea8cc98 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -23,7 +23,6 @@ import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxFastOrganicLayout; import com.mxgraph.layout.mxGraphLayout; -import com.mxgraph.layout.mxIGraphLayout; import com.mxgraph.layout.mxOrganicLayout; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxICell; @@ -38,6 +37,7 @@ import com.mxgraph.util.mxRectangle; import com.mxgraph.util.mxUndoManager; import com.mxgraph.util.mxUndoableEdit; import com.mxgraph.view.mxCellState; +import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxGraphView; import java.awt.BorderLayout; import java.awt.Color; @@ -133,11 +133,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxUndoManager undoManager = new mxUndoManager(); private final mxRubberband rubberband; //NOPMD We keep a referenec as insurance to prevent garbage collection - - private final mxGraphLayout fastOrganicLayout; - private final mxGraphLayout circleLayout; - private final mxGraphLayout organicLayout; - private final mxGraphLayout hierarchyLayout; + private final mxFastOrganicLayout fastOrganicLayout; + private final mxCircleLayout circleLayout; + private final mxOrganicLayout organicLayout; + private final mxHierarchicalLayout hierarchyLayout; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; @@ -193,19 +192,12 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); - fastOrganicLayout = lockedVertexModel.createLockedVertexWrapper(new mxFastOrganicLayout(graph)); - hierarchyLayout = lockedVertexModel.createLockedVertexWrapper(new mxHierarchicalLayout(graph)); - circleLayout = lockedVertexModel.createLockedVertexWrapper(new mxCircleLayout(graph) { - { - setResetEdges(true); - } - }); - organicLayout = lockedVertexModel.createLockedVertexWrapper(new mxOrganicLayout(graph) { - { - setResetEdges(true); - setMaxIterations(10); - } - }); + fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); + circleLayout = new mxCircleLayoutImpl(graph); + organicLayout = new mxOrganicLayoutImpl(graph); + organicLayout.setMaxIterations(10); + hierarchyLayout = new mxHierarchicalLayoutImpl(graph); + //local method to configure layout buttons BiConsumer configure = (layoutButton, layout) -> { layoutButtons.put(layout, layoutButton); @@ -502,7 +494,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider .add(hierarchyLayoutButton) .addPreferredGap(LayoutStyle.RELATED) .add(circleLayoutButton) - .addPreferredGap(LayoutStyle.UNRELATED) + .addPreferredGap(LayoutStyle.RELATED) .add(jSeparator2, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(jLabel2) @@ -516,7 +508,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider .add(zoomActualButton, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(fitZoomButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(12, Short.MAX_VALUE)) ); toolbarLayout.setVerticalGroup(toolbarLayout.createParallelGroup(GroupLayout.LEADING) .add(toolbarLayout.createSequentialGroup() @@ -577,18 +569,18 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().beginUpdate(); CancelationListener cancelationListener = new CancelationListener(); - ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, + ModalDialogProgressIndicator progressIndicator = new ModalDialogProgressIndicator(windowAncestor, Bundle.Visualization_computingLayout(), new String[]{CANCEL}, CANCEL, cancelationListener); SwingWorker morphWorker = new SwingWorker() { - int i = 0; + int progress = 0; int max = 100; @Override protected Void doInBackground() { - progress.start(Bundle.Visualization_computingLayout()); + progressIndicator.start(Bundle.Visualization_computingLayout()); layout.execute(graph.getDefaultParent()); if (isCancelled()) { - progress.finish(); + progressIndicator.finish(); return null; } @@ -600,10 +592,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (isCancelled()) { stopAnimation(); } else { - i++; - progress.switchToDeterminate(Bundle.Visualization_computingLayout(), i, max); - if ( i >= max *3.0/4.0){ - max *=2; + progress++; + progressIndicator.switchToDeterminate(Bundle.Visualization_computingLayout(), progress, max); + if (progress >= max * 3.0 / 4.0) { + max *= 2; } } } @@ -616,7 +608,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } else { fitGraph(); } - progress.finish(); + progressIndicator.finish(); }); morph.startAnimation(); @@ -633,7 +625,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } }; - cancelationListener.configure(morphWorker, progress); + cancelationListener.configure(morphWorker, progressIndicator); morphWorker.execute(); } @@ -746,6 +738,96 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + final private class mxFastOrganicLayoutImpl extends mxFastOrganicLayout { + + mxFastOrganicLayoutImpl(mxGraph graph) { + super(graph); + } + + @Override + public boolean isVertexIgnored(Object vertex) { + return super.isVertexIgnored(vertex) + || lockedVertexModel.isVertexLocked((mxCell) vertex); + } + + @Override + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names + if (isVertexIgnored(vertex)) { + return getVertexBounds(vertex); + } else { + return super.setVertexLocation(vertex, x, y); + } + } + } + + final private class mxCircleLayoutImpl extends mxCircleLayout { + + mxCircleLayoutImpl(mxGraph graph) { + super(graph); + setResetEdges(true); + } + + @Override + public boolean isVertexIgnored(Object vertex) { + return super.isVertexIgnored(vertex) + || lockedVertexModel.isVertexLocked((mxCell) vertex); + } + + @Override + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names + if (isVertexIgnored(vertex)) { + return getVertexBounds(vertex); + } else { + return super.setVertexLocation(vertex, x, y); + } + } + } + + final private class mxOrganicLayoutImpl extends mxOrganicLayout { + + mxOrganicLayoutImpl(mxGraph graph) { + super(graph); + setResetEdges(true); + } + + @Override + public boolean isVertexIgnored(Object vertex) { + return super.isVertexIgnored(vertex) + || lockedVertexModel.isVertexLocked((mxCell) vertex); + } + + @Override + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names + if (isVertexIgnored(vertex)) { + return getVertexBounds(vertex); + } else { + return super.setVertexLocation(vertex, x, y); + } + } + } + + final private class mxHierarchicalLayoutImpl extends mxHierarchicalLayout { + + mxHierarchicalLayoutImpl(mxGraph graph) { + super(graph); + } + + @Override + public boolean isVertexIgnored(Object vertex) { + return super.isVertexIgnored(vertex) + || lockedVertexModel.isVertexLocked((mxCell) vertex); + } + + @Override + public mxRectangle setVertexLocation(Object vertex, double x, double y) { //NOPMD x, y are standard coordinate names + if (isVertexIgnored(vertex)) { + return getVertexBounds(vertex); + } else { + return super.setVertexLocation(vertex, x, y); + } + } + } + /** * Listener that closses the given ModalDialogProgressIndicator and cancels * the future. From f3f650c2f364c8abb45faf28e93f83f15c4d4f65 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 9 Apr 2018 13:54:40 +0200 Subject: [PATCH 21/29] fix codacy issues --- .../autopsy/communications/VisualizationPanel.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 25eea8cc98..c76427aa62 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -738,6 +738,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Extension of mxFastOrganicLayout that ignores locked vertices. + */ final private class mxFastOrganicLayoutImpl extends mxFastOrganicLayout { mxFastOrganicLayoutImpl(mxGraph graph) { @@ -760,6 +763,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Extension of mxCircleLayout that ignores locked vertices. + */ final private class mxCircleLayoutImpl extends mxCircleLayout { mxCircleLayoutImpl(mxGraph graph) { @@ -783,6 +789,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Extension of mxOrganicLayout that ignores locked vertices. + */ final private class mxOrganicLayoutImpl extends mxOrganicLayout { mxOrganicLayoutImpl(mxGraph graph) { @@ -806,6 +815,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Extension of mxHierarchicalLayout that ignores locked vertices. + */ final private class mxHierarchicalLayoutImpl extends mxHierarchicalLayout { mxHierarchicalLayoutImpl(mxGraph graph) { From 7a73afd647c990f3c03a9df1cb9b354894574573 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Mon, 9 Apr 2018 10:36:26 -0400 Subject: [PATCH 22/29] Fixed return type issue. --- .../src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 10a7bef73c..b988dd4e49 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -83,7 +83,7 @@ public class KeywordSearch { throw new AssertionError(); } - static Logger getTikaLogger() { + static java.util.logging.Logger getTikaLogger() { return tikaLogger; } From 206e599037ba390ad28c9ffc76685a380aaa2909 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 9 Apr 2018 16:43:26 +0200 Subject: [PATCH 23/29] remove animation of layout and handle errors. --- .../autopsy/communications/Bundle.properties | 5 +- .../communications/CommunicationsGraph.java | 2 +- .../communications/LockedVertexModel.java | 4 + .../communications/VisualizationPanel.java | 143 +++++++++--------- 4 files changed, 77 insertions(+), 77 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index ea3049f895..358971eaa8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -20,9 +20,6 @@ CVTTopComponent.vizPanel.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle_1=Browse CVTTopComponent.browseVisualizeTabPane.AccessibleContext.accessibleName=Visualize CVTTopComponent.vizPanel.TabConstraints.tabTitle_1=Visualize -VisualizationPanel.jButton6.text=Hierarchy -VisualizationPanel.jButton7.text=Circle -VisualizationPanel.jButton8.text=Organic VisualizationPanel.fitGraphButton.text= VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin. VisualizationPanel.jLabel1.text=Layouts: @@ -39,5 +36,5 @@ VisualizationPanel.zoomOutButton.text= VisualizationPanel.circleLayoutButton.text=Circle VisualizationPanel.organicLayoutButton.text=Organic VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic -VisualizationPanel.hierarchyLayoutButton.text=Hierarchy +VisualizationPanel.hierarchyLayoutButton.text=Hierarchical VisualizationPanel.clearVizButton.text_1=Clear Viz. diff --git a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java index 2dadb888b9..716d00656c 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java @@ -264,7 +264,7 @@ final class CommunicationsGraph extends mxGraph { for (final AccountDeviceInstanceKey adiKey : pinnedAccountModel.getPinnedAccounts()) { if (isCancelled()) { break; - } + } //get accounts related to pinned account final List relatedAccountDeviceInstances = commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter); diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index 251f6382f7..d8c2a28091 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -83,6 +83,10 @@ final class LockedVertexModel { lockedVertices.clear(); } + boolean isEmpty() { + return lockedVertices.isEmpty(); + } + /** * Event that represents a change in the locked state of one or more * vertices. diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index c76427aa62..325fbd51b9 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -22,13 +22,12 @@ import com.google.common.eventbus.Subscribe; import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxFastOrganicLayout; -import com.mxgraph.layout.mxGraphLayout; +import com.mxgraph.layout.mxIGraphLayout; import com.mxgraph.layout.mxOrganicLayout; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxICell; import com.mxgraph.swing.handler.mxRubberband; import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.swing.util.mxMorphing; import com.mxgraph.util.mxEvent; import com.mxgraph.util.mxEventObject; import com.mxgraph.util.mxEventSource; @@ -90,6 +89,7 @@ import org.openide.util.lookup.ProxyLookup; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator; import org.sleuthkit.datamodel.CommunicationsFilter; @@ -133,18 +133,14 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxUndoManager undoManager = new mxUndoManager(); private final mxRubberband rubberband; //NOPMD We keep a referenec as insurance to prevent garbage collection - private final mxFastOrganicLayout fastOrganicLayout; - private final mxCircleLayout circleLayout; - private final mxOrganicLayout organicLayout; - private final mxHierarchicalLayout hierarchyLayout; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; private final PinnedAccountModel pinnedAccountModel = new PinnedAccountModel(); private final LockedVertexModel lockedVertexModel = new LockedVertexModel(); - private final Map layoutButtons = new HashMap<>(); - private mxGraphLayout currentLayout; + private final Map layoutButtons = new HashMap<>(); + private NamedGraphLayout currentLayout; public VisualizationPanel() { initComponents(); @@ -192,14 +188,14 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); - fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); - circleLayout = new mxCircleLayoutImpl(graph); - organicLayout = new mxOrganicLayoutImpl(graph); + FastOrganicLayoutImpl fastOrganicLayout = new FastOrganicLayoutImpl(graph); + CircleLayoutImpl circleLayout = new CircleLayoutImpl(graph); + OrganicLayoutImpl organicLayout = new OrganicLayoutImpl(graph); organicLayout.setMaxIterations(10); - hierarchyLayout = new mxHierarchicalLayoutImpl(graph); + HierarchicalLayoutImpl hierarchyLayout = new HierarchicalLayoutImpl(graph); //local method to configure layout buttons - BiConsumer configure = (layoutButton, layout) -> { + BiConsumer configure = (layoutButton, layout) -> { layoutButtons.put(layout, layoutButton); layoutButton.addActionListener(event -> applyLayout(layout)); }; @@ -556,77 +552,52 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider /** * Apply the given layout. The given layout becomes the current layout. The - * layout is computed in the background and applied via mxMorphing. + * layout is computed in the background. * * @param layout The layout to apply. */ - @NbBundle.Messages({"Visualization.computingLayout=Computing Layout"}) - private void applyLayout(mxGraphLayout layout) { + @NbBundle.Messages({"VisualizationPanel.computingLayout=Computing Layout", + "# {0} - layout name", + "VisualizationPanel.layoutFailWithLockedVertices.text={0} layout failed with locked vertices. Unlock some vertices or try a different layout.", + "# {0} - layout name", + "VisualizationPanel.layoutFail.text={0} layout failed. Try a different layout."}) + private void applyLayout(NamedGraphLayout layout) { currentLayout = layout; layoutButtons.forEach((layoutKey, button) -> button.setFont(button.getFont().deriveFont(layoutKey == layout ? Font.BOLD : Font.PLAIN))); - // layout using morphing - graph.getModel().beginUpdate(); - CancelationListener cancelationListener = new CancelationListener(); - ModalDialogProgressIndicator progressIndicator = new ModalDialogProgressIndicator(windowAncestor, - Bundle.Visualization_computingLayout(), new String[]{CANCEL}, CANCEL, cancelationListener); - SwingWorker morphWorker = new SwingWorker() { - int progress = 0; - int max = 100; + ModalDialogProgressIndicator progressIndicator = new ModalDialogProgressIndicator(windowAncestor, Bundle.VisualizationPanel_computingLayout()); + progressIndicator.start(Bundle.VisualizationPanel_computingLayout()); + new SwingWorker() { @Override protected Void doInBackground() { - progressIndicator.start(Bundle.Visualization_computingLayout()); - layout.execute(graph.getDefaultParent()); - if (isCancelled()) { - progressIndicator.finish(); - return null; - } - - mxMorphing morph = new mxMorphing(graphComponent, 20, 1.2, 20) { - @Override - public void updateAnimation() { - fireEvent(new mxEventObject(mxEvent.EXECUTE)); - super.updateAnimation(); - if (isCancelled()) { - stopAnimation(); - } else { - progress++; - progressIndicator.switchToDeterminate(Bundle.Visualization_computingLayout(), progress, max); - if (progress >= max * 3.0 / 4.0) { - max *= 2; - } - } - } - }; - - morph.addListener(mxEvent.DONE, (Object sender, mxEventObject event) -> { + graph.getModel().beginUpdate(); + try { + layout.execute(graph.getDefaultParent()); + } finally { graph.getModel().endUpdate(); - if (isCancelled()) { - undoManager.undo(); - } else { - fitGraph(); - } progressIndicator.finish(); - }); - - morph.startAnimation(); + } return null; } @Override protected void done() { - super.done(); try { get(); + fitGraph(); } catch (InterruptedException | ExecutionException ex) { - logger.log(Level.SEVERE, "Layout interupted", ex); + logger.log(Level.WARNING, "CVT graph layout failed.", ex); + if (lockedVertexModel.isEmpty()) { + MessageNotifyUtil.Message.error(Bundle.VisualizationPanel_layoutFail_text(layout.getDisplayName())); + } else { + MessageNotifyUtil.Message.error(Bundle.VisualizationPanel_layoutFailWithLockedVertices_text(layout.getDisplayName())); + } + undoManager.undo(); } } - }; - cancelationListener.configure(morphWorker, progressIndicator); - morphWorker.execute(); + }.execute(); } private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed @@ -662,9 +633,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider final Dimension size = graphComponent.getSize(); final double widthFactor = size.getWidth() / boundsForCells.getWidth(); + final double heightFactor = size.getHeight() / boundsForCells.getHeight(); - graphComponent.zoom(widthFactor); - + graphComponent.zoom((heightFactor + widthFactor) / 2.0); } @@ -738,12 +709,20 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } + /** + * Extend mxIGraphLayout with a getDisplayName method, + */ + private interface NamedGraphLayout extends mxIGraphLayout { + + String getDisplayName(); + } + /** * Extension of mxFastOrganicLayout that ignores locked vertices. */ - final private class mxFastOrganicLayoutImpl extends mxFastOrganicLayout { + final private class FastOrganicLayoutImpl extends mxFastOrganicLayout implements NamedGraphLayout { - mxFastOrganicLayoutImpl(mxGraph graph) { + FastOrganicLayoutImpl(mxGraph graph) { super(graph); } @@ -761,14 +740,19 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider return super.setVertexLocation(vertex, x, y); } } + + @Override + public String getDisplayName() { + return "Fast Organic"; + } } /** * Extension of mxCircleLayout that ignores locked vertices. */ - final private class mxCircleLayoutImpl extends mxCircleLayout { + final private class CircleLayoutImpl extends mxCircleLayout implements NamedGraphLayout { - mxCircleLayoutImpl(mxGraph graph) { + CircleLayoutImpl(mxGraph graph) { super(graph); setResetEdges(true); } @@ -787,14 +771,19 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider return super.setVertexLocation(vertex, x, y); } } + + @Override + public String getDisplayName() { + return "Circle"; + } } /** * Extension of mxOrganicLayout that ignores locked vertices. */ - final private class mxOrganicLayoutImpl extends mxOrganicLayout { + final private class OrganicLayoutImpl extends mxOrganicLayout implements NamedGraphLayout { - mxOrganicLayoutImpl(mxGraph graph) { + OrganicLayoutImpl(mxGraph graph) { super(graph); setResetEdges(true); } @@ -813,14 +802,19 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider return super.setVertexLocation(vertex, x, y); } } + + @Override + public String getDisplayName() { + return "Organic"; + } } /** * Extension of mxHierarchicalLayout that ignores locked vertices. */ - final private class mxHierarchicalLayoutImpl extends mxHierarchicalLayout { + final private class HierarchicalLayoutImpl extends mxHierarchicalLayout implements NamedGraphLayout { - mxHierarchicalLayoutImpl(mxGraph graph) { + HierarchicalLayoutImpl(mxGraph graph) { super(graph); } @@ -838,6 +832,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider return super.setVertexLocation(vertex, x, y); } } + + @Override + public String getDisplayName() { + return "Hierarchical"; + } } /** From 4379f81e176d3098b59411035d38405fdc052013 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 9 Apr 2018 16:51:59 +0200 Subject: [PATCH 24/29] call fitGraph() within transaction to avoid 'blip' --- .../sleuthkit/autopsy/communications/LockedVertexModel.java | 3 --- .../sleuthkit/autopsy/communications/VisualizationPanel.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java index d8c2a28091..7d8b8c083d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/LockedVertexModel.java @@ -21,9 +21,6 @@ package org.sleuthkit.autopsy.communications; import com.google.common.collect.ImmutableSet; import com.google.common.eventbus.EventBus; import com.mxgraph.model.mxCell; -import com.mxgraph.util.mxPoint; -import com.mxgraph.util.mxRectangle; -import com.mxgraph.view.mxGraph; import java.util.Collection; import java.util.HashSet; import java.util.Set; diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 325fbd51b9..4f6b53ae39 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -575,6 +575,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().beginUpdate(); try { layout.execute(graph.getDefaultParent()); + fitGraph(); } finally { graph.getModel().endUpdate(); progressIndicator.finish(); @@ -586,7 +587,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider protected void done() { try { get(); - fitGraph(); } catch (InterruptedException | ExecutionException ex) { logger.log(Level.WARNING, "CVT graph layout failed.", ex); if (lockedVertexModel.isEmpty()) { From 42988f20bbdfd2900d8419015d0be04c9d93d5eb Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 10 Apr 2018 13:45:38 -0400 Subject: [PATCH 25/29] Fix compile error in KeywordSearch.java --- .../src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java index 10a7bef73c..b988dd4e49 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearch.java @@ -83,7 +83,7 @@ public class KeywordSearch { throw new AssertionError(); } - static Logger getTikaLogger() { + static java.util.logging.Logger getTikaLogger() { return tikaLogger; } From aff1f64ced8d0063c77dccc79dbc2b1fbaa47c13 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Tue, 10 Apr 2018 22:41:06 -0400 Subject: [PATCH 26/29] Added more logging and status --- .../volatilityDSP/VolatilityProcessor.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/VolatilityProcessor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/VolatilityProcessor.java index fd285ae1aa..50246f5255 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/VolatilityProcessor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/VolatilityProcessor.java @@ -136,7 +136,6 @@ class VolatilityProcessor { break; } String pluginToRun = pluginsToRun.get(i); - progressMonitor.setProgressText(Bundle.VolatilityProcessor_progressMessage_runningImageInfo(pluginToRun)); runVolatilityPlugin(pluginToRun); progressMonitor.setProgress(i); } @@ -172,6 +171,8 @@ class VolatilityProcessor { "VolatilityProcessor_exceptionMessage_errorIndexingOutput=Error indexing output for {0} plugin" }) private void runVolatilityPlugin(String pluginToRun) throws VolatilityProcessorException { + progressMonitor.setProgressText("Running module " + pluginToRun); + List commandLine = new ArrayList<>(); commandLine.add("\"" + executableFile + "\""); //NON-NLS File memoryImage = new File(memoryImagePath); @@ -314,6 +315,8 @@ class VolatilityProcessor { String filePath = volfile.getParent(); + logger.log(Level.INFO, "Looking up file " + fileName + " at path " + filePath); + try { List resolvedFiles; if (filePath == null) { @@ -333,12 +336,13 @@ class VolatilityProcessor { } fileName += ".%"; //NON-NLS + logger.log(Level.INFO, "Looking up file (extension wildcard) " + fileName + " at path " + filePath); + if (filePath == null) { resolvedFiles = fileManager.findFiles(fileName); //NON-NLS } else { resolvedFiles = fileManager.findFiles(fileName, filePath); //NON-NLS } - } if (resolvedFiles.isEmpty()) { @@ -387,6 +391,7 @@ class VolatilityProcessor { * @param pluginOutputFile File that contains the output to parse. */ private void createArtifactsFromPluginOutput(String pluginName, File pluginOutputFile) throws VolatilityProcessorException { + progressMonitor.setProgressText("Parsing module " + pluginName); Set fileSet = null; switch (pluginName) { case "dlllist": //NON-NLS @@ -421,6 +426,7 @@ class VolatilityProcessor { } if (fileSet != null && !fileSet.isEmpty()) { + progressMonitor.setProgressText("Flagging files from module " + pluginName); flagFiles(fileSet, pluginName); } } From 2d99a3dbd4fb2e0f949b5ddceb355ea49cef6ad4 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 11 Apr 2018 11:12:32 -0400 Subject: [PATCH 27/29] Switched to 'java.util' Logger. --- Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java b/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java index b1ff751b77..96f7d18fa3 100644 --- a/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java +++ b/Testing/src/org/sleuthkit/autopsy/testing/AutopsyTestCases.java @@ -32,6 +32,7 @@ import java.util.Date; import java.util.List; import java.util.Random; import java.util.logging.Level; +import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JDialog; import javax.swing.text.JTextComponent; @@ -57,7 +58,6 @@ import org.netbeans.jemmy.operators.JTreeOperator; import org.netbeans.jemmy.operators.JTreeOperator.NoSuchPathException; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.core.UserPreferencesException; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.datamodel.CaseDbConnectionInfo; From e32348590ef912384dddb35446f84c7f6c832938 Mon Sep 17 00:00:00 2001 From: rishwanth1995 Date: Wed, 11 Apr 2018 11:48:42 -0400 Subject: [PATCH 28/29] reduce verbosity of ant build in travis --- .travis.yml | 7 ++++--- Core/build.xml | 2 +- CoreLibs/build.xml | 2 +- Experimental/build.xml | 2 +- KeywordSearch/build.xml | 2 +- RecentActivity/build.xml | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 90b51996f9..6aaaa910fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,10 @@ install: - sudo apt-get install testdisk - cd sleuthkit/sleuthkit - sh install-sleuthkit.sh -script: +script: + - set -e - cd $TRAVIS_BUILD_DIR/ - - ant build + - ant -q build > /dev/null - cd Core/ - - xvfb-run ant test + - xvfb-run ant -q test > /dev/null diff --git a/Core/build.xml b/Core/build.xml index 3555ff0711..90b588bbc3 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -91,7 +91,7 @@ - + diff --git a/CoreLibs/build.xml b/CoreLibs/build.xml index 4084652c2c..f4c8cf0844 100644 --- a/CoreLibs/build.xml +++ b/CoreLibs/build.xml @@ -23,7 +23,7 @@ - + diff --git a/Experimental/build.xml b/Experimental/build.xml index b3923a5c30..3264616a39 100644 --- a/Experimental/build.xml +++ b/Experimental/build.xml @@ -13,7 +13,7 @@ - + diff --git a/KeywordSearch/build.xml b/KeywordSearch/build.xml index 5fe021fff8..5066a8e051 100644 --- a/KeywordSearch/build.xml +++ b/KeywordSearch/build.xml @@ -29,7 +29,7 @@ - + diff --git a/RecentActivity/build.xml b/RecentActivity/build.xml index f64b4191ca..af346f58e7 100644 --- a/RecentActivity/build.xml +++ b/RecentActivity/build.xml @@ -23,7 +23,7 @@ - + From 8f48347669a7dd108daabad432545846dbfef890 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 11 Apr 2018 11:53:01 -0400 Subject: [PATCH 29/29] Switched to 'java.lang' Logger. --- .../src/org/sleuthkit/autopsy/testing/RegressionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java b/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java index 87a24f5c85..8f1ef48a4c 100644 --- a/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java +++ b/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java @@ -20,11 +20,11 @@ package org.sleuthkit.autopsy.testing; import java.io.File; import java.io.IOException; +import java.util.logging.Logger; import junit.framework.Test; import junit.framework.TestCase; import org.netbeans.jemmy.Timeouts; import org.netbeans.junit.NbModuleSuite; -import org.sleuthkit.autopsy.coreutils.Logger; /** * This test expects the following system properties to be set: img_path: The