From 3788efff78cdf50f809c9673cd60665e8101a2a6 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Tue, 19 Apr 2016 09:57:02 -0400 Subject: [PATCH 01/37] Made new file types detectable by file extension mismatch settings. --- .../FileExtMismatchSettingsPanel.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java index 56883ef119..64fee99b5a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java @@ -29,10 +29,10 @@ import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; -import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; /** @@ -422,7 +422,17 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel return; } - boolean mimeTypeDetectable = (null != fileTypeDetector) ? fileTypeDetector.isDetectable(newMime) : false; + FileTypeDetector detector; + try { + detector = new FileTypeDetector(); + } catch (FileTypeDetector.FileTypeDetectorInitException ex) { + mimeErrLabel.setForeground(Color.red); + mimeErrLabel.setText(NbBundle.getMessage(this.getClass(), + "FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable")); + logger.log(Level.WARNING, "Couldn't create file type detector for file ext mismatch settings.", ex); + return; + } + boolean mimeTypeDetectable = (null != detector) ? detector.isDetectable(newMime) : false; if (!mimeTypeDetectable) { mimeErrLabel.setForeground(Color.red); mimeErrLabel.setText(NbBundle.getMessage(this.getClass(), From 318c44276cb18ce91b0b988d4f6ff05d83a304ca Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 29 Apr 2016 13:47:35 -0400 Subject: [PATCH 02/37] Fixed expandability of global settings panels. --- .../FileExtMismatchSettingsPanel.form | 90 ++++++------- .../FileExtMismatchSettingsPanel.java | 75 +++++------ .../hashdatabase/HashLookupSettingsPanel.form | 32 +++-- .../hashdatabase/HashLookupSettingsPanel.java | 19 +-- .../InterestingItemDefsPanel.form | 111 +++++++++------- .../InterestingItemDefsPanel.java | 82 ++++++------ nbproject/platform.properties | 120 +----------------- 7 files changed, 218 insertions(+), 311 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form index 126d42e0af..53f27fc5d5 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form @@ -22,8 +22,8 @@ - - + + @@ -57,9 +57,9 @@ - - - + + + @@ -87,19 +87,18 @@ - - - - - - - - - - + - + + + + + + + + + @@ -108,21 +107,22 @@ - + - - - - - - - - + + + + + + + + + + + - - - + @@ -211,17 +211,18 @@ - + - - - - + + - + + + + @@ -231,17 +232,18 @@ - - - - - - - + + + + + + + + + + - - - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java index 4978eb3119..1acc8d0ace 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java @@ -211,16 +211,16 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addGroup(mimePanelLayout.createSequentialGroup() - .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel1) - .addGroup(mimePanelLayout.createSequentialGroup() - .addComponent(userTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(addTypeButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(removeTypeButton))) + .addComponent(jLabel1) .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(mimeErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(mimePanelLayout.createSequentialGroup() + .addComponent(userTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(addTypeButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(removeTypeButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(mimeErrLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); mimePanelLayout.setVerticalGroup( @@ -229,15 +229,15 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel .addContainerGap() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 374, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(removeTypeButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(userTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(addTypeButton))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(mimeErrLabel) + .addComponent(jScrollPane2) + .addGap(18, 18, 18) + .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(mimeErrLabel) + .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(removeTypeButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(mimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(userTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(addTypeButton)))) .addContainerGap()) ); @@ -283,15 +283,16 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(extensionPanelLayout.createSequentialGroup() .addComponent(extHeaderLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 324, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(37, Short.MAX_VALUE)) - .addComponent(extErrorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, extensionPanelLayout.createSequentialGroup() - .addComponent(userExtTextField) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(extensionPanelLayout.createSequentialGroup() + .addComponent(userExtTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(addExtButton) - .addGap(4, 4, 4) - .addComponent(removeExtButton)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(removeExtButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(extErrorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) ); extensionPanelLayout.setVerticalGroup( extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -299,14 +300,14 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel .addContainerGap() .addComponent(extHeaderLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 367, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(userExtTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(addExtButton) - .addComponent(removeExtButton)) - .addGap(5, 5, 5) - .addComponent(extErrorLabel) + .addComponent(jScrollPane3) + .addGap(18, 18, 18) + .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(extErrorLabel) + .addGroup(extensionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(userExtTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(addExtButton) + .addComponent(removeExtButton))) .addContainerGap()) ); @@ -324,8 +325,8 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() - .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 466, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(31, 31, 31)) + .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE) + .addContainerGap()) ); jScrollPane1.setViewportView(jPanel1); @@ -339,8 +340,8 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 482, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(18, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE) + .addGap(0, 0, 0)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.form index 5cd2c50c5e..a18286dac0 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.form @@ -83,9 +83,9 @@ - - - + + + @@ -106,16 +106,20 @@ - + - - + + - + + + + + + - @@ -180,14 +184,14 @@ - + - + @@ -239,16 +243,16 @@ - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java index 0eefefba17..090ca6b0d8 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashLookupSettingsPanel.java @@ -652,12 +652,15 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(createDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 137, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(importDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(importDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(1, 1, 1) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(10, 10, 10) @@ -751,14 +754,14 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan .addComponent(sendIngestMessagesCheckBox) .addGap(18, 18, 18) .addComponent(ingestWarningLabel)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 304, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(importDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(createDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(deleteDatabaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(33, Short.MAX_VALUE)) + .addGap(33, 33, 33)) ); jScrollPane2.setViewportView(jPanel1); @@ -775,8 +778,8 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 410, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 410, Short.MAX_VALUE) + .addGap(9, 9, 9)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.form index e55060f6a1..fb33bdbdd1 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.form @@ -30,14 +30,14 @@ - - + + - + @@ -66,13 +66,11 @@ - + - - - - + + @@ -81,36 +79,33 @@ - + - - - - - - - + + + - + - + - + + @@ -119,16 +114,17 @@ - + - - - + + + + - + @@ -144,18 +140,10 @@ - - - - - - - - @@ -177,51 +165,60 @@ + + + + + + + + - + - + - + - - - + + + + - + - + - + - + - - - + + + - + @@ -235,7 +232,7 @@ - + @@ -248,7 +245,7 @@ - + @@ -262,9 +259,10 @@ + - + @@ -405,6 +403,12 @@ + + + + + + @@ -778,6 +782,12 @@ + + + + + + @@ -805,6 +815,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.java index 61271fc54c..f107ab99f2 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemDefsPanel.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.modules.interestingitems; import java.awt.EventQueue; -import java.awt.Font; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -35,15 +34,13 @@ import javax.swing.JOptionPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.apache.tika.mime.MediaType; +import org.apache.tika.mime.MimeTypes; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; -import org.apache.tika.mime.MediaType; -import org.apache.tika.mime.MimeTypes; -import org.openide.util.Exceptions; -import org.sleuthkit.autopsy.coreutils.Logger; /** * A panel that allows a user to make interesting item definitions. @@ -482,12 +479,12 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp editRuleButton = new javax.swing.JButton(); rulesListLabel = new javax.swing.JLabel(); rulesListScrollPane = new javax.swing.JScrollPane(); - rulesList = new javax.swing.JList(); + rulesList = new javax.swing.JList<>(); setDescScrollPanel = new javax.swing.JScrollPane(); setDescriptionTextArea = new javax.swing.JTextArea(); editSetButton = new javax.swing.JButton(); setsListScrollPane = new javax.swing.JScrollPane(); - setsList = new javax.swing.JList(); + setsList = new javax.swing.JList<>(); fileNameExtensionRadioButton = new javax.swing.JRadioButton(); jLabel3 = new javax.swing.JLabel(); fileNameTextField = new javax.swing.JTextField(); @@ -510,7 +507,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp jScrollPane2 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); jLabel7 = new javax.swing.JLabel(); - mimeTypeComboBox = new javax.swing.JComboBox(); + mimeTypeComboBox = new javax.swing.JComboBox<>(); jLabel8 = new javax.swing.JLabel(); equalitySignComboBox = new javax.swing.JComboBox(); jSpinner1 = new javax.swing.JSpinner(); @@ -567,6 +564,8 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp setDescriptionTextArea.setFont(setDescriptionTextArea.getFont().deriveFont(setDescriptionTextArea.getFont().getStyle() & ~java.awt.Font.BOLD, 13)); setDescriptionTextArea.setLineWrap(true); setDescriptionTextArea.setRows(2); + setDescriptionTextArea.setMinimumSize(new java.awt.Dimension(10, 22)); + setDescriptionTextArea.setPreferredSize(new java.awt.Dimension(14, 40)); setDescScrollPanel.setViewportView(setDescriptionTextArea); editSetButton.setFont(editSetButton.getFont().deriveFont(editSetButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); @@ -706,6 +705,8 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp mimeTypeComboBox.setEditable(true); mimeTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] {""})); mimeTypeComboBox.setEnabled(false); + mimeTypeComboBox.setMinimumSize(new java.awt.Dimension(0, 20)); + mimeTypeComboBox.setPreferredSize(new java.awt.Dimension(12, 20)); org.openide.awt.Mnemonics.setLocalizedText(jLabel8, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.jLabel8.text")); // NOI18N @@ -713,6 +714,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp equalitySignComboBox.setEnabled(false); jSpinner1.setEnabled(false); + jSpinner1.setMinimumSize(new java.awt.Dimension(2, 20)); fileSizeUnitComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { Bundle.InterestingItemDefsPanel_bytes(), Bundle.InterestingItemDefsPanel_kiloBytes(), Bundle.InterestingItemDefsPanel_megaBytes(), Bundle.InterestingItemDefsPanel_gigaBytes() })); fileSizeUnitComboBox.setEnabled(false); @@ -725,9 +727,8 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(setsListLabel) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(setsListScrollPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE) - .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING)) + .addComponent(setsListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 314, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 314, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(newSetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -738,18 +739,15 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(12, 12, 12) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel1) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel2) - .addGap(27, 27, 27) + .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addGap(92, 92, 92) .addComponent(filesRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(dirsRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bothRadioButton) - .addGap(27, 27, 27)))) + .addComponent(bothRadioButton))) + .addGap(27, 27, 27)) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() @@ -759,20 +757,22 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel3) .addComponent(jLabel7) - .addComponent(jLabel8)) + .addComponent(jLabel8) + .addComponent(jLabel2)) .addGap(6, 6, 6)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(rulePathConditionTextField, javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jSpinner1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.Alignment.LEADING, 0, 245, Short.MAX_VALUE) + .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(8, 8, 8)) + .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(fileNameTextField))) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(360, 360, 360) @@ -783,15 +783,9 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addGroup(jPanel1Layout.createSequentialGroup() .addGap(360, 360, 360) .addComponent(ignoreKnownFilesCheckbox)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(360, 360, 360) - .addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(360, 360, 360) .addComponent(jLabel6)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(360, 360, 360) - .addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(360, 360, 360) .addComponent(newRuleButton) @@ -808,8 +802,14 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addComponent(fileNameExtensionRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(fileNameRegexCheckbox)) - .addComponent(rulePathConditionRegexCheckBox)))) - .addGap(20, 20, 20)) + .addComponent(rulePathConditionRegexCheckBox))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(360, 360, 360) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(setDescScrollPanel) + .addComponent(rulesListScrollPane)) + .addGap(7, 7, 7))) + .addGap(23, 23, 23)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -824,12 +824,13 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addGap(18, 18, 18) .addComponent(setsListLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(setsListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(setsListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(newSetButton) .addComponent(editSetButton) - .addComponent(deleteSetButton))) + .addComponent(deleteSetButton)) + .addGap(13, 13, 13)) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -841,7 +842,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(rulesListLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(rulesListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(newRuleButton) @@ -879,7 +880,8 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp .addComponent(jLabel8) .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(19, 19, 19))) .addContainerGap()) ); @@ -892,12 +894,12 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 728, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 34, Short.MAX_VALUE)) + .addComponent(jScrollPane1) + .addGap(34, 34, 34)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE) + .addComponent(jScrollPane1) ); }// //GEN-END:initComponents diff --git a/nbproject/platform.properties b/nbproject/platform.properties index 9d31c5e1e0..20ef8536b3 100644 --- a/nbproject/platform.properties +++ b/nbproject/platform.properties @@ -13,122 +13,4 @@ cluster.path=\ ${nbplatform.active.dir}/java:\ ${nbplatform.active.dir}/platform disabled.modules=\ - org.apache.tools.ant.module,\ - org.netbeans.api.debugger.jpda,\ - org.netbeans.api.java,\ - org.netbeans.api.maven,\ - org.netbeans.lib.nbjavac,\ - org.netbeans.libs.cglib,\ - org.netbeans.libs.javacapi,\ - org.netbeans.libs.javacimpl,\ - org.netbeans.libs.springframework,\ - org.netbeans.modules.ant.browsetask,\ - org.netbeans.modules.ant.debugger,\ - org.netbeans.modules.ant.freeform,\ - org.netbeans.modules.ant.grammar,\ - org.netbeans.modules.ant.kit,\ - org.netbeans.modules.beans,\ - org.netbeans.modules.classfile,\ - org.netbeans.modules.dbschema,\ - org.netbeans.modules.debugger.jpda,\ - org.netbeans.modules.debugger.jpda.ant,\ - org.netbeans.modules.debugger.jpda.js,\ - org.netbeans.modules.debugger.jpda.kit,\ - org.netbeans.modules.debugger.jpda.projects,\ - org.netbeans.modules.debugger.jpda.ui,\ - org.netbeans.modules.debugger.jpda.visual,\ - org.netbeans.modules.findbugs.installer,\ - org.netbeans.modules.form,\ - org.netbeans.modules.form.binding,\ - org.netbeans.modules.form.j2ee,\ - org.netbeans.modules.form.kit,\ - org.netbeans.modules.form.nb,\ - org.netbeans.modules.form.refactoring,\ - org.netbeans.modules.hibernate,\ - org.netbeans.modules.hibernate4lib,\ - org.netbeans.modules.hibernatelib,\ - org.netbeans.modules.hudson.ant,\ - org.netbeans.modules.hudson.maven,\ - org.netbeans.modules.i18n,\ - org.netbeans.modules.i18n.form,\ - org.netbeans.modules.j2ee.core.utilities,\ - org.netbeans.modules.j2ee.eclipselink,\ - org.netbeans.modules.j2ee.eclipselinkmodelgen,\ - org.netbeans.modules.j2ee.jpa.refactoring,\ - org.netbeans.modules.j2ee.jpa.verification,\ - org.netbeans.modules.j2ee.metadata,\ - org.netbeans.modules.j2ee.metadata.model.support,\ - org.netbeans.modules.j2ee.persistence,\ - org.netbeans.modules.j2ee.persistence.kit,\ - org.netbeans.modules.j2ee.persistenceapi,\ - org.netbeans.modules.java.api.common,\ - org.netbeans.modules.java.debug,\ - org.netbeans.modules.java.editor,\ - org.netbeans.modules.java.editor.lib,\ - org.netbeans.modules.java.examples,\ - org.netbeans.modules.java.freeform,\ - org.netbeans.modules.java.guards,\ - org.netbeans.modules.java.helpset,\ - org.netbeans.modules.java.hints,\ - org.netbeans.modules.java.hints.declarative,\ - org.netbeans.modules.java.hints.declarative.test,\ - org.netbeans.modules.java.hints.legacy.spi,\ - org.netbeans.modules.java.hints.test,\ - org.netbeans.modules.java.hints.ui,\ - org.netbeans.modules.java.j2sedeploy,\ - org.netbeans.modules.java.j2seembedded,\ - org.netbeans.modules.java.j2seplatform,\ - org.netbeans.modules.java.j2seprofiles,\ - org.netbeans.modules.java.j2seproject,\ - org.netbeans.modules.java.kit,\ - org.netbeans.modules.java.lexer,\ - org.netbeans.modules.java.metrics,\ - org.netbeans.modules.java.navigation,\ - org.netbeans.modules.java.platform,\ - org.netbeans.modules.java.preprocessorbridge,\ - org.netbeans.modules.java.project,\ - org.netbeans.modules.java.source,\ - org.netbeans.modules.java.source.ant,\ - org.netbeans.modules.java.source.queries,\ - org.netbeans.modules.java.source.queriesimpl,\ - org.netbeans.modules.java.sourceui,\ - org.netbeans.modules.java.testrunner,\ - org.netbeans.modules.javadoc,\ - org.netbeans.modules.javaee.injection,\ - org.netbeans.modules.javawebstart,\ - org.netbeans.modules.junit,\ - org.netbeans.modules.maven,\ - org.netbeans.modules.maven.checkstyle,\ - org.netbeans.modules.maven.coverage,\ - org.netbeans.modules.maven.embedder,\ - org.netbeans.modules.maven.grammar,\ - org.netbeans.modules.maven.graph,\ - org.netbeans.modules.maven.hints,\ - org.netbeans.modules.maven.indexer,\ - org.netbeans.modules.maven.junit,\ - org.netbeans.modules.maven.kit,\ - org.netbeans.modules.maven.model,\ - org.netbeans.modules.maven.osgi,\ - org.netbeans.modules.maven.persistence,\ - org.netbeans.modules.maven.refactoring,\ - org.netbeans.modules.maven.repository,\ - org.netbeans.modules.maven.search,\ - org.netbeans.modules.maven.spring,\ - org.netbeans.modules.nashorn.execution,\ - org.netbeans.modules.performance,\ - org.netbeans.modules.performance.java,\ - org.netbeans.modules.projectimport.eclipse.core,\ - org.netbeans.modules.projectimport.eclipse.j2se,\ - org.netbeans.modules.refactoring.java,\ - org.netbeans.modules.spellchecker.bindings.java,\ - org.netbeans.modules.spring.beans,\ - org.netbeans.modules.testng,\ - org.netbeans.modules.testng.ant,\ - org.netbeans.modules.testng.maven,\ - org.netbeans.modules.websvc.jaxws21,\ - org.netbeans.modules.websvc.jaxws21api,\ - org.netbeans.modules.websvc.saas.codegen.java,\ - org.netbeans.modules.whitelist,\ - org.netbeans.modules.xml.jaxb,\ - org.netbeans.modules.xml.tools.java,\ - org.netbeans.spi.java.hints \ No newline at end of file + org.netbeans.modules.junit From cf57ba0a3fbe61b4d91423c95135ddd055a68c45 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 29 Apr 2016 13:52:23 -0400 Subject: [PATCH 03/37] Fixed plat file. --- nbproject/platform.properties | 120 +++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/nbproject/platform.properties b/nbproject/platform.properties index 20ef8536b3..9d31c5e1e0 100644 --- a/nbproject/platform.properties +++ b/nbproject/platform.properties @@ -13,4 +13,122 @@ cluster.path=\ ${nbplatform.active.dir}/java:\ ${nbplatform.active.dir}/platform disabled.modules=\ - org.netbeans.modules.junit + org.apache.tools.ant.module,\ + org.netbeans.api.debugger.jpda,\ + org.netbeans.api.java,\ + org.netbeans.api.maven,\ + org.netbeans.lib.nbjavac,\ + org.netbeans.libs.cglib,\ + org.netbeans.libs.javacapi,\ + org.netbeans.libs.javacimpl,\ + org.netbeans.libs.springframework,\ + org.netbeans.modules.ant.browsetask,\ + org.netbeans.modules.ant.debugger,\ + org.netbeans.modules.ant.freeform,\ + org.netbeans.modules.ant.grammar,\ + org.netbeans.modules.ant.kit,\ + org.netbeans.modules.beans,\ + org.netbeans.modules.classfile,\ + org.netbeans.modules.dbschema,\ + org.netbeans.modules.debugger.jpda,\ + org.netbeans.modules.debugger.jpda.ant,\ + org.netbeans.modules.debugger.jpda.js,\ + org.netbeans.modules.debugger.jpda.kit,\ + org.netbeans.modules.debugger.jpda.projects,\ + org.netbeans.modules.debugger.jpda.ui,\ + org.netbeans.modules.debugger.jpda.visual,\ + org.netbeans.modules.findbugs.installer,\ + org.netbeans.modules.form,\ + org.netbeans.modules.form.binding,\ + org.netbeans.modules.form.j2ee,\ + org.netbeans.modules.form.kit,\ + org.netbeans.modules.form.nb,\ + org.netbeans.modules.form.refactoring,\ + org.netbeans.modules.hibernate,\ + org.netbeans.modules.hibernate4lib,\ + org.netbeans.modules.hibernatelib,\ + org.netbeans.modules.hudson.ant,\ + org.netbeans.modules.hudson.maven,\ + org.netbeans.modules.i18n,\ + org.netbeans.modules.i18n.form,\ + org.netbeans.modules.j2ee.core.utilities,\ + org.netbeans.modules.j2ee.eclipselink,\ + org.netbeans.modules.j2ee.eclipselinkmodelgen,\ + org.netbeans.modules.j2ee.jpa.refactoring,\ + org.netbeans.modules.j2ee.jpa.verification,\ + org.netbeans.modules.j2ee.metadata,\ + org.netbeans.modules.j2ee.metadata.model.support,\ + org.netbeans.modules.j2ee.persistence,\ + org.netbeans.modules.j2ee.persistence.kit,\ + org.netbeans.modules.j2ee.persistenceapi,\ + org.netbeans.modules.java.api.common,\ + org.netbeans.modules.java.debug,\ + org.netbeans.modules.java.editor,\ + org.netbeans.modules.java.editor.lib,\ + org.netbeans.modules.java.examples,\ + org.netbeans.modules.java.freeform,\ + org.netbeans.modules.java.guards,\ + org.netbeans.modules.java.helpset,\ + org.netbeans.modules.java.hints,\ + org.netbeans.modules.java.hints.declarative,\ + org.netbeans.modules.java.hints.declarative.test,\ + org.netbeans.modules.java.hints.legacy.spi,\ + org.netbeans.modules.java.hints.test,\ + org.netbeans.modules.java.hints.ui,\ + org.netbeans.modules.java.j2sedeploy,\ + org.netbeans.modules.java.j2seembedded,\ + org.netbeans.modules.java.j2seplatform,\ + org.netbeans.modules.java.j2seprofiles,\ + org.netbeans.modules.java.j2seproject,\ + org.netbeans.modules.java.kit,\ + org.netbeans.modules.java.lexer,\ + org.netbeans.modules.java.metrics,\ + org.netbeans.modules.java.navigation,\ + org.netbeans.modules.java.platform,\ + org.netbeans.modules.java.preprocessorbridge,\ + org.netbeans.modules.java.project,\ + org.netbeans.modules.java.source,\ + org.netbeans.modules.java.source.ant,\ + org.netbeans.modules.java.source.queries,\ + org.netbeans.modules.java.source.queriesimpl,\ + org.netbeans.modules.java.sourceui,\ + org.netbeans.modules.java.testrunner,\ + org.netbeans.modules.javadoc,\ + org.netbeans.modules.javaee.injection,\ + org.netbeans.modules.javawebstart,\ + org.netbeans.modules.junit,\ + org.netbeans.modules.maven,\ + org.netbeans.modules.maven.checkstyle,\ + org.netbeans.modules.maven.coverage,\ + org.netbeans.modules.maven.embedder,\ + org.netbeans.modules.maven.grammar,\ + org.netbeans.modules.maven.graph,\ + org.netbeans.modules.maven.hints,\ + org.netbeans.modules.maven.indexer,\ + org.netbeans.modules.maven.junit,\ + org.netbeans.modules.maven.kit,\ + org.netbeans.modules.maven.model,\ + org.netbeans.modules.maven.osgi,\ + org.netbeans.modules.maven.persistence,\ + org.netbeans.modules.maven.refactoring,\ + org.netbeans.modules.maven.repository,\ + org.netbeans.modules.maven.search,\ + org.netbeans.modules.maven.spring,\ + org.netbeans.modules.nashorn.execution,\ + org.netbeans.modules.performance,\ + org.netbeans.modules.performance.java,\ + org.netbeans.modules.projectimport.eclipse.core,\ + org.netbeans.modules.projectimport.eclipse.j2se,\ + org.netbeans.modules.refactoring.java,\ + org.netbeans.modules.spellchecker.bindings.java,\ + org.netbeans.modules.spring.beans,\ + org.netbeans.modules.testng,\ + org.netbeans.modules.testng.ant,\ + org.netbeans.modules.testng.maven,\ + org.netbeans.modules.websvc.jaxws21,\ + org.netbeans.modules.websvc.jaxws21api,\ + org.netbeans.modules.websvc.saas.codegen.java,\ + org.netbeans.modules.whitelist,\ + org.netbeans.modules.xml.jaxb,\ + org.netbeans.modules.xml.tools.java,\ + org.netbeans.spi.java.hints \ No newline at end of file From 12e7257e1ff80562110b906217e94d43d53b337a Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 29 Apr 2016 14:57:33 -0400 Subject: [PATCH 04/37] Let virtual directories be tagged. --- .../autopsy/directorytree/ExplorerNodeActionVisitor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java index d60c9507f3..1b11bb6b8f 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java @@ -18,11 +18,9 @@ */ package org.sleuthkit.autopsy.directorytree; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.actions.AddContentTagAction; -import java.awt.Toolkit; import java.awt.Dimension; import java.awt.Font; +import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -37,6 +35,8 @@ import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Content; @@ -113,6 +113,7 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default visit(final VirtualDirectory d) { List actions = new ArrayList<>(); actions.add(ExtractAction.getInstance()); + actions.add(AddContentTagAction.getInstance()); actions.addAll(ContextMenuExtensionPoint.getActions()); return actions; } From 8ac5c222696f85ac81d885c9514b9ae9e1ed117e Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Fri, 29 Apr 2016 14:59:34 -0400 Subject: [PATCH 05/37] Undid previous commit. --- .../autopsy/directorytree/ExplorerNodeActionVisitor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java index 1b11bb6b8f..3bc2e55e9f 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExplorerNodeActionVisitor.java @@ -113,7 +113,6 @@ public class ExplorerNodeActionVisitor extends ContentVisitor.Default visit(final VirtualDirectory d) { List actions = new ArrayList<>(); actions.add(ExtractAction.getInstance()); - actions.add(AddContentTagAction.getInstance()); actions.addAll(ContextMenuExtensionPoint.getActions()); return actions; } From 5bf62102f2530bdcb125e42fb3eb1d0ae94b28d6 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Mon, 2 May 2016 09:08:23 -0400 Subject: [PATCH 06/37] Improved panel resizing on file ext mismatch panel. --- .../autopsy/casemodule/CaseMetadata.xsd | 19 +++++++++++++++++++ .../FileExtMismatchSettingsPanel.form | 15 +++++++++------ .../FileExtMismatchSettingsPanel.java | 5 +++-- 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd new file mode 100755 index 0000000000..355415c2d2 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form index 53f27fc5d5..4d7beec429 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.form @@ -207,20 +207,20 @@ - + - - + + - + - - + + @@ -254,6 +254,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java index 1acc8d0ace..2f6aee9f2a 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/FileExtMismatchSettingsPanel.java @@ -244,6 +244,7 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel jSplitPane1.setLeftComponent(mimePanel); userExtTextField.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchSettingsPanel.class, "FileExtMismatchSettingsPanel.userExtTextField.text")); // NOI18N + userExtTextField.setMinimumSize(new java.awt.Dimension(20, 20)); userExtTextField.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { userExtTextFieldFocusGained(evt); @@ -285,13 +286,13 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel .addComponent(extHeaderLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 324, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(extensionPanelLayout.createSequentialGroup() - .addComponent(userExtTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(userExtTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(addExtButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(removeExtButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extErrorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(extErrorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)) .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) ); extensionPanelLayout.setVerticalGroup( From dfce250309a71499ff048eb018b5698c83b602b7 Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 3 May 2016 14:21:36 -0400 Subject: [PATCH 07/37] always show tag notification --- .../timeline/events/TagsAddedEvent.java | 19 +- .../timeline/events/TagsUpdatedEvent.java | 1 - .../timeline/ui/VisualizationPanel.java | 219 +++++++++--------- 3 files changed, 128 insertions(+), 111 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/events/TagsAddedEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/events/TagsAddedEvent.java index 2ff4474429..c0384a4f53 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/events/TagsAddedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/events/TagsAddedEvent.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 2014-2016 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.timeline.events; diff --git a/Core/src/org/sleuthkit/autopsy/timeline/events/TagsUpdatedEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/events/TagsUpdatedEvent.java index 7d38458332..694bfe2453 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/events/TagsUpdatedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/events/TagsUpdatedEvent.java @@ -36,6 +36,5 @@ abstract public class TagsUpdatedEvent { public TagsUpdatedEvent(Set updatedEventIDs) { this.updatedEventIDs = updatedEventIDs; - } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java index 1fe72b5aa8..896ae6ee27 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java @@ -31,7 +31,6 @@ import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.geometry.Insets; import javafx.scene.control.Button; @@ -81,8 +80,8 @@ import org.sleuthkit.autopsy.timeline.actions.ZoomIn; import org.sleuthkit.autopsy.timeline.actions.ZoomOut; import org.sleuthkit.autopsy.timeline.actions.ZoomToEvents; import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel; +import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent; import org.sleuthkit.autopsy.timeline.events.TagsUpdatedEvent; -import org.sleuthkit.autopsy.timeline.filters.TagsFilter; import org.sleuthkit.autopsy.timeline.ui.countsview.CountsViewPane; import org.sleuthkit.autopsy.timeline.ui.detailview.DetailViewPane; import org.sleuthkit.autopsy.timeline.ui.detailview.tree.EventsTree; @@ -97,16 +96,16 @@ import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo; * TODO: refactor common code out of histogram and CountsView? -jm */ final public class VisualizationPanel extends BorderPane { - + private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName()); - + private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS private static final Background background = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)); - + @GuardedBy("this") private LoggedTask histogramTask; - + private final EventsTree eventsTree; private AbstractVisualizationPane visualization; //// range slider and histogram componenets @@ -121,13 +120,13 @@ final public class VisualizationPanel extends BorderPane { */ @FXML private StackPane rangeHistogramStack; - + private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75); //// time range selection components @FXML private MenuButton zoomMenuButton; - + @FXML private Button zoomOutButton; @FXML @@ -165,7 +164,7 @@ final public class VisualizationPanel extends BorderPane { * wraps contained visualization so that we can show notifications over it. */ private final NotificationPane notificationPane = new NotificationPane(); - + private final TimeLineController controller; private final FilteredEventsModel filteredEvents; @@ -216,26 +215,26 @@ final public class VisualizationPanel extends BorderPane { } /** - * convert the given epoch millis to a LocalDateTime USING THE CURERNT + * Convert the given epoch millis to a LocalDateTime USING THE CURERNT * TIMEZONE FROM TIMELINECONTROLLER * - * @param millis + * @param millis The milliseconds to convert. * - * @return the given epoch millis as a LocalDateTime + * @return The given epoch millis as a LocalDateTime */ private static LocalDateTime epochMillisToLocalDateTime(long millis) { return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), TimeLineController.getTimeZoneID()); } - + public VisualizationPanel(@Nonnull TimeLineController controller, @Nonnull EventsTree eventsTree) { this.controller = controller; this.filteredEvents = controller.getEventsModel(); this.eventsTree = eventsTree; FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS } - + @FXML // This method is called by the FXMLLoader when initialization is complete - @NbBundle.Messages({"VisualizationPanel.refresh=refresh", + @NbBundle.Messages({ "VisualizationPanel.visualizationModeLabel.text=Visualization Mode:", "VisualizationPanel.startLabel.text=Start:", "VisualizationPanel.endLabel.text=End:", @@ -252,15 +251,6 @@ final public class VisualizationPanel extends BorderPane { //configure notification pane notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK); - notificationPane.getActions().setAll(new Action(Bundle.VisualizationPanel_refresh()) { - { - setGraphic(new ImageView(REFRESH)); - setEventHandler((ActionEvent t) -> { - filteredEvents.refresh(); - notificationPane.hide(); - }); - } - }); setCenter(notificationPane); //configure visualization mode toggle @@ -276,7 +266,7 @@ final public class VisualizationPanel extends BorderPane { controller.setViewMode(VisualizationMode.DETAIL); } }; - + if (countsToggle.getToggleGroup() != null) { countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener); } else { @@ -353,9 +343,9 @@ final public class VisualizationPanel extends BorderPane { } }); refreshHistorgram(); - + } - + private void setViewMode(VisualizationMode visualizationMode) { switch (visualizationMode) { case COUNTS: @@ -368,7 +358,7 @@ final public class VisualizationPanel extends BorderPane { break; } } - + private synchronized void setVisualization(final AbstractVisualizationPane newViz) { Platform.runLater(() -> { synchronized (VisualizationPanel.this) { @@ -376,11 +366,11 @@ final public class VisualizationPanel extends BorderPane { toolBar.getItems().removeAll(visualization.getSettingsNodes()); visualization.dispose(); } - + visualization = newViz; visualization.update(); toolBar.getItems().addAll(newViz.getSettingsNodes()); - + notificationPane.setContent(visualization); if (visualization instanceof DetailViewPane) { Platform.runLater(() -> { @@ -390,7 +380,7 @@ final public class VisualizationPanel extends BorderPane { } visualization.hasEvents.addListener((observable, oldValue, newValue) -> { if (newValue == false) { - + notificationPane.setContent( new StackPane(visualization, new Region() { @@ -407,75 +397,79 @@ final public class VisualizationPanel extends BorderPane { } }); } - + @Subscribe @NbBundle.Messages("VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.") public void handleTimeLineTagEvent(TagsUpdatedEvent event) { - TagsFilter tagsFilter = filteredEvents.getFilter().getTagsFilter(); - if (tagsFilter.isSelected() && tagsFilter.isDisabled() == false) { - Platform.runLater(() -> { - notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); - }); - } + Platform.runLater(() -> { + notificationPane.setCloseButtonVisible(false); + notificationPane.getActions().setAll(new Refresh()); + notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); + }); } - + + @Subscribe + public void handleRefreshRequestedEvent(RefreshRequestedEvent event) { + Platform.runLater(notificationPane::hide); + } + synchronized private void refreshHistorgram() { - + if (histogramTask != null) { histogramTask.cancel(true); } - + histogramTask = new LoggedTask( NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.title"), true) { // NON-NLS - private final Lighting lighting = new Lighting(); - + private final Lighting lighting = new Lighting(); + @Override protected Void call() throws Exception { + + updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS - updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS + long max = 0; + final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval()); + final long lowerBound = rangeInfo.getLowerBound(); + final long upperBound = rangeInfo.getUpperBound(); + Interval timeRange = new Interval(new DateTime(lowerBound, TimeLineController.getJodaTimeZone()), new DateTime(upperBound, TimeLineController.getJodaTimeZone())); - long max = 0; - final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval()); - final long lowerBound = rangeInfo.getLowerBound(); - final long upperBound = rangeInfo.getUpperBound(); - Interval timeRange = new Interval(new DateTime(lowerBound, TimeLineController.getJodaTimeZone()), new DateTime(upperBound, TimeLineController.getJodaTimeZone())); + //extend range to block bounderies (ie day, month, year) + int p = 0; // progress counter - //extend range to block bounderies (ie day, month, year) - int p = 0; // progress counter + //clear old data, and reset ranges and series + Platform.runLater(() -> { + updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS - //clear old data, and reset ranges and series - Platform.runLater(() -> { - updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS + }); + + ArrayList bins = new ArrayList<>(); + + DateTime start = timeRange.getStart(); + while (timeRange.contains(start)) { + if (isCancelled()) { + return null; + } + DateTime end = start.plus(rangeInfo.getPeriodSize().getPeriod()); + final Interval interval = new Interval(start, end); + //increment for next iteration - }); - - ArrayList bins = new ArrayList<>(); - - DateTime start = timeRange.getStart(); - while (timeRange.contains(start)) { - if (isCancelled()) { - return null; - } - DateTime end = start.plus(rangeInfo.getPeriodSize().getPeriod()); - final Interval interval = new Interval(start, end); - //increment for next iteration - - start = end; - - updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS - //query for current range - long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum(); - bins.add(count); - - max = Math.max(count, max); - - final double fMax = Math.log(max); - final ArrayList fbins = new ArrayList<>(bins); - Platform.runLater(() -> { - updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS - - histogramBox.getChildren().clear(); + start = end; + + updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS + //query for current range + long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum(); + bins.add(count); + + max = Math.max(count, max); + + final double fMax = Math.log(max); + final ArrayList fbins = new ArrayList<>(bins); + Platform.runLater(() -> { + updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS + histogramBox.getChildren().clear(); + for (Long bin : fbins) { if (isCancelled()) { break; @@ -498,41 +492,41 @@ final public class VisualizationPanel extends BorderPane { } return null; } - - }; + + }; new Thread(histogramTask).start(); controller.monitorTask(histogramTask); } - + private void refreshTimeUI() { refreshTimeUI(filteredEvents.timeRangeProperty().get()); } - + private void refreshTimeUI(Interval interval) { - + RangeDivisionInfo rangeDivisionInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval()); - + final long minTime = rangeDivisionInfo.getLowerBound(); final long maxTime = rangeDivisionInfo.getUpperBound(); - + long startMillis = interval.getStartMillis(); long endMillis = interval.getEndMillis(); - + if (minTime > 0 && maxTime > minTime) { - + Platform.runLater(() -> { startPicker.localDateTimeProperty().removeListener(startListener); endPicker.localDateTimeProperty().removeListener(endListener); rangeSlider.highValueChangingProperty().removeListener(rangeSliderListener); rangeSlider.lowValueChangingProperty().removeListener(rangeSliderListener); - + rangeSlider.setMax((maxTime - minTime)); - + rangeSlider.setLowValue(startMillis - minTime); rangeSlider.setHighValue(endMillis - minTime); startPicker.setLocalDateTime(epochMillisToLocalDateTime(startMillis)); endPicker.setLocalDateTime(epochMillisToLocalDateTime(endMillis)); - + rangeSlider.highValueChangingProperty().addListener(rangeSliderListener); rangeSlider.lowValueChangingProperty().addListener(rangeSliderListener); startPicker.localDateTimeProperty().addListener(startListener); @@ -540,10 +534,10 @@ final public class VisualizationPanel extends BorderPane { }); } } - + @NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events") private class NoEventsDialog extends StackPane { - + @FXML private TitledPane titledPane; @FXML @@ -556,14 +550,14 @@ final public class VisualizationPanel extends BorderPane { private Button zoomButton; @FXML private Label noEventsDialogLabel; - + private final Runnable closeCallback; - + private NoEventsDialog(Runnable closeCallback) { this.closeCallback = closeCallback; FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS } - + @FXML void initialize() { assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS @@ -574,7 +568,7 @@ final public class VisualizationPanel extends BorderPane { noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS dismissButton.setOnAction(actionEvent -> closeCallback.run()); - + ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton); ActionUtils.configureButton(new Back(controller), backButton); ActionUtils.configureButton(new ResetFilters(controller), resetFiltersButton); @@ -586,15 +580,15 @@ final public class VisualizationPanel extends BorderPane { * the selected LocalDateTime as start/end to the timelinecontroller. */ private class PickerListener implements InvalidationListener { - + private final BiFunction< Interval, Long, Interval> intervalMapper; private final Supplier pickerSupplier; - + PickerListener(Supplier pickerSupplier, BiFunction intervalMapper) { this.pickerSupplier = pickerSupplier; this.intervalMapper = intervalMapper; } - + @Override public void invalidated(Observable observable) { LocalDateTime pickerTime = pickerSupplier.get().getLocalDateTime(); @@ -609,7 +603,7 @@ final public class VisualizationPanel extends BorderPane { * callback that disabled date/times outside the span of the current case. */ private class LocalDateDisabler implements Callback { - + @Override public Void call(LocalDateTimePicker.LocalDateTimeRange viewedRange) { startPicker.disabledLocalDateTimes().clear(); @@ -619,7 +613,7 @@ final public class VisualizationPanel extends BorderPane { Interval spanningInterval = filteredEvents.getSpanningInterval(); long spanStartMillis = spanningInterval.getStartMillis(); long spaneEndMillis = spanningInterval.getEndMillis(); - + LocalDate rangeStartLocalDate = viewedRange.getStartLocalDateTime().toLocalDate(); LocalDate rangeEndLocalDate = viewedRange.getEndLocalDateTime().toLocalDate().plusDays(1); //iterate over days of the displayed range and disable ones not in spanning interval @@ -647,11 +641,11 @@ final public class VisualizationPanel extends BorderPane { * picker to reset if invalid info was entered */ private final LocalDateTimeTextField picker; - + LocalDateTimeValidator(LocalDateTimeTextField picker) { this.picker = picker; } - + @Override public Boolean call(LocalDateTime param) { long epochMilli = localDateTimeToEpochMilli(param); @@ -666,4 +660,15 @@ final public class VisualizationPanel extends BorderPane { } } } + + private class Refresh extends Action { + + @NbBundle.Messages({"VisualizationPanel.refresh=refresh"}) + Refresh() { + super(Bundle.VisualizationPanel_refresh()); + + setGraphic(new ImageView(REFRESH)); + setEventHandler(actionEvent -> filteredEvents.refresh()); + } + } } From 5a05ab2cb3d0354157e79600a67ba8636fe03a24 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 4 May 2016 11:21:52 -0400 Subject: [PATCH 08/37] Fixed finish button enabling problem. --- .../autopsy/report/ReportVisualPanel2.form | 4 ++ .../autopsy/report/ReportVisualPanel2.java | 48 +++++++++++-------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form index 119000eebe..0786a6a0ae 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form @@ -89,6 +89,7 @@ + @@ -100,6 +101,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java index f57da241f9..40b8334ea1 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java @@ -22,7 +22,6 @@ import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; -import java.util.EnumMap; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -41,7 +40,6 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TskCoreException; @@ -164,21 +162,11 @@ final class ReportVisualPanel2 extends JPanel { return result; } - private boolean areArtifactsSelected() { - boolean result = false; - for (Entry entry : artifactStates.entrySet()) { - if (entry.getValue()) { - result = true; - } - } - return result; - } - private void updateFinishButton() { if (taggedResultsRadioButton.isSelected()) { wizPanel.setFinish(areTagsSelected()); } else { - wizPanel.setFinish(areArtifactsSelected()); + wizPanel.setFinish(true); } } @@ -216,9 +204,19 @@ final class ReportVisualPanel2 extends JPanel { taggedResultsRadioButtonStateChanged(evt); } }); + taggedResultsRadioButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseReleased(java.awt.event.MouseEvent evt) { + taggedResultsRadioButtonMouseReleased(evt); + } + }); optionsButtonGroup.add(allResultsRadioButton); org.openide.awt.Mnemonics.setLocalizedText(allResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.allResultsRadioButton.text")); // NOI18N + allResultsRadioButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseReleased(java.awt.event.MouseEvent evt) { + allResultsRadioButtonMouseReleased(evt); + } + }); org.openide.awt.Mnemonics.setLocalizedText(dataLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.dataLabel.text")); // NOI18N @@ -294,11 +292,7 @@ final class ReportVisualPanel2 extends JPanel { }// //GEN-END:initComponents private void taggedResultsRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_taggedResultsRadioButtonStateChanged - tagsList.setEnabled(taggedResultsRadioButton.isSelected()); - selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); - deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); - advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); - updateFinishButton(); + }//GEN-LAST:event_taggedResultsRadioButtonStateChanged private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed @@ -319,8 +313,24 @@ final class ReportVisualPanel2 extends JPanel { private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed artifactStates = dialog.display(); - wizPanel.setFinish(areArtifactsSelected()); }//GEN-LAST:event_advancedButtonActionPerformed + + private void taggedResultsRadioButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_taggedResultsRadioButtonMouseReleased + tagsList.setEnabled(taggedResultsRadioButton.isSelected()); + selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); + updateFinishButton(); + }//GEN-LAST:event_taggedResultsRadioButtonMouseReleased + + private void allResultsRadioButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_allResultsRadioButtonMouseReleased + tagsList.setEnabled(taggedResultsRadioButton.isSelected()); + selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); + updateFinishButton(); + }//GEN-LAST:event_allResultsRadioButtonMouseReleased + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton advancedButton; private javax.swing.JRadioButton allResultsRadioButton; From 2b08257852f76fab27124ae00ac459af2fe6e4b4 Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 4 May 2016 11:50:25 -0400 Subject: [PATCH 09/37] Fixed list selection via keyboard problem with finish button. --- .../autopsy/report/ReportVisualPanel2.form | 7 --- .../autopsy/report/ReportVisualPanel2.java | 57 +++++++------------ 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form index 0786a6a0ae..3df3f78f59 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.form @@ -87,10 +87,6 @@ - - - - @@ -101,9 +97,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java index 40b8334ea1..a140357a50 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportVisualPanel2.java @@ -35,6 +35,8 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import javax.swing.ListModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import javax.swing.event.ListDataListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; @@ -66,6 +68,26 @@ final class ReportVisualPanel2 extends JPanel { deselectAllButton.setEnabled(false); allResultsRadioButton.setSelected(true); this.wizPanel = wizPanel; + this.allResultsRadioButton.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + tagsList.setEnabled(taggedResultsRadioButton.isSelected()); + selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); + updateFinishButton(); + } + }); + this.taggedResultsRadioButton.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + tagsList.setEnabled(taggedResultsRadioButton.isSelected()); + selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); + advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); + updateFinishButton(); + } + }); } // Initialize the list of Tags @@ -199,24 +221,9 @@ final class ReportVisualPanel2 extends JPanel { optionsButtonGroup.add(taggedResultsRadioButton); org.openide.awt.Mnemonics.setLocalizedText(taggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.taggedResultsRadioButton.text")); // NOI18N - taggedResultsRadioButton.addChangeListener(new javax.swing.event.ChangeListener() { - public void stateChanged(javax.swing.event.ChangeEvent evt) { - taggedResultsRadioButtonStateChanged(evt); - } - }); - taggedResultsRadioButton.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseReleased(java.awt.event.MouseEvent evt) { - taggedResultsRadioButtonMouseReleased(evt); - } - }); optionsButtonGroup.add(allResultsRadioButton); org.openide.awt.Mnemonics.setLocalizedText(allResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.allResultsRadioButton.text")); // NOI18N - allResultsRadioButton.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseReleased(java.awt.event.MouseEvent evt) { - allResultsRadioButtonMouseReleased(evt); - } - }); org.openide.awt.Mnemonics.setLocalizedText(dataLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.dataLabel.text")); // NOI18N @@ -291,10 +298,6 @@ final class ReportVisualPanel2 extends JPanel { ); }// //GEN-END:initComponents - private void taggedResultsRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_taggedResultsRadioButtonStateChanged - - }//GEN-LAST:event_taggedResultsRadioButtonStateChanged - private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed for (String tag : tags) { tagStates.put(tag, Boolean.TRUE); @@ -315,22 +318,6 @@ final class ReportVisualPanel2 extends JPanel { artifactStates = dialog.display(); }//GEN-LAST:event_advancedButtonActionPerformed - private void taggedResultsRadioButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_taggedResultsRadioButtonMouseReleased - tagsList.setEnabled(taggedResultsRadioButton.isSelected()); - selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); - deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); - advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); - updateFinishButton(); - }//GEN-LAST:event_taggedResultsRadioButtonMouseReleased - - private void allResultsRadioButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_allResultsRadioButtonMouseReleased - tagsList.setEnabled(taggedResultsRadioButton.isSelected()); - selectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); - deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected()); - advancedButton.setEnabled(!taggedResultsRadioButton.isSelected()); - updateFinishButton(); - }//GEN-LAST:event_allResultsRadioButtonMouseReleased - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton advancedButton; private javax.swing.JRadioButton allResultsRadioButton; From c98658f88ea1c982eec4bab01b7cb99253e1740d Mon Sep 17 00:00:00 2001 From: jmillman Date: Wed, 4 May 2016 12:23:23 -0400 Subject: [PATCH 10/37] add permanent refresh button enabled when tags are updated --- .../timeline/ui/VisualizationPanel.fxml | 163 +++++++++------ .../timeline/ui/VisualizationPanel.java | 197 ++++++++++-------- 2 files changed, 200 insertions(+), 160 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.fxml b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.fxml index ac2748668b..2a39b11e7f 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.fxml +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.fxml @@ -1,79 +1,106 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java index 896ae6ee27..597e3f9b6a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java @@ -29,6 +29,7 @@ import java.util.function.Supplier; import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.Observable; +import javafx.beans.property.ReadOnlyBooleanWrapper; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; @@ -96,16 +97,16 @@ import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo; * TODO: refactor common code out of histogram and CountsView? -jm */ final public class VisualizationPanel extends BorderPane { - + private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName()); - + private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS private static final Background background = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)); - + @GuardedBy("this") private LoggedTask histogramTask; - + private final EventsTree eventsTree; private AbstractVisualizationPane visualization; //// range slider and histogram componenets @@ -120,13 +121,13 @@ final public class VisualizationPanel extends BorderPane { */ @FXML private StackPane rangeHistogramStack; - + private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75); //// time range selection components @FXML private MenuButton zoomMenuButton; - + @FXML private Button zoomOutButton; @FXML @@ -158,13 +159,15 @@ final public class VisualizationPanel extends BorderPane { @FXML private Button snapShotButton; @FXML + private Button refreshButton; + @FXML private Label visualizationModeLabel; /** * wraps contained visualization so that we can show notifications over it. */ private final NotificationPane notificationPane = new NotificationPane(); - + private final ReadOnlyBooleanWrapper needsRefresh = new ReadOnlyBooleanWrapper(false); private final TimeLineController controller; private final FilteredEventsModel filteredEvents; @@ -190,7 +193,7 @@ final public class VisualizationPanel extends BorderPane { /** * hides the notification pane on any event */ - private final InvalidationListener zoomListener = any -> notificationPane.hide(); + private final InvalidationListener zoomListener = any -> setNeedsRefresh(false); /** * listen to change in end time picker and push to controller @@ -225,14 +228,14 @@ final public class VisualizationPanel extends BorderPane { private static LocalDateTime epochMillisToLocalDateTime(long millis) { return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), TimeLineController.getTimeZoneID()); } - + public VisualizationPanel(@Nonnull TimeLineController controller, @Nonnull EventsTree eventsTree) { this.controller = controller; this.filteredEvents = controller.getEventsModel(); this.eventsTree = eventsTree; FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS } - + @FXML // This method is called by the FXMLLoader when initialization is complete @NbBundle.Messages({ "VisualizationPanel.visualizationModeLabel.text=Visualization Mode:", @@ -266,7 +269,7 @@ final public class VisualizationPanel extends BorderPane { controller.setViewMode(VisualizationMode.DETAIL); } }; - + if (countsToggle.getToggleGroup() != null) { countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener); } else { @@ -279,6 +282,7 @@ final public class VisualizationPanel extends BorderPane { //configure snapshor button / action ActionUtils.configureButton(new SaveSnapshotAsReport(controller, VisualizationPanel.this), snapShotButton); + ActionUtils.configureButton(new Refresh(), refreshButton); /////configure start and end pickers startLabel.setText(Bundle.VisualizationPanel_startLabel_text()); @@ -343,9 +347,9 @@ final public class VisualizationPanel extends BorderPane { } }); refreshHistorgram(); - + } - + private void setViewMode(VisualizationMode visualizationMode) { switch (visualizationMode) { case COUNTS: @@ -357,75 +361,83 @@ final public class VisualizationPanel extends BorderPane { detailsToggle.setSelected(true); break; } + } - + private synchronized void setVisualization(final AbstractVisualizationPane newViz) { Platform.runLater(() -> { - synchronized (VisualizationPanel.this) { - if (visualization != null) { - toolBar.getItems().removeAll(visualization.getSettingsNodes()); - visualization.dispose(); - } - - visualization = newViz; - visualization.update(); - toolBar.getItems().addAll(newViz.getSettingsNodes()); - - notificationPane.setContent(visualization); - if (visualization instanceof DetailViewPane) { - Platform.runLater(() -> { - ((DetailViewPane) visualization).setHighLightedEvents(eventsTree.getSelectedEvents()); - eventsTree.setDetailViewPane((DetailViewPane) visualization); - }); - } - visualization.hasEvents.addListener((observable, oldValue, newValue) -> { - if (newValue == false) { - - notificationPane.setContent( - new StackPane(visualization, - new Region() { - { - setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY))); - setOpacity(.3); - } - }, - new NoEventsDialog(() -> notificationPane.setContent(visualization)))); - } else { - notificationPane.setContent(visualization); - } + if (visualization != null) { + toolBar.getItems().removeAll(visualization.getSettingsNodes()); + visualization.dispose(); + } + + visualization = newViz; + visualization.update(); + toolBar.getItems().addAll(newViz.getSettingsNodes()); + + notificationPane.setContent(visualization); + if (visualization instanceof DetailViewPane) { + Platform.runLater(() -> { + ((DetailViewPane) visualization).setHighLightedEvents(eventsTree.getSelectedEvents()); + eventsTree.setDetailViewPane((DetailViewPane) visualization); }); } + visualization.hasEvents.addListener((observable, oldValue, newValue) -> { + if (newValue == false) { + + notificationPane.setContent( + new StackPane(visualization, + new Region() { + { + setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY))); + setOpacity(.3); + } + }, + new NoEventsDialog(() -> notificationPane.setContent(visualization)))); + } else { + notificationPane.setContent(visualization); + } + }); + }); + setNeedsRefresh(false); } - + @Subscribe @NbBundle.Messages("VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.") public void handleTimeLineTagEvent(TagsUpdatedEvent event) { - Platform.runLater(() -> { - notificationPane.setCloseButtonVisible(false); - notificationPane.getActions().setAll(new Refresh()); - notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); - }); + setNeedsRefresh(true); } - + @Subscribe public void handleRefreshRequestedEvent(RefreshRequestedEvent event) { - Platform.runLater(notificationPane::hide); + setNeedsRefresh(false); } - + + private void setNeedsRefresh(Boolean needsRefresh) { + Platform.runLater(() -> { + VisualizationPanel.this.needsRefresh.set(needsRefresh); + if (needsRefresh) { + notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); + } else { + notificationPane.hide(); + } + }); + } + synchronized private void refreshHistorgram() { - + if (histogramTask != null) { histogramTask.cancel(true); } - + histogramTask = new LoggedTask( NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.title"), true) { // NON-NLS private final Lighting lighting = new Lighting(); - + @Override protected Void call() throws Exception { - + updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS long max = 0; @@ -442,9 +454,9 @@ final public class VisualizationPanel extends BorderPane { updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS }); - + ArrayList bins = new ArrayList<>(); - + DateTime start = timeRange.getStart(); while (timeRange.contains(start)) { if (isCancelled()) { @@ -455,21 +467,21 @@ final public class VisualizationPanel extends BorderPane { //increment for next iteration start = end; - + updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS //query for current range long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum(); bins.add(count); - + max = Math.max(count, max); - + final double fMax = Math.log(max); final ArrayList fbins = new ArrayList<>(bins); Platform.runLater(() -> { updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS histogramBox.getChildren().clear(); - + for (Long bin : fbins) { if (isCancelled()) { break; @@ -492,41 +504,41 @@ final public class VisualizationPanel extends BorderPane { } return null; } - + }; new Thread(histogramTask).start(); controller.monitorTask(histogramTask); } - + private void refreshTimeUI() { refreshTimeUI(filteredEvents.timeRangeProperty().get()); } - + private void refreshTimeUI(Interval interval) { - + RangeDivisionInfo rangeDivisionInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval()); - + final long minTime = rangeDivisionInfo.getLowerBound(); final long maxTime = rangeDivisionInfo.getUpperBound(); - + long startMillis = interval.getStartMillis(); long endMillis = interval.getEndMillis(); - + if (minTime > 0 && maxTime > minTime) { - + Platform.runLater(() -> { startPicker.localDateTimeProperty().removeListener(startListener); endPicker.localDateTimeProperty().removeListener(endListener); rangeSlider.highValueChangingProperty().removeListener(rangeSliderListener); rangeSlider.lowValueChangingProperty().removeListener(rangeSliderListener); - + rangeSlider.setMax((maxTime - minTime)); - + rangeSlider.setLowValue(startMillis - minTime); rangeSlider.setHighValue(endMillis - minTime); startPicker.setLocalDateTime(epochMillisToLocalDateTime(startMillis)); endPicker.setLocalDateTime(epochMillisToLocalDateTime(endMillis)); - + rangeSlider.highValueChangingProperty().addListener(rangeSliderListener); rangeSlider.lowValueChangingProperty().addListener(rangeSliderListener); startPicker.localDateTimeProperty().addListener(startListener); @@ -534,10 +546,10 @@ final public class VisualizationPanel extends BorderPane { }); } } - + @NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events") private class NoEventsDialog extends StackPane { - + @FXML private TitledPane titledPane; @FXML @@ -550,14 +562,14 @@ final public class VisualizationPanel extends BorderPane { private Button zoomButton; @FXML private Label noEventsDialogLabel; - + private final Runnable closeCallback; - + private NoEventsDialog(Runnable closeCallback) { this.closeCallback = closeCallback; FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS } - + @FXML void initialize() { assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS @@ -568,7 +580,7 @@ final public class VisualizationPanel extends BorderPane { noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS dismissButton.setOnAction(actionEvent -> closeCallback.run()); - + ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton); ActionUtils.configureButton(new Back(controller), backButton); ActionUtils.configureButton(new ResetFilters(controller), resetFiltersButton); @@ -580,15 +592,15 @@ final public class VisualizationPanel extends BorderPane { * the selected LocalDateTime as start/end to the timelinecontroller. */ private class PickerListener implements InvalidationListener { - + private final BiFunction< Interval, Long, Interval> intervalMapper; private final Supplier pickerSupplier; - + PickerListener(Supplier pickerSupplier, BiFunction intervalMapper) { this.pickerSupplier = pickerSupplier; this.intervalMapper = intervalMapper; } - + @Override public void invalidated(Observable observable) { LocalDateTime pickerTime = pickerSupplier.get().getLocalDateTime(); @@ -603,7 +615,7 @@ final public class VisualizationPanel extends BorderPane { * callback that disabled date/times outside the span of the current case. */ private class LocalDateDisabler implements Callback { - + @Override public Void call(LocalDateTimePicker.LocalDateTimeRange viewedRange) { startPicker.disabledLocalDateTimes().clear(); @@ -613,7 +625,7 @@ final public class VisualizationPanel extends BorderPane { Interval spanningInterval = filteredEvents.getSpanningInterval(); long spanStartMillis = spanningInterval.getStartMillis(); long spaneEndMillis = spanningInterval.getEndMillis(); - + LocalDate rangeStartLocalDate = viewedRange.getStartLocalDateTime().toLocalDate(); LocalDate rangeEndLocalDate = viewedRange.getEndLocalDateTime().toLocalDate().plusDays(1); //iterate over days of the displayed range and disable ones not in spanning interval @@ -641,11 +653,11 @@ final public class VisualizationPanel extends BorderPane { * picker to reset if invalid info was entered */ private final LocalDateTimeTextField picker; - + LocalDateTimeValidator(LocalDateTimeTextField picker) { this.picker = picker; } - + @Override public Boolean call(LocalDateTime param) { long epochMilli = localDateTimeToEpochMilli(param); @@ -660,15 +672,16 @@ final public class VisualizationPanel extends BorderPane { } } } - + private class Refresh extends Action { - + @NbBundle.Messages({"VisualizationPanel.refresh=refresh"}) Refresh() { super(Bundle.VisualizationPanel_refresh()); - + setGraphic(new ImageView(REFRESH)); setEventHandler(actionEvent -> filteredEvents.refresh()); + disabledProperty().bind(needsRefresh.not()); } } } From 0043f4a5fef2a859b68e255c25397884bf18581e Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Wed, 4 May 2016 13:15:48 -0400 Subject: [PATCH 11/37] Made reports delete in ui when action is taken. --- Core/src/org/sleuthkit/autopsy/datamodel/Reports.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java b/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java index e3715787cf..12e41d9e13 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Reports.java @@ -42,7 +42,6 @@ import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Report; import org.sleuthkit.datamodel.TskCoreException; @@ -111,7 +110,7 @@ public final class Reports implements AutopsyVisitableItem { @Override public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); - if (eventType.equals(Case.Events.REPORT_ADDED.toString())) { + if (eventType.equals(Case.Events.REPORT_ADDED.toString()) || eventType.equals(Case.Events.REPORT_DELETED.toString())) { /** * Checking for a current case is a stop gap measure * until a different way of handling the closing of @@ -272,7 +271,6 @@ public final class Reports implements AutopsyVisitableItem { JOptionPane.YES_NO_OPTION) == 0) { try { Case.getCurrentCase().deleteReports(selectedReportsCollection, checkbox.isSelected()); - DataContentTopComponent.findInstance().repaint(); } catch (TskCoreException | IllegalStateException ex) { Logger.getLogger(DeleteReportAction.class.getName()).log(Level.INFO, "Error deleting the reports. ", ex); // NON-NLS - Provide solution to the user? } From 09e6cd963ba7b79671d86dae5f2a106db3fc605c Mon Sep 17 00:00:00 2001 From: Oliver Spohngellert Date: Thu, 5 May 2016 12:05:00 -0400 Subject: [PATCH 12/37] Got rid of xsd. --- .../autopsy/casemodule/CaseMetadata.xsd | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd deleted file mode 100755 index 355415c2d2..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.xsd +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 060c9123360b5c23d4950e34818a73c5322e707b Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 5 May 2016 15:31:21 -0400 Subject: [PATCH 13/37] cleanup around notifications --- .../autopsy/timeline/actions/RebuildDataBase.java | 6 ++++-- .../autopsy/timeline/images/information-frame.png | Bin 0 -> 897 bytes .../autopsy/timeline/images/information-white.png | Bin 0 -> 651 bytes .../sleuthkit/autopsy/timeline/ui/StatusBar.fxml | 6 +++--- .../sleuthkit/autopsy/timeline/ui/StatusBar.java | 2 +- .../autopsy/timeline/ui/VisualizationPanel.java | 12 ++++++++---- 6 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/timeline/images/information-frame.png create mode 100644 Core/src/org/sleuthkit/autopsy/timeline/images/information-white.png diff --git a/Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java b/Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java index 85715b6706..63669522df 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java @@ -32,10 +32,12 @@ public class RebuildDataBase extends Action { private static final Image DB_REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/database_refresh.png"); - @NbBundle.Messages({"RebuildDataBase.text=Update"}) + @NbBundle.Messages({ + "RebuildDataBase.text=Update DB", + "RebuildDataBase.longText=Update the DB to include new events."}) public RebuildDataBase(TimeLineController controller) { super(Bundle.RebuildDataBase_text()); - + setLongText(Bundle.RebuildDataBase_longText()); setGraphic(new ImageView(DB_REFRESH)); setEventHandler(actionEvent -> controller.rebuildRepo()); } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/images/information-frame.png b/Core/src/org/sleuthkit/autopsy/timeline/images/information-frame.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b53a7f6277b8e82fb4612f55c31782033a5295 GIT binary patch literal 897 zcmV-{1AhF8P)VA_VTb`mQIJR^-uCzR_a&3br_}X=r1O~E z+}zBoGQ6d;vvY4a96mn$0p94t46feNaO+79@njx~P4({C*|v#xD#v0mhLfbS90&w> zE9<+uy7q=bp?#+>Phj+0HL7MUKy9rTZnqmnQ^hM{9=%Ls|MtKNS(Xhl`N1Yqxm@=8 z{r(N@?Hj|VE=@qL_QK_IVQlO>&K**5{;-NKQx7oj;*_yRp_VA=ko>o9(;w<=@Bp& z>PKK}lxkB1k-xdr)p;-yFJsNN1wm%nz?IGB@NUe&!bTIiUP5L%hy2exB4_;~wYyGz zfkn0ngIvBub1NtmifrmqC{=t67)BXdj1( zgRD%0i+vQ*Oo@_S4VfmIhAv>I(+SB+CW>7cm@vd#Kw^U|ul_9_|2Vp=$&Rd+fkT}Q z*+!5u1FNbk+T6z~|0*E3$VOTEG|DU+yop32(ao#fnCHmBC{Dv_r^(hT0rN4qEn5lJ zv#56!5Ne%+n>V9TW@V4Zlbf2Fw9=^^#}0;;-hUFqcq&6DnTzWW635A1gPy_%Yuf_TCI86cm}qf{#S=zBFW3rX|-@O-;I5in%4**lS&Y=R(c8TsYm|;ixm0?NTD7*cuFtgDYi(VCp~zRUPOY>_7o6uGf=BYr6giE ziM!kVbmnb$alu<3{NBgR?>Fzw>})QIBDlzqXsSQngJQ7+x_$*X*D8#$RWvUls^`2e zVmA!KrsLR0rg;jZ(GXg%=i>m$K*BPEvqt?+(RgtC5=@TA?&F?cJLvqWwc7Rya@Nqa zoq0hb)?}x-{%A(2Tvs4YEfBsNc;d$J{1!NgMmPD7D14+a8EZ#lcr$X&eG!C zgdik?_8(r&LJ)*-c=#1pU)b|`3GUx4z~);quq+!MKKUX< z?>4HySX?eDO?fOYH0cW@sem4O$r*}=R8YK0j_ty)WWIfbnWsLQIKSNOez$5@3oZ&3 zL`+1xSY?@K0{rO3nzV?THn#hz?NJkfqNpj*F7U5SRXH4VVoe%ARZGoQJJ;`-6hIR< z5;)fdk~87wFBSGXa-TG50L=Hu_4(Syj_;oQRs~U#IJ|#Z7N9-Zj#2#L4Y - + - - - - - - - + + - + @@ -74,10 +74,10 @@ - + - - - - + diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java index 1ed89786db..cc9fb8b2ca 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java @@ -74,6 +74,7 @@ import org.sleuthkit.autopsy.timeline.FXMLConstructor; import org.sleuthkit.autopsy.timeline.TimeLineController; import org.sleuthkit.autopsy.timeline.VisualizationMode; import org.sleuthkit.autopsy.timeline.actions.Back; +import org.sleuthkit.autopsy.timeline.actions.RebuildDataBase; import org.sleuthkit.autopsy.timeline.actions.ResetFilters; import org.sleuthkit.autopsy.timeline.actions.SaveSnapshotAsReport; import org.sleuthkit.autopsy.timeline.actions.ZoomIn; @@ -99,6 +100,7 @@ final public class VisualizationPanel extends BorderPane { private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName()); private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS + private static final Image WARNING = new Image("org/sleuthkit/autopsy/timeline/images/warning_triangle.png", 16, 16, true, true); // NON-NLS private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS private static final Background GRAY_BACKGROUND = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)); @@ -164,6 +166,8 @@ final public class VisualizationPanel extends BorderPane { private Button snapShotButton; @FXML private Button refreshButton; + @FXML + private Button updateDBButton; /* * Wraps contained visualization so that we can show notifications over it. @@ -260,7 +264,8 @@ final public class VisualizationPanel extends BorderPane { "VisualizationPanel.countsToggle.text=Counts", "VisualizationPanel.detailsToggle.text=Details", "VisualizationPanel.zoomMenuButton.text=Zoom in/out to", - "VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date."}) + "VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.", + "StatusBar.refreshLabel.text=The timeline DB may be out of date."}) void initialize() { assert endPicker != null : "fx:id=\"endPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS assert histogramBox != null : "fx:id=\"histogramBox\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS @@ -275,12 +280,32 @@ final public class VisualizationPanel extends BorderPane { setCenter(notificationPane); needsRefresh.addListener(observable -> { if (needsRefresh.get()) { + notificationPane.getActions().setAll(new Refresh()); notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); } else { notificationPane.hide(); } }); + //this should use an event(EventBus) , not this weird observable pattern + controller.eventsDBStaleProperty().addListener(staleProperty -> { + Platform.runLater(() -> { + if (controller.isEventsDBStale()) { + notificationPane.getActions().setAll(new RebuildDataBase(controller)); + notificationPane.show(Bundle.StatusBar_refreshLabel_text(), new ImageView(WARNING)); + } else { + VisualizationPanel.this.refreshHistorgram(); + notificationPane.hide(); + } + }); + }); + + //configure snapshor button / action + ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton); + ActionUtils.configureButton(new Refresh(), refreshButton); + + ActionUtils.configureButton(new RebuildDataBase(controller), updateDBButton); + //configure visualization mode toggle visualizationModeLabel.setText(Bundle.VisualizationPanel_visualizationModeLabel_text()); countsToggle.setText(Bundle.VisualizationPanel_countsToggle_text()); @@ -306,10 +331,6 @@ final public class VisualizationPanel extends BorderPane { controller.visualizationModeProperty().addListener(visualizationMode -> syncVisualizationMode()); syncVisualizationMode(); - //configure snapshor button / action - ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton); - ActionUtils.configureButton(new Refresh(), refreshButton); - /////configure start and end pickers startLabel.setText(Bundle.VisualizationPanel_startLabel_text()); endLabel.setText(Bundle.VisualizationPanel_endLabel_text()); @@ -366,12 +387,6 @@ final public class VisualizationPanel extends BorderPane { filteredEvents.zoomParametersProperty().addListener(zoomListener); refreshTimeUI(); //populate the viz - //this should use an event(EventBus) , not this weird observable pattern - controller.eventsDBStaleProperty().addListener(staleProperty -> { - if (controller.isEventsDBStale()) { - Platform.runLater(VisualizationPanel.this::refreshHistorgram); - } - }); refreshHistorgram(); } From a5aee16b28c58a0729637985b6fdf0cd4f61fe04 Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 10 May 2016 16:27:01 -0400 Subject: [PATCH 33/37] improve Event system remove unused code; use notifications instead of dialogs for data source events --- .../autopsy/timeline/PromptDialogManager.java | 36 +------ .../autopsy/timeline/TimeLineController.java | 58 +++-------- .../datamodel/FilteredEventsModel.java | 10 +- .../timeline/events/DBUpdatedEvent.java | 13 +++ .../autopsy/timeline/ui/StatusBar.fxml | 1 + .../timeline/ui/VisualizationPanel.java | 98 +++++++++++-------- 6 files changed, 97 insertions(+), 119 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java diff --git a/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java b/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java index 45c22ac047..1957724060 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java @@ -157,7 +157,7 @@ class PromptDialogManager { * @return True if they want to continue anyways */ @NbBundle.Messages({ - "PromptDialogManager.confirmDuringIngest.headerText=You are trying to show a timeline before ingest has been completed.\nThe timeline may be incomplete.", + "PromptDialogManager.confirmDuringIngest.headerText=You are trying to update the Timeline DB before ingest has been completed.\nThe Timeline may be incomplete.", "PromptDialogManager.confirmDuringIngest.contentText=Do you want to continue?"}) @ThreadConfined(type = ThreadConfined.ThreadType.JFX) boolean confirmDuringIngest() { @@ -173,38 +173,24 @@ class PromptDialogManager { /** * Prompt the user to confirm rebuilding the database for the given list of - * reasons, adding that "ingest has finished" for the datasource with the - * given name, if not blank, as a reason and as extra header text. + * reasons. * - * @param finishedDataSourceName The name of the datasource that has - * finished be analyzed. Will be ignored if it - * is null or empty. - * @param rebuildReasons A List of reasons why the database is out - * of date. + * @param rebuildReasons A List of reasons why the database is out of date. * * @return True if the user a confirms rebuilding the database. */ @NbBundle.Messages({ "PromptDialogManager.rebuildPrompt.headerText=The Timeline database is incomplete and/or out of date." + " Some events may be missing or inaccurate and some features may be unavailable.", - "# {0} - data source name", - "PromptDialogManager.rebuildPrompt.ingestDone=Ingest has finished for {0}.", "PromptDialogManager.rebuildPrompt.details=Details"}) @ThreadConfined(type = ThreadConfined.ThreadType.JFX) - boolean confirmRebuild(@Nullable String finishedDataSourceName, List rebuildReasons) { + boolean confirmRebuild(List rebuildReasons) { currentDialog = new Alert(Alert.AlertType.CONFIRMATION, Bundle.TimeLinecontroller_updateNowQuestion(), UPDATE, CONTINUE_NO_UPDATE); currentDialog.initModality(Modality.APPLICATION_MODAL); currentDialog.setTitle(Bundle.Timeline_dialogs_title()); setDialogIcons(currentDialog); - //configure header text depending on presence of finishedDataSourceName - String headerText = Bundle.PromptDialogManager_rebuildPrompt_headerText(); - if (StringUtils.isNotBlank(finishedDataSourceName)) { - String datasourceMessage = Bundle.PromptDialogManager_rebuildPrompt_ingestDone(finishedDataSourceName); - rebuildReasons.add(0, datasourceMessage); - headerText = datasourceMessage + "\n\n" + headerText; - } - currentDialog.setHeaderText(headerText); + currentDialog.setHeaderText(Bundle.PromptDialogManager_rebuildPrompt_headerText()); //set up listview of reasons to rebuild ListView listView = new ListView<>(FXCollections.observableArrayList(rebuildReasons)); @@ -225,16 +211,4 @@ class PromptDialogManager { return currentDialog.showAndWait().map(UPDATE::equals).orElse(false); } - /** - * Prompt the user to confirm rebuilding the database for the given list of - * reasons. - * - * @param rebuildReasons S List of reasons why the database is out of date. - * - * @return True if the user a confirms rebuilding the database. - */ - @ThreadConfined(type = ThreadConfined.ThreadType.JFX) - boolean confirmRebuild(ArrayList rebuildReasons) { - return confirmRebuild(null, rebuildReasons); - } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index 369bd11910..91e8b7ff23 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -51,7 +51,6 @@ import javafx.concurrent.Task; import javafx.concurrent.Worker; import static javafx.concurrent.Worker.State.FAILED; import static javafx.concurrent.Worker.State.SUCCEEDED; -import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.Immutable; import javax.swing.SwingUtilities; @@ -74,10 +73,9 @@ import org.sleuthkit.autopsy.coreutils.LoggedTask; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ThreadConfined; +import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.ingest.IngestManager; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent.CANCELLED; -import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisEvent; -import static org.sleuthkit.autopsy.timeline.Bundle.*; import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel; import org.sleuthkit.autopsy.timeline.datamodel.TimeLineEvent; import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType; @@ -90,7 +88,6 @@ import org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD; import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel; import org.sleuthkit.autopsy.timeline.zooming.TimeUnits; import org.sleuthkit.autopsy.timeline.zooming.ZoomParams; -import org.sleuthkit.datamodel.Content; /** * Controller in the MVC design along with FilteredEventsModel TimeLineView. @@ -264,6 +261,7 @@ public class TimeLineController { @NbBundle.Messages({ "TimeLineController.setEventsDBStale.errMsgStale=Failed to mark the timeline db as stale. Some results may be out of date or missing.", "TimeLineController.setEventsDBStale.errMsgNotStale=Failed to mark the timeline db as not stale. Some results may be out of date or missing."}) + @ThreadConfined(type = ThreadConfined.ThreadType.JFX) private void setEventsDBStale(final Boolean stale) { eventsDBStale.set(stale); try { @@ -389,12 +387,13 @@ public class TimeLineController { perCaseTimelineProperties.setIngestRunning(ingestRunning); } catch (IOException ex) { MessageNotifyUtil.Notify.error(Bundle.Timeline_dialogs_title(), - ingestRunning ? TimeLineController_setIngestRunning_errMsgRunning() - : TimeLinecontroller_setIngestRunning_errMsgNotRunning()); + ingestRunning ? Bundle.TimeLineController_setIngestRunning_errMsgRunning() + : Bundle.TimeLinecontroller_setIngestRunning_errMsgNotRunning()); LOGGER.log(Level.SEVERE, "Error marking the ingest state while the timeline db was populated.", ex); //NON-NLS } if (markDBNotStale) { setEventsDBStale(false); + filteredEvents.fireDBUpdated(); } SwingUtilities.invokeLater(this::showWindow); break; @@ -470,7 +469,7 @@ public class TimeLineController { listeningToAutopsy = true; } - Platform.runLater(() -> promptForRebuild(null)); + Platform.runLater(() -> promptForRebuild()); } /** @@ -484,7 +483,7 @@ public class TimeLineController { * processing. Will be ignored if it is null or empty. */ @ThreadConfined(type = ThreadConfined.ThreadType.JFX) - private void promptForRebuild(@Nullable String dataSourceName) { + private void promptForRebuild() { //if there is an existing prompt or progressdialog, just show that if (promptDialogManager.bringCurrentDialogToFront()) { @@ -500,7 +499,7 @@ public class TimeLineController { //if necessary prompt user with reasons to rebuild List rebuildReasons = getRebuildReasons(); if (false == rebuildReasons.isEmpty()) { - if (promptDialogManager.confirmRebuild(dataSourceName, rebuildReasons)) { + if (promptDialogManager.confirmRebuild(rebuildReasons)) { rebuildRepo(); return; } @@ -817,42 +816,6 @@ public class TimeLineController { } - /** - * Is the timeline window open? - * - * @return True if the timeline is open. - */ - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private boolean isWindowOpen() { - return mainFrame != null && mainFrame.isOpened() && mainFrame.isVisible(); - } - - /** - * Rebuild the db ONLY IF THE TIMELINE WINDOW IS OPEN. The user will be - * prompted with reasons why the database needs to be rebuilt and can still - * cancel the rebuild. The prompt will include that ingest has finished for - * the given datasource name, if not blank. - * - * @param dataSourceName The name of the datasource that has finished - * ingest. Will be ignored if it is null or empty. - */ - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private void rebuildIfWindowOpen(@Nullable String dataSourceName) { - if (isWindowOpen()) { - Platform.runLater(() -> this.promptForRebuild(dataSourceName)); - } - } - - /** - * Rebuild the db ONLY IF THE TIMELINE WINDOW IS OPEN. The user will be - * prompted with reasons why the database needs to be rebuilt and can still - * cancel the rebuild. - */ - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - public void rebuildIfWindowOpen() { - rebuildIfWindowOpen(null); - } - /** * Listener for IngestManager.IngestModuleEvents. */ @@ -903,8 +866,8 @@ public class TimeLineController { switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) { case DATA_SOURCE_ANALYSIS_COMPLETED: // include data source name in rebuild prompt on ingest completed - final Content dataSource = ((DataSourceAnalysisEvent) evt).getDataSource(); - SwingUtilities.invokeLater(() -> rebuildIfWindowOpen(dataSource.getName())); + Platform.runLater(() -> setEventsDBStale(true)); + filteredEvents.reFireAutopsyEvent((AutopsyEvent) evt); break; case DATA_SOURCE_ANALYSIS_STARTED: case CANCELLED: @@ -939,6 +902,7 @@ public class TimeLineController { case DATA_SOURCE_ADDED: //mark db stale, and prompt to rebuild Platform.runLater(() -> setEventsDBStale(true)); + filteredEvents.reFireAutopsyEvent((AutopsyEvent) evt); break; case CURRENT_CASE: //close timeline on case changes. diff --git a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java index ad5bc8786e..95e56b3355 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java @@ -40,9 +40,11 @@ import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent.DeletedContentTagInfo; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType; import org.sleuthkit.autopsy.timeline.datamodel.eventtype.RootEventType; import org.sleuthkit.autopsy.timeline.db.EventsRepository; +import org.sleuthkit.autopsy.timeline.events.DBUpdatedEvent; import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent; import org.sleuthkit.autopsy.timeline.events.TagsAddedEvent; import org.sleuthkit.autopsy.timeline.events.TagsDeletedEvent; @@ -436,8 +438,14 @@ public final class FilteredEventsModel { eventbus.unregister(0); } - public void refresh() { + public void fireDBUpdated() { + eventbus.post(new DBUpdatedEvent()); + } + public void fireRefreshRequest() { eventbus.post(new RefreshRequestedEvent()); } + public void reFireAutopsyEvent(AutopsyEvent event) { + eventbus.post(event); + } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java new file mode 100644 index 0000000000..e92dbe3f7d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java @@ -0,0 +1,13 @@ +/* + * 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.timeline.events; + +/** + * + */ +public class DBUpdatedEvent { + +} diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/StatusBar.fxml b/Core/src/org/sleuthkit/autopsy/timeline/ui/StatusBar.fxml index bdb713b123..8f410511a1 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/StatusBar.fxml +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/StatusBar.fxml @@ -7,6 +7,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java index cc9fb8b2ca..9e7ca22940 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java @@ -68,8 +68,10 @@ import org.controlsfx.control.action.ActionUtils; import org.joda.time.DateTime; import org.joda.time.Interval; import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent; import org.sleuthkit.autopsy.coreutils.LoggedTask; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent; import org.sleuthkit.autopsy.timeline.FXMLConstructor; import org.sleuthkit.autopsy.timeline.TimeLineController; import org.sleuthkit.autopsy.timeline.VisualizationMode; @@ -81,6 +83,7 @@ import org.sleuthkit.autopsy.timeline.actions.ZoomIn; import org.sleuthkit.autopsy.timeline.actions.ZoomOut; import org.sleuthkit.autopsy.timeline.actions.ZoomToEvents; import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel; +import org.sleuthkit.autopsy.timeline.events.DBUpdatedEvent; import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent; import org.sleuthkit.autopsy.timeline.events.TagsUpdatedEvent; import org.sleuthkit.autopsy.timeline.ui.countsview.CountsViewPane; @@ -206,7 +209,7 @@ final public class VisualizationPanel extends BorderPane { /** * hides the notification pane on any event */ - private final InvalidationListener zoomListener = any -> setNeedsRefresh(false); + private final InvalidationListener zoomListener = any -> handleRefreshRequested(null); /** * listen to change in end time picker and push to controller @@ -264,8 +267,8 @@ final public class VisualizationPanel extends BorderPane { "VisualizationPanel.countsToggle.text=Counts", "VisualizationPanel.detailsToggle.text=Details", "VisualizationPanel.zoomMenuButton.text=Zoom in/out to", - "VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.", - "StatusBar.refreshLabel.text=The timeline DB may be out of date."}) + "VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date." + }) void initialize() { assert endPicker != null : "fx:id=\"endPicker\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS assert histogramBox != null : "fx:id=\"histogramBox\" was not injected: check your FXML file 'ViewWrapper.fxml'."; // NON-NLS @@ -276,29 +279,7 @@ final public class VisualizationPanel extends BorderPane { //configure notification pane notificationPane.getStyleClass().add(NotificationPane.STYLE_CLASS_DARK); - notificationPane.getActions().setAll(new Refresh()); setCenter(notificationPane); - needsRefresh.addListener(observable -> { - if (needsRefresh.get()) { - notificationPane.getActions().setAll(new Refresh()); - notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); - } else { - notificationPane.hide(); - } - }); - - //this should use an event(EventBus) , not this weird observable pattern - controller.eventsDBStaleProperty().addListener(staleProperty -> { - Platform.runLater(() -> { - if (controller.isEventsDBStale()) { - notificationPane.getActions().setAll(new RebuildDataBase(controller)); - notificationPane.show(Bundle.StatusBar_refreshLabel_text(), new ImageView(WARNING)); - } else { - VisualizationPanel.this.refreshHistorgram(); - notificationPane.hide(); - } - }); - }); //configure snapshor button / action ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton); @@ -391,6 +372,13 @@ final public class VisualizationPanel extends BorderPane { } + /** + * Set whether the visualziation may not represent the current state of the + * DB, because, for example, tags have been updated. + * + * @param needsRefresh True if the visualization may not represent the + * current state of the DB. + */ /** * Handle TagsUpdatedEvents. * @@ -402,8 +390,14 @@ final public class VisualizationPanel extends BorderPane { * @param event The TagsUpdatedEvent to handle. */ @Subscribe - public void handleTimeLineTagEvent(TagsUpdatedEvent event) { - setNeedsRefresh(true); + public void handleTimeLineTagUpdate(TagsUpdatedEvent event) { + Platform.runLater(() -> { + VisualizationPanel.this.needsRefresh.set(true); + if (notificationPane.isShowing() == false) { + notificationPane.getActions().setAll(new Refresh()); + notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); + } + }); } /** @@ -417,19 +411,39 @@ final public class VisualizationPanel extends BorderPane { * @param event The RefreshRequestedEvent to handle. */ @Subscribe - public void handleRefreshRequestedEvent(RefreshRequestedEvent event) { - setNeedsRefresh(false); + public void handleRefreshRequested(RefreshRequestedEvent event) { + Platform.runLater(() -> { + VisualizationPanel.this.needsRefresh.set(false); + if (notificationPane.getText().equals(Bundle.VisualizationPanel_tagsAddedOrDeleted())) { + notificationPane.hide(); + } + }); } - /** - * Set whether the visualziation may not represent the current state of the - * DB, because, for example, tags have been updated. - * - * @param needsRefresh True if the visualization may not represent the - * current state of the DB. - */ - private void setNeedsRefresh(Boolean needsRefresh) { - Platform.runLater(() -> VisualizationPanel.this.needsRefresh.set(needsRefresh)); + + + @Subscribe + public void handleFresh(DBUpdatedEvent event) { + Platform.runLater(() -> { + VisualizationPanel.this.refreshHistorgram(); + notificationPane.hide(); + }); + } + + @Subscribe + public void handlDataSourceAdded(DataSourceAddedEvent event) { + Platform.runLater(() -> { + notificationPane.getActions().setAll(new RebuildDataBase(controller)); + notificationPane.show("A new datasource, " + event.getDataSource().getName() + ", has been added. The Timeline DB may be out of date.", new ImageView(WARNING)); + }); + } + + @Subscribe + public void handleAnalysisCompleted(DataSourceAnalysisCompletedEvent event) { + Platform.runLater(() -> { + notificationPane.getActions().setAll(new RebuildDataBase(controller)); + notificationPane.show("Analysis has finished for " + event.getDataSource().getName() + ". The Timeline DB may be out of date.", new ImageView(WARNING)); + }); } /** @@ -607,7 +621,11 @@ final public class VisualizationPanel extends BorderPane { ); }); }); - setNeedsRefresh(false); + + Platform.runLater(() -> { + VisualizationPanel.this.needsRefresh.set(false); + notificationPane.hide(); + }); } @NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events") @@ -748,7 +766,7 @@ final public class VisualizationPanel extends BorderPane { super(Bundle.VisualizationPanel_refresh_text()); setLongText(Bundle.VisualizationPanel_refresh_longText()); setGraphic(new ImageView(REFRESH)); - setEventHandler(actionEvent -> filteredEvents.refresh()); + setEventHandler(actionEvent -> filteredEvents.fireRefreshRequest()); disabledProperty().bind(needsRefresh.not()); } } From 2ff31cc7a5014075bbd3ef57c62afc193df4901b Mon Sep 17 00:00:00 2001 From: jmillman Date: Wed, 11 May 2016 10:16:24 -0400 Subject: [PATCH 34/37] move refresh state into AbstractVisualizationPane; cleanup VisualizationPanel.java and VisualizationPanel.fxml --- .../ui/AbstractVisualizationPane.java | 33 ++-- .../timeline/ui/VisualizationPanel.fxml | 168 +++++++++--------- .../timeline/ui/VisualizationPanel.java | 42 ++--- 3 files changed, 113 insertions(+), 130 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java index 2c0d8bd12e..d418fba23b 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.timeline.ui; -import com.google.common.eventbus.Subscribe; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -72,7 +71,6 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.timeline.TimeLineController; import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel; import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType; -import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent; /** * Abstract base class for TimeLineChart based visualizations. @@ -106,6 +104,13 @@ public abstract class AbstractVisualizationPane update(); + public boolean needsRefresh() { + return needsRefresh.get(); + } + + public ReadOnlyBooleanProperty needsRefreshProperty() { + return needsRefresh.getReadOnlyProperty(); + } + /** * The visualization nodes that are selected. * @@ -438,17 +451,6 @@ public abstract class AbstractVisualizationPane - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java index 9e7ca22940..9b2ae5283a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/VisualizationPanel.java @@ -29,7 +29,6 @@ import java.util.function.Supplier; import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.Observable; -import javafx.beans.property.ReadOnlyBooleanWrapper; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; @@ -177,13 +176,6 @@ final public class VisualizationPanel extends BorderPane { */ private final NotificationPane notificationPane = new NotificationPane(); - /* - * Boolean property that holds true if the visualziation may not represent - * the current state of the DB, because, for example, tags have been updated - * but the vis. was not refreshed. - */ - private final ReadOnlyBooleanWrapper needsRefresh = new ReadOnlyBooleanWrapper(false); - private final TimeLineController controller; private final FilteredEventsModel filteredEvents; @@ -283,7 +275,6 @@ final public class VisualizationPanel extends BorderPane { //configure snapshor button / action ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton); - ActionUtils.configureButton(new Refresh(), refreshButton); ActionUtils.configureButton(new RebuildDataBase(controller), updateDBButton); @@ -391,8 +382,8 @@ final public class VisualizationPanel extends BorderPane { */ @Subscribe public void handleTimeLineTagUpdate(TagsUpdatedEvent event) { + visualization.setNeedsRefresh(); Platform.runLater(() -> { - VisualizationPanel.this.needsRefresh.set(true); if (notificationPane.isShowing() == false) { notificationPane.getActions().setAll(new Refresh()); notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION)); @@ -401,9 +392,8 @@ final public class VisualizationPanel extends BorderPane { } /** - * Handle RefreshRequestedEvent. - * - * Mark that the visualization has been refreshed. + * Handle a RefreshRequestedEvent from the events model by updating the + * visualization. * * NOTE: This VisualizationPanel must be registered with the * filteredEventsModel's EventBus in order for this handler to be invoked. @@ -412,22 +402,18 @@ final public class VisualizationPanel extends BorderPane { */ @Subscribe public void handleRefreshRequested(RefreshRequestedEvent event) { + visualization.update(); Platform.runLater(() -> { - VisualizationPanel.this.needsRefresh.set(false); - if (notificationPane.getText().equals(Bundle.VisualizationPanel_tagsAddedOrDeleted())) { + if (Bundle.VisualizationPanel_tagsAddedOrDeleted().equals(notificationPane.getText())) { notificationPane.hide(); } }); } - - @Subscribe - public void handleFresh(DBUpdatedEvent event) { - Platform.runLater(() -> { - VisualizationPanel.this.refreshHistorgram(); - notificationPane.hide(); - }); + public void handleDBUpdated(DBUpdatedEvent event) { + refreshHistorgram(); + Platform.runLater(notificationPane::hide); } @Subscribe @@ -606,8 +592,9 @@ final public class VisualizationPanel extends BorderPane { } //setup new vis. visualization = vizPane; + ActionUtils.configureButton(new Refresh(), refreshButton); visualization.update(); - toolBar.getItems().addAll(vizPane.getSettingsNodes()); + toolBar.getItems().addAll(2, vizPane.getSettingsNodes()); notificationPane.setContent(visualization); //listen to has event sproperty and show "dialog" if it is false. @@ -622,10 +609,7 @@ final public class VisualizationPanel extends BorderPane { }); }); - Platform.runLater(() -> { - VisualizationPanel.this.needsRefresh.set(false); - notificationPane.hide(); - }); + Platform.runLater(notificationPane::hide); } @NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events") @@ -760,14 +744,14 @@ final public class VisualizationPanel extends BorderPane { private class Refresh extends Action { @NbBundle.Messages({ - "VisualizationPanel.refresh.text=Refresh", + "VisualizationPanel.refresh.text=Refresh Vis.", "VisualizationPanel.refresh.longText=Refresh the visualization to include information that is in the database but not visualized, such as newly updated tags."}) Refresh() { super(Bundle.VisualizationPanel_refresh_text()); setLongText(Bundle.VisualizationPanel_refresh_longText()); setGraphic(new ImageView(REFRESH)); setEventHandler(actionEvent -> filteredEvents.fireRefreshRequest()); - disabledProperty().bind(needsRefresh.not()); + disabledProperty().bind(visualization.needsRefreshProperty().not()); } } } From b1417748bd4951b678c174a08b5ebc39d6ef9d01 Mon Sep 17 00:00:00 2001 From: jmillman Date: Wed, 11 May 2016 11:16:22 -0400 Subject: [PATCH 35/37] cleanup PromptDialogManager, UpdateDB, FilteredEventsModel, TimeLineController, DBUpdatedEvent, RefreshRequestedEvent, AbstractVisualizationPane,and VisualizationPanel --- .../autopsy/timeline/PromptDialogManager.java | 27 +++--- .../autopsy/timeline/TimeLineController.java | 62 ++++++------- .../{RebuildDataBase.java => UpdateDB.java} | 15 ++- .../datamodel/FilteredEventsModel.java | 47 +++++++++- .../timeline/events/DBUpdatedEvent.java | 22 ++++- .../events/RefreshRequestedEvent.java | 4 +- .../ui/AbstractVisualizationPane.java | 74 ++++++++++----- .../autopsy/timeline/ui/StatusBar.java | 4 +- .../timeline/ui/VisualizationPanel.java | 93 ++++++++++++------- .../ui/countsview/CountsViewPane.java | 4 +- .../ui/countsview/EventCountsChart.java | 2 +- .../ui/detailview/DetailViewPane.java | 2 +- 12 files changed, 228 insertions(+), 128 deletions(-) rename Core/src/org/sleuthkit/autopsy/timeline/actions/{RebuildDataBase.java => UpdateDB.java} (84%) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java b/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java index 1957724060..0e1996456e 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/PromptDialogManager.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.timeline; import java.io.IOException; import java.net.URL; -import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import javafx.collections.FXCollections; @@ -34,8 +33,6 @@ import javafx.scene.control.ListView; import javafx.scene.image.Image; import javafx.stage.Modality; import javafx.stage.Stage; -import javax.annotation.Nullable; -import org.apache.commons.lang3.StringUtils; import org.controlsfx.dialog.ProgressDialog; import org.controlsfx.tools.Borders; import org.openide.util.NbBundle; @@ -50,13 +47,13 @@ class PromptDialogManager { private static final Logger LOGGER = Logger.getLogger(PromptDialogManager.class.getName()); - @NbBundle.Messages("PrompDialogManager.buttonType.showTimeline=Show Timeline") - private static final ButtonType SHOW_TIMELINE = new ButtonType(Bundle.PrompDialogManager_buttonType_showTimeline(), ButtonBar.ButtonData.OK_DONE); + @NbBundle.Messages("PrompDialogManager.buttonType.showTimeline=Continue") + private static final ButtonType CONTINUE = new ButtonType(Bundle.PrompDialogManager_buttonType_showTimeline(), ButtonBar.ButtonData.OK_DONE); @NbBundle.Messages("PrompDialogManager.buttonType.continueNoUpdate=Continue Without Updating") private static final ButtonType CONTINUE_NO_UPDATE = new ButtonType(Bundle.PrompDialogManager_buttonType_continueNoUpdate(), ButtonBar.ButtonData.CANCEL_CLOSE); - @NbBundle.Messages("PrompDialogManager.buttonType.update=Update") + @NbBundle.Messages("PrompDialogManager.buttonType.update=Update DB") private static final ButtonType UPDATE = new ButtonType(Bundle.PrompDialogManager_buttonType_update(), ButtonBar.ButtonData.OK_DONE); /** @@ -89,7 +86,7 @@ class PromptDialogManager { } /** - * Bring the currently managed dialog (if there is one) to the front + * Bring the currently managed dialog (if there is one) to the front. * * @return True if a dialog was brought to the front, or false of there is * no currently managed open dialog @@ -151,24 +148,24 @@ class PromptDialogManager { } /** - * Prompt the user that ingest is running and the db may not end up + * Prompt the user that ingest is running and the DB may not end up * complete. * - * @return True if they want to continue anyways + * @return True if they want to continue anyways. */ @NbBundle.Messages({ - "PromptDialogManager.confirmDuringIngest.headerText=You are trying to update the Timeline DB before ingest has been completed.\nThe Timeline may be incomplete.", + "PromptDialogManager.confirmDuringIngest.headerText=You are trying to update the Timeline DB before ingest has been completed. The Timeline DB may be incomplete.", "PromptDialogManager.confirmDuringIngest.contentText=Do you want to continue?"}) @ThreadConfined(type = ThreadConfined.ThreadType.JFX) boolean confirmDuringIngest() { - currentDialog = new Alert(Alert.AlertType.CONFIRMATION, Bundle.PromptDialogManager_confirmDuringIngest_contentText(), SHOW_TIMELINE, ButtonType.CANCEL); + currentDialog = new Alert(Alert.AlertType.CONFIRMATION, Bundle.PromptDialogManager_confirmDuringIngest_contentText(), CONTINUE, ButtonType.CANCEL); currentDialog.initModality(Modality.APPLICATION_MODAL); currentDialog.setTitle(Bundle.Timeline_dialogs_title()); setDialogIcons(currentDialog); currentDialog.setHeaderText(Bundle.PromptDialogManager_confirmDuringIngest_headerText()); - //show dialog and map all results except "show timeline" to false. - return currentDialog.showAndWait().map(SHOW_TIMELINE::equals).orElse(false); + //show dialog and map all results except "continue" to false. + return currentDialog.showAndWait().map(CONTINUE::equals).orElse(false); } /** @@ -180,8 +177,7 @@ class PromptDialogManager { * @return True if the user a confirms rebuilding the database. */ @NbBundle.Messages({ - "PromptDialogManager.rebuildPrompt.headerText=The Timeline database is incomplete and/or out of date." - + " Some events may be missing or inaccurate and some features may be unavailable.", + "PromptDialogManager.rebuildPrompt.headerText=The Timeline DB is incomplete and/or out of date. Some events may be missing or inaccurate and some features may be unavailable.", "PromptDialogManager.rebuildPrompt.details=Details"}) @ThreadConfined(type = ThreadConfined.ThreadType.JFX) boolean confirmRebuild(List rebuildReasons) { @@ -210,5 +206,4 @@ class PromptDialogManager { //show dialog and map all results except "update" to false. return currentDialog.showAndWait().map(UPDATE::equals).orElse(false); } - } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java index 91e8b7ff23..a02917d75f 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/TimeLineController.java @@ -139,7 +139,7 @@ public class TimeLineController { private final ReadOnlyStringWrapper taskTitle = new ReadOnlyStringWrapper(); - private final ReadOnlyStringWrapper status = new ReadOnlyStringWrapper(); + private final ReadOnlyStringWrapper statusMessage = new ReadOnlyStringWrapper(); /** * Status is a string that will be displayed in the status bar as a kind of @@ -147,12 +147,12 @@ public class TimeLineController { * * @return The status property */ - public ReadOnlyStringProperty getStatusProperty() { - return status.getReadOnlyProperty(); + public ReadOnlyStringProperty statusMessageProperty() { + return statusMessage.getReadOnlyProperty(); } - public void setStatus(String string) { - status.set(string); + public void setStatusMessage(String string) { + statusMessage.set(string); } private final Case autoCase; private final PerCaseTimelineProperties perCaseTimelineProperties; @@ -199,10 +199,10 @@ public class TimeLineController { private final PropertyChangeListener ingestModuleListener = new AutopsyIngestModuleListener(); @GuardedBy("this") - private final ReadOnlyObjectWrapper viewMode = new ReadOnlyObjectWrapper<>(VisualizationMode.COUNTS); + private final ReadOnlyObjectWrapper visualizationMode = new ReadOnlyObjectWrapper<>(VisualizationMode.COUNTS); synchronized public ReadOnlyObjectProperty visualizationModeProperty() { - return viewMode.getReadOnlyProperty(); + return visualizationMode.getReadOnlyProperty(); } @GuardedBy("filteredEvents") @@ -393,7 +393,7 @@ public class TimeLineController { } if (markDBNotStale) { setEventsDBStale(false); - filteredEvents.fireDBUpdated(); + filteredEvents.postDBUpdated(); } SwingUtilities.invokeLater(this::showWindow); break; @@ -453,6 +453,7 @@ public class TimeLineController { mainFrame.close(); mainFrame = null; } + OpenTimelineAction.invalidateController(); } /** @@ -469,18 +470,14 @@ public class TimeLineController { listeningToAutopsy = true; } - Platform.runLater(() -> promptForRebuild()); + Platform.runLater(this::promptForRebuild); } /** - * Prompt the user to confirm rebuilding the db because ingest has finished - * on the datasource with the given name. Checks if a database rebuild is - * necessary for any other reasons and includes those in the prompt. If the - * user confirms, rebuilds the database. Shows the timeline window when the - * rebuild is done, or immediately if the rebuild is not confirmed. - * - * @param dataSourceName The name of the datasource that ingest has finished - * processing. Will be ignored if it is null or empty. + * Prompt the user to confirm rebuilding the db. Checks if a database + * rebuild is necessary and includes the reasons in the prompt. If the user + * confirms, rebuilds the database. Shows the timeline window when the + * rebuild is done, or immediately if the rebuild is not confirmed. F */ @ThreadConfined(type = ThreadConfined.ThreadType.JFX) private void promptForRebuild() { @@ -559,7 +556,7 @@ public class TimeLineController { * Request a time range the same length as the given period and centered * around the middle of the currently viewed time range. * - * @param period The period of time to shw around the current center of the + * @param period The period of time to show around the current center of the * view. */ synchronized public void pushPeriod(ReadablePeriod period) { @@ -585,9 +582,14 @@ public class TimeLineController { pushTimeRange(new Interval(start, end)); } - synchronized public void setViewMode(VisualizationMode visualizationMode) { - if (viewMode.get() != visualizationMode) { - viewMode.set(visualizationMode); + /** + * Set a new Visualization mode as the active one. + * + * @param visualizationMode The new VisaualizationMode to set. + */ + synchronized public void setVisualizationMode(VisualizationMode visualizationMode) { + if (this.visualizationMode.get() != visualizationMode) { + this.visualizationMode.set(visualizationMode); } } @@ -811,11 +813,6 @@ public class TimeLineController { TimeLineController.timeZone.set(timeZone); } - Interval getSpanningInterval(Collection eventIDs) { - return filteredEvents.getSpanningInterval(eventIDs); - - } - /** * Listener for IngestManager.IngestModuleEvents. */ @@ -833,16 +830,14 @@ public class TimeLineController { try { Case.getCurrentCase(); } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ + // Case is closed, do nothing. return; } switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) { case CONTENT_CHANGED: case DATA_ADDED: - //since black board artifacts or new derived content have been added, the db is stale. + //since black board artifacts or new derived content have been added, the DB is stale. Platform.runLater(() -> setEventsDBStale(true)); break; case FILE_DONE: @@ -865,9 +860,9 @@ public class TimeLineController { public void propertyChange(PropertyChangeEvent evt) { switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) { case DATA_SOURCE_ANALYSIS_COMPLETED: - // include data source name in rebuild prompt on ingest completed + //mark db stale, and prompt to rebuild Platform.runLater(() -> setEventsDBStale(true)); - filteredEvents.reFireAutopsyEvent((AutopsyEvent) evt); + filteredEvents.postAutopsyEventLocally((AutopsyEvent) evt); break; case DATA_SOURCE_ANALYSIS_STARTED: case CANCELLED: @@ -902,11 +897,10 @@ public class TimeLineController { case DATA_SOURCE_ADDED: //mark db stale, and prompt to rebuild Platform.runLater(() -> setEventsDBStale(true)); - filteredEvents.reFireAutopsyEvent((AutopsyEvent) evt); + filteredEvents.postAutopsyEventLocally((AutopsyEvent) evt); break; case CURRENT_CASE: //close timeline on case changes. - OpenTimelineAction.invalidateController(); SwingUtilities.invokeLater(TimeLineController.this::shutDownTimeLine); break; } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java b/Core/src/org/sleuthkit/autopsy/timeline/actions/UpdateDB.java similarity index 84% rename from Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java rename to Core/src/org/sleuthkit/autopsy/timeline/actions/UpdateDB.java index b632ebadbb..599f029844 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/actions/RebuildDataBase.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/actions/UpdateDB.java @@ -25,17 +25,22 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.timeline.TimeLineController; /** - * An action that rebuilds the events database to include any new results from + * An action that rebuilds the timeline database to include any new results from * ingest. */ -public class RebuildDataBase extends Action { - +public class UpdateDB extends Action { + private static final Image DB_REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/database_refresh.png"); - + + /** + * Constructor + * + * @param controller The TimeLineController for this action. + */ @NbBundle.Messages({ "RebuildDataBase.text=Update DB", "RebuildDataBase.longText=Update the DB to include new events."}) - public RebuildDataBase(TimeLineController controller) { + public UpdateDB(TimeLineController controller) { super(Bundle.RebuildDataBase_text()); setLongText(Bundle.RebuildDataBase_longText()); setGraphic(new ImageView(DB_REFRESH)); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java index 95e56b3355..1431673f22 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/FilteredEventsModel.java @@ -414,6 +414,15 @@ public final class FilteredEventsModel { return false; } + /** + * Post a TagsAddedEvent to all registered subscribers, if the given set of + * updated event IDs is not empty. + * + * @param updatedEventIDs The set of event ids to be included in the + * TagsAddedEvent. + * + * @return True if an event was posted. + */ private boolean postTagsAdded(Set updatedEventIDs) { boolean tagsUpdated = !updatedEventIDs.isEmpty(); if (tagsUpdated) { @@ -422,6 +431,15 @@ public final class FilteredEventsModel { return tagsUpdated; } + /** + * Post a TagsDeletedEvent to all registered subscribers, if the given set + * of updated event IDs is not empty. + * + * @param updatedEventIDs The set of event ids to be included in the + * TagsDeletedEvent. + * + * @return True if an event was posted. + */ private boolean postTagsDeleted(Set updatedEventIDs) { boolean tagsUpdated = !updatedEventIDs.isEmpty(); if (tagsUpdated) { @@ -430,22 +448,45 @@ public final class FilteredEventsModel { return tagsUpdated; } + /** + * Register the given object to receive events. + * + * @param o The object to register. Must implement public methods annotated + * with Subscribe. + */ synchronized public void registerForEvents(Object o) { eventbus.register(o); } + /** + * Un-register the given object, so it no longer receives events. + * + * @param o The object to un-register. + */ synchronized public void unRegisterForEvents(Object o) { eventbus.unregister(0); } - public void fireDBUpdated() { + /** + * Post a DBUpdatedEvent to all registered subscribers. + */ + public void postDBUpdated() { eventbus.post(new DBUpdatedEvent()); } - public void fireRefreshRequest() { + + /** + * Post a RefreshRequestedEvent to all registered subscribers. + */ + public void postRefreshRequest() { eventbus.post(new RefreshRequestedEvent()); } - public void reFireAutopsyEvent(AutopsyEvent event) { + /** + * (Re)Post an AutopsyEvent received from another event distribution system + * locally to all registered subscribers. + */ + public void postAutopsyEventLocally(AutopsyEvent event) { eventbus.post(event); } + } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java index e92dbe3f7d..75d72d913a 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/events/DBUpdatedEvent.java @@ -1,12 +1,28 @@ /* - * 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 2016 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.timeline.events; /** + * A "local" event published by filteredEventsModel to indicate that DB has been + * updated. * + * This event is not intended for use out side of the Timeline module. */ public class DBUpdatedEvent { diff --git a/Core/src/org/sleuthkit/autopsy/timeline/events/RefreshRequestedEvent.java b/Core/src/org/sleuthkit/autopsy/timeline/events/RefreshRequestedEvent.java index f8cdfe23e7..47b04eb479 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/events/RefreshRequestedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/events/RefreshRequestedEvent.java @@ -22,8 +22,8 @@ package org.sleuthkit.autopsy.timeline.events; * A "local" event published by filteredEventsModel to indicate that the user * requested that the current visualization be refreshed with out changing any * of the parameters ( to include more up to date tag data for example.) - *

- * This event is not intended for use out side of the timeline module. + * + * This event is not intended for use out side of the Timeline module. */ public class RefreshRequestedEvent { diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java index d418fba23b..edf74385f6 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/AbstractVisualizationPane.java @@ -96,25 +96,29 @@ public abstract class AbstractVisualizationPane> dataSeries = FXCollections.>observableArrayList(); protected final Map> eventTypeToSeriesMap = new HashMap<>(); @@ -136,14 +140,40 @@ public abstract class AbstractVisualizationPane selectedNodes = FXCollections.observableArrayList(); - private InvalidationListener updateListener = any -> update(); + /** + * Listener that is attached to various properties that should trigger a vis + * update when they change. + */ + private InvalidationListener updateListener = any -> refresh(); - public boolean needsRefresh() { - return needsRefresh.get(); + /** + * Does the visualization represent an out-of-date state of the DB. It might + * if, for example, tags have been updated but the vis. was not refreshed. + * + * @return True if the visualization does not represent the curent state of + * the DB. + */ + public boolean isOutOfDate() { + return outOfDate.get(); } - public ReadOnlyBooleanProperty needsRefreshProperty() { - return needsRefresh.getReadOnlyProperty(); + /** + * Set this visualization out of date because, for example, tags have been + * updated but the vis. was not refreshed. + */ + void setOutOfDate() { + outOfDate.set(true); + } + + /** + * Get a ReadOnlyBooleanProperty that holds true if this visualization does + * not represent the current state of the DB> + * + * @return A ReadOnlyBooleanProperty that holds the out-of-date state for + * this visualization. + */ + public ReadOnlyBooleanProperty outOfDateProperty() { + return outOfDate.getReadOnlyProperty(); } /** @@ -339,13 +369,13 @@ public abstract class AbstractVisualizationPane controller.setStatus(isHover() ? DEFAULT_TOOLTIP.getText() : "")); + hoverProperty().addListener(hoverProp -> controller.setStatusMessage(isHover() ? DEFAULT_TOOLTIP.getText() : "")); } @@ -534,10 +564,6 @@ public abstract class AbstractVisualizationPane The type of a single object that can represent * the range of data displayed along the X-Axis. */ - abstract protected class VisualizationUpdateTask extends LoggedTask { + abstract protected class VisualizationRefreshTask extends LoggedTask { private final Node center; @@ -657,10 +683,10 @@ public abstract class AbstractVisualizationPane { + countsToggle.toggleGroupProperty().addListener((Observable toggleGroup) -> { countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener); }); } @@ -303,6 +298,9 @@ final public class VisualizationPanel extends BorderPane { controller.visualizationModeProperty().addListener(visualizationMode -> syncVisualizationMode()); syncVisualizationMode(); + ActionUtils.configureButton(new SaveSnapshotAsReport(controller, notificationPane::getContent), snapShotButton); + ActionUtils.configureButton(new UpdateDB(controller), updateDBButton); + /////configure start and end pickers startLabel.setText(Bundle.VisualizationPanel_startLabel_text()); endLabel.setText(Bundle.VisualizationPanel_endLabel_text()); @@ -364,16 +362,8 @@ final public class VisualizationPanel extends BorderPane { } /** - * Set whether the visualziation may not represent the current state of the - * DB, because, for example, tags have been updated. - * - * @param needsRefresh True if the visualization may not represent the - * current state of the DB. - */ - /** - * Handle TagsUpdatedEvents. - * - * Mark that the visualization needs to be refreshed. + * Handle TagsUpdatedEvents by marking that the visualization needs to be + * refreshed. * * NOTE: This VisualizationPanel must be registered with the * filteredEventsModel's EventBus in order for this handler to be invoked. @@ -382,7 +372,7 @@ final public class VisualizationPanel extends BorderPane { */ @Subscribe public void handleTimeLineTagUpdate(TagsUpdatedEvent event) { - visualization.setNeedsRefresh(); + visualization.setOutOfDate(); Platform.runLater(() -> { if (notificationPane.isShowing() == false) { notificationPane.getActions().setAll(new Refresh()); @@ -392,7 +382,7 @@ final public class VisualizationPanel extends BorderPane { } /** - * Handle a RefreshRequestedEvent from the events model by updating the + * Handle a RefreshRequestedEvent from the events model by refreshing the * visualization. * * NOTE: This VisualizationPanel must be registered with the @@ -402,7 +392,7 @@ final public class VisualizationPanel extends BorderPane { */ @Subscribe public void handleRefreshRequested(RefreshRequestedEvent event) { - visualization.update(); + visualization.refresh(); Platform.runLater(() -> { if (Bundle.VisualizationPanel_tagsAddedOrDeleted().equals(notificationPane.getText())) { notificationPane.hide(); @@ -410,25 +400,59 @@ final public class VisualizationPanel extends BorderPane { }); } + /** + * Handle a DBUpdatedEvent from the events model by refreshing the + * visualization. + * + * NOTE: This VisualizationPanel must be registered with the + * filteredEventsModel's EventBus in order for this handler to be invoked. + * + * @param event The DBUpdatedEvent to handle. + */ @Subscribe public void handleDBUpdated(DBUpdatedEvent event) { + visualization.refresh(); refreshHistorgram(); Platform.runLater(notificationPane::hide); } + /** + * Handle a DataSourceAddedEvent from the events model by showing a + * notification. + * + * NOTE: This VisualizationPanel must be registered with the + * filteredEventsModel's EventBus in order for this handler to be invoked. + * + * @param event The DataSourceAddedEvent to handle. + */ @Subscribe + @NbBundle.Messages({ + "# {0} - datasource name", + "VisualizationPanel.notification.newDataSource={0} has been added as a new datasource. The Timeline DB may be out of date."}) public void handlDataSourceAdded(DataSourceAddedEvent event) { Platform.runLater(() -> { - notificationPane.getActions().setAll(new RebuildDataBase(controller)); - notificationPane.show("A new datasource, " + event.getDataSource().getName() + ", has been added. The Timeline DB may be out of date.", new ImageView(WARNING)); + notificationPane.getActions().setAll(new UpdateDB(controller)); + notificationPane.show(Bundle.VisualizationPanel_notification_newDataSource(event.getDataSource().getName()), new ImageView(WARNING)); }); } + /** + * Handle a DataSourceAnalysisCompletedEvent from the events modelby showing + * a notification. + * + * NOTE: This VisualizationPanel must be registered with the + * filteredEventsModel's EventBus in order for this handler to be invoked. + * + * @param event The DataSourceAnalysisCompletedEvent to handle. + */ @Subscribe + @NbBundle.Messages({ + "# {0} - datasource name", + "VisualizationPanel.notification.analysisComplete=Analysis has finished for {0}. The Timeline DB may be out of date."}) public void handleAnalysisCompleted(DataSourceAnalysisCompletedEvent event) { Platform.runLater(() -> { - notificationPane.getActions().setAll(new RebuildDataBase(controller)); - notificationPane.show("Analysis has finished for " + event.getDataSource().getName() + ". The Timeline DB may be out of date.", new ImageView(WARNING)); + notificationPane.getActions().setAll(new UpdateDB(controller)); + notificationPane.show(Bundle.VisualizationPanel_notification_analysisComplete(event.getDataSource().getName()), new ImageView(WARNING)); }); } @@ -590,14 +614,15 @@ final public class VisualizationPanel extends BorderPane { toolBar.getItems().removeAll(visualization.getSettingsNodes()); visualization.dispose(); } - //setup new vis. + visualization = vizPane; - ActionUtils.configureButton(new Refresh(), refreshButton); - visualization.update(); + //setup new vis. + ActionUtils.configureButton(new Refresh(), refreshButton);//configure new refresh action for new visualization + visualization.refresh(); toolBar.getItems().addAll(2, vizPane.getSettingsNodes()); notificationPane.setContent(visualization); - //listen to has event sproperty and show "dialog" if it is false. + //listen to has events property and show "dialog" if it is false. visualization.hasVisibleEventsProperty().addListener(hasEvents -> { notificationPane.setContent(visualization.hasVisibleEvents() ? visualization @@ -608,8 +633,6 @@ final public class VisualizationPanel extends BorderPane { ); }); }); - - Platform.runLater(notificationPane::hide); } @NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events") @@ -745,13 +768,13 @@ final public class VisualizationPanel extends BorderPane { @NbBundle.Messages({ "VisualizationPanel.refresh.text=Refresh Vis.", - "VisualizationPanel.refresh.longText=Refresh the visualization to include information that is in the database but not visualized, such as newly updated tags."}) + "VisualizationPanel.refresh.longText=Refresh the visualization to include information that is in the DB but not visualized, such as newly updated tags."}) Refresh() { super(Bundle.VisualizationPanel_refresh_text()); setLongText(Bundle.VisualizationPanel_refresh_longText()); setGraphic(new ImageView(REFRESH)); - setEventHandler(actionEvent -> filteredEvents.fireRefreshRequest()); - disabledProperty().bind(visualization.needsRefreshProperty().not()); + setEventHandler(actionEvent -> filteredEvents.postRefreshRequest()); + disabledProperty().bind(visualization.outOfDateProperty().not()); } } } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/CountsViewPane.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/CountsViewPane.java index 91649dcf37..3221d797df 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/CountsViewPane.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/CountsViewPane.java @@ -132,7 +132,7 @@ public class CountsViewPane extends AbstractVisualizationPane { - update(); + refresh(); syncAxisScaleLabel(); }); syncAxisScaleLabel(); @@ -306,7 +306,7 @@ public class CountsViewPane extends AbstractVisualizationPane> { + private class CountsUpdateTask extends VisualizationRefreshTask> { CountsUpdateTask() { super(Bundle.CountsViewPane_loggedTask_name(), true); diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/EventCountsChart.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/EventCountsChart.java index 477ef7eb64..031101ab1e 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/EventCountsChart.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/countsview/EventCountsChart.java @@ -403,7 +403,7 @@ final class EventCountsChart extends StackedBarChart implements Bundle.CountsViewPane_detailSwitchMessage(), Bundle.CountsViewPane_detailSwitchTitle(), JOptionPane.YES_NO_OPTION); if (showConfirmDialog == JOptionPane.YES_OPTION) { - controller.setViewMode(VisualizationMode.DETAIL); + controller.setVisualizationMode(VisualizationMode.DETAIL); } /* diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/DetailViewPane.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/DetailViewPane.java index 5b9dc12837..05e9165598 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/DetailViewPane.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/DetailViewPane.java @@ -344,7 +344,7 @@ public class DetailViewPane extends AbstractVisualizationPane { + private class DetailsUpdateTask extends VisualizationRefreshTask { DetailsUpdateTask() { super(Bundle.DetailViewPane_loggedTask_name(), true); From 38f98f210052f5b41cd952545a3f72ad4af2e932 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 12 May 2016 13:43:43 -0400 Subject: [PATCH 36/37] Clean up documentation/dead code in UserDefinedFileTypesManager --- .../UserDefinedFileTypesManager.java | 384 ++++++++---------- 1 file changed, 162 insertions(+), 222 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java index d22114bfbb..9950093045 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java @@ -20,22 +20,16 @@ package org.sleuthkit.autopsy.modules.filetypeid; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; import javax.xml.bind.DatatypeConverter; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import org.openide.util.NbBundle; import org.openide.util.io.NbObjectInputStream; import org.openide.util.io.NbObjectOutputStream; -import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; @@ -46,25 +40,13 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** - * Manages user-defined file types characterized by MIME type, signature, and - * optional membership in an interesting files set. - *

- * Note that this class exposes a very simple get/set API that operates on the - * user-defined file types as a complete set - there is no concept of adding, - * editing or deleting file types singly. This works because this class is not - * exposed outside of this ingest module package and is ONLY used in a very - * specific paradigm. In this paradigm, there is a single modal writer of file - * types in the form of a global settings panel that disables itself when ingest - * is running so that multiple readers in the form of file ingest modules get a - * consistent set of file type definitions. - *

- * Thread-safe. + * A singleton manager for the custom file types defined by Autopsy and by + * users. */ final class UserDefinedFileTypesManager { - private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName()); - private static final String USER_DEFINED_TYPES_XML_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS - private static final String USER_DEFINED_TYPES_SERIALIZATION_FILE = "UserFileTypeDefinitions.settings"; + private static final String XML_SETTINGS_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS + private static final String SERIALIZED_SETTINGS_FILE = "UserFileTypeDefinitions.settings"; //NON-NLS private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS private static final String MIME_TYPE_TAG_NAME = "MimeType"; //NON-NLS @@ -73,34 +55,15 @@ final class UserDefinedFileTypesManager { private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS private static final String RELATIVE_ATTRIBUTE = "RelativeToStart"; //NON-NLS - private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS - private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS - private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS private static UserDefinedFileTypesManager instance; - - /** - * File types to be persisted to the user-defined file type definitions file - * are stored in this mapping of MIME types to file types. Access to this - * map is guarded by the intrinsic lock of the user-defined file types - * manager for thread-safety. - */ private final List userDefinedFileTypes = new ArrayList<>(); + private final List allFileTypes = new ArrayList<>(); /** - * The combined set of user-defined file types and file types predefined by - * Autopsy are stored in this mapping of MIME types to file types. This is - * the current working set of file types. Access to this map is guarded by - * the intrinsic lock of the user-defined file types manager for - * thread-safety. - */ - private final List fileTypes = new ArrayList<>(); - - /** - * Gets the singleton manager of user-defined file types characterized by - * MIME type, signature, and optional membership in an interesting files - * set. + * Gets the singleton manager of the custom file types defined by Autopsy + * and by users. * - * @return The user-defined file types manager singleton. + * @return The custom file types manager singleton. */ synchronized static UserDefinedFileTypesManager getInstance() { if (instance == null) { @@ -110,19 +73,19 @@ final class UserDefinedFileTypesManager { } /** - * Creates a manager of user-defined file types characterized by MIME type, - * signature, and optional membership in an interesting files set. + * Constructs a manager for the custom file types defined by Autopsy and by + * users. */ private UserDefinedFileTypesManager() { } /** - * Gets both the predefined and the user-defined file types. + * Gets all of the custom file types defined by Autopsy and by users. * - * @return A mapping of file type names to file types, possibly empty. + * @return A list of file types, possibly empty. * - * @throws - * org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException + * @throws UserDefinedFileTypesException if there is a problem accessing the + * file types. */ synchronized List getFileTypes() throws UserDefinedFileTypesException { loadFileTypes(); @@ -133,16 +96,16 @@ final class UserDefinedFileTypesManager { * Collections.unmodifiableCollection() is not used here because this * view of the file types is a snapshot. */ - return new ArrayList<>(fileTypes); + return new ArrayList<>(allFileTypes); } /** - * Gets the user-defined file types. + * Gets the custom file types defined by users. * - * @return A mapping of file type names to file types, possibly empty. + * @return A list of file types, possibly empty. * - * @throws - * org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException + * @throws UserDefinedFileTypesException if there is a problem accessing the + * file types. */ synchronized List getUserDefinedFileTypes() throws UserDefinedFileTypesException { loadFileTypes(); @@ -157,15 +120,15 @@ final class UserDefinedFileTypesManager { } /** - * Loads the MIME type to file type mappings with predefined and - * user-defined types. + * Loads or re-loads the custom file types defined by Autopsy and by users. * - * @throws - * org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException + * @throws UserDefinedFileTypesException if there is a problem loading the + * file types. */ private void loadFileTypes() throws UserDefinedFileTypesException { - fileTypes.clear(); + allFileTypes.clear(); userDefinedFileTypes.clear(); + /** * Load the predefined types first so that they can be overwritten by * any user-defined types with the same names. @@ -175,156 +138,185 @@ final class UserDefinedFileTypesManager { } /** - * Adds the predefined file types to the in-memory mappings of MIME types to - * file types. + * Loads or re-loads the custom file types defined by Autopsy. * - * @throws - * org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException + * @throws UserDefinedFileTypesException if there is a problem loading the + * file types. */ private void loadPredefinedFileTypes() throws UserDefinedFileTypesException { byte[] byteArray; FileType fileType; try { + /* + * Add type for xml. + */ List signatureList; signatureList = new ArrayList<>(); - signatureList.add(new Signature(" newFileTypes) throws UserDefinedFileTypesException { - String filePath = getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE); + String filePath = getFileTypeDefinitionsFilePath(SERIALIZED_SETTINGS_FILE); writeFileTypes(newFileTypes, filePath); } @@ -378,72 +368,68 @@ final class UserDefinedFileTypesManager { } /** - * Writes a set of file types to a file. + * Writes a collection of custom file types to disk. * * @param fileTypes A collection of file types. * @param filePath The path to the destination file. * - * @throws ParserConfigurationException - * @throws IOException - * @throws FileNotFoundException - * @throws UnsupportedEncodingException - * @throws TransformerException + * @throws UserDefinedFileTypesException if there is a problem writing the + * file types. */ private static void writeFileTypes(List fileTypes, String filePath) throws UserDefinedFileTypesException { try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) { UserDefinedFileTypesSettings settings = new UserDefinedFileTypesSettings(fileTypes); out.writeObject(settings); } catch (IOException ex) { - throw new UserDefinedFileTypesException(String.format("Failed to write settings to %s", filePath), ex); + throw new UserDefinedFileTypesException(String.format("Failed to write settings to %s", filePath), ex); //NON-NLS } } /** - * Reads the file types + * Reads a collection of custom file types from disk. * - * @param filePath the file path where the file types are to be read + * @param filePath The path of the file from which the custom file types are + * to be read. * - * @return the file types + * @return The custom file types. * - * @throws ParserConfigurationException If the file cannot be read + * @throws UserDefinedFileTypesException if there is a problem reading the + * file types. */ - private static List readFileTypesSerialized() throws UserDefinedFileTypesException { - File serializedDefs = new File(getFileTypeDefinitionsFilePath(USER_DEFINED_TYPES_SERIALIZATION_FILE)); + private static List readSerializedFileTypes() throws UserDefinedFileTypesException { + File serializedDefs = new File(getFileTypeDefinitionsFilePath(SERIALIZED_SETTINGS_FILE)); try { try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(serializedDefs))) { UserDefinedFileTypesSettings filesSetsSettings = (UserDefinedFileTypesSettings) in.readObject(); return filesSetsSettings.getUserDefinedFileTypes(); } } catch (IOException | ClassNotFoundException ex) { - throw new UserDefinedFileTypesException("Couldn't read serialized settings.", ex); + throw new UserDefinedFileTypesException("Couldn't read serialized settings.", ex); //NON-NLS } } /** - * Provides a mechanism for reading a set of file type definitions from an - * XML file. + * Provides a mechanism for reading a set of custom file type definitions + * from an XML file. */ private static class XMLDefinitionsReader { /** - * Reads a set of file type definitions from an XML file. + * Reads a set of custom file type definitions from an XML file. * * @param filePath The path to the XML file. * - * @return A collection of file types read from the XML file. + * @return A collection of custom file types read from the XML file. + * + * @throws IOException if there is problem reading the + * XML file. + * @throws SAXException if there is a problem parsing + * the XML file. + * @throws ParserConfigurationException if there is a problem parsing + * the XML file. */ private static List readFileTypes(String filePath) throws IOException, SAXException, ParserConfigurationException { List fileTypes = new ArrayList<>(); - /* - * RC: Commenting out the loadDocument overload that validates - * against the XSD is a temp fix for a failure to provide an upgrade - * path when the RelativeToStart attribute was added to the - * Signature element. The upgrade path can be supplied, but the plan - * is to replace the use of XML with object serialization for the - * settings, so it may not be worth the effort. - */ - // private static final String FILE_TYPE_DEFINITIONS_SCHEMA_FILE = "FileTypes.xsd"; //NON-NLS - // Document doc = XMLUtil.loadDocument(filePath, UserDefinedFileTypesManager.class, FILE_TYPE_DEFINITIONS_SCHEMA_FILE); Document doc = XMLUtil.loadDocument(filePath); if (doc != null) { Element fileTypesElem = doc.getDocumentElement(); @@ -460,14 +446,16 @@ final class UserDefinedFileTypesManager { } /** - * Gets a file type definition from a file type XML element. + * Gets a custom file type definition from a file type XML element. * * @param fileTypeElem The XML element. * * @return A file type object. * - * @throws IllegalArgumentException - * @throws NumberFormatException + * @throws IllegalArgumentException if there is a problem parsing the + * file type. + * @throws NumberFormatException if there is a problem parsing the + * file type. */ private static FileType parseFileType(Element fileTypeElem) throws IllegalArgumentException, NumberFormatException { String mimeType = XMLDefinitionsReader.parseMimeType(fileTypeElem); @@ -522,35 +510,6 @@ final class UserDefinedFileTypesManager { return new Signature(signatureBytes, offset, signatureType, isRelativeToStart); } - /** - * Gets the interesting files set name from a file type XML element. - * - * @param fileTypeElem The XML element. - * - * @return The files set name, possibly empty. - */ - private static String parseInterestingFilesSet(Element fileTypeElem) { - String filesSetName = ""; - NodeList filesSetElems = fileTypeElem.getElementsByTagName(INTERESTING_FILES_SET_TAG_NAME); - if (filesSetElems.getLength() > 0) { - Element filesSetElem = (Element) filesSetElems.item(0); - filesSetName = filesSetElem.getTextContent(); - } - return filesSetName; - } - - /** - * Gets the alert attribute from a file type XML element. - * - * @param fileTypeElem The XML element. - * - * @return True or false; - */ - private static boolean parseAlert(Element fileTypeElem) { - String alertAttribute = fileTypeElem.getAttribute(ALERT_ATTRIBUTE); - return Boolean.parseBoolean(alertAttribute); - } - /** * Gets the text content of a single child element. * @@ -570,7 +529,7 @@ final class UserDefinedFileTypesManager { } /** - * Private constructor suppresses creation of instanmces of this utility + * Private constructor suppresses creation of instances of this utility * class. */ private XMLDefinitionsReader() { @@ -579,26 +538,7 @@ final class UserDefinedFileTypesManager { } /** - * Logs an exception, bundles the exception with a simple message in a - * uniform exception type, and throws the wrapper exception. - * - * @param ex The exception to wrap. - * @param messageKey A key into the bundle file that maps to the desired - * message. - * - * @throws - * org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException - */ - private void throwUserDefinedFileTypesException(Exception ex, String messageKey) throws UserDefinedFileTypesException { - String message = NbBundle.getMessage(UserDefinedFileTypesManager.class, messageKey); - logger.log(Level.SEVERE, message, ex); - throw new UserDefinedFileTypesException(message, ex); - } - - /** - * Used to translate more implementation-details-specific exceptions (which - * are logged by this class) into more generic exceptions for propagation to - * clients of the user-defined file types manager. + * .An exception thrown by the custom file types manager. */ static class UserDefinedFileTypesException extends Exception { From 4ea7eb11f817cba4842c42baceb24fd33fef01e7 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 12 May 2016 13:46:08 -0400 Subject: [PATCH 37/37] Class name change: UserDefinedFileTypesManager to CustomFileTypesManager --- ...nager.java => CustomFileTypesManager.java} | 54 +++++++++---------- .../modules/filetypeid/FileTypeDetector.java | 4 +- .../FileTypeIdGlobalSettingsPanel.java | 10 ++-- 3 files changed, 34 insertions(+), 34 deletions(-) rename Core/src/org/sleuthkit/autopsy/modules/filetypeid/{UserDefinedFileTypesManager.java => CustomFileTypesManager.java} (91%) diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java similarity index 91% rename from Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java rename to Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java index 9950093045..60b5479608 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/CustomFileTypesManager.java @@ -43,7 +43,7 @@ import org.xml.sax.SAXException; * A singleton manager for the custom file types defined by Autopsy and by * users. */ -final class UserDefinedFileTypesManager { +final class CustomFileTypesManager { private static final String XML_SETTINGS_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS private static final String SERIALIZED_SETTINGS_FILE = "UserFileTypeDefinitions.settings"; //NON-NLS @@ -55,7 +55,7 @@ final class UserDefinedFileTypesManager { private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS private static final String RELATIVE_ATTRIBUTE = "RelativeToStart"; //NON-NLS - private static UserDefinedFileTypesManager instance; + private static CustomFileTypesManager instance; private final List userDefinedFileTypes = new ArrayList<>(); private final List allFileTypes = new ArrayList<>(); @@ -65,9 +65,9 @@ final class UserDefinedFileTypesManager { * * @return The custom file types manager singleton. */ - synchronized static UserDefinedFileTypesManager getInstance() { + synchronized static CustomFileTypesManager getInstance() { if (instance == null) { - instance = new UserDefinedFileTypesManager(); + instance = new CustomFileTypesManager(); } return instance; } @@ -76,7 +76,7 @@ final class UserDefinedFileTypesManager { * Constructs a manager for the custom file types defined by Autopsy and by * users. */ - private UserDefinedFileTypesManager() { + private CustomFileTypesManager() { } /** @@ -84,10 +84,10 @@ final class UserDefinedFileTypesManager { * * @return A list of file types, possibly empty. * - * @throws UserDefinedFileTypesException if there is a problem accessing the + * @throws CustomFileTypesException if there is a problem accessing the * file types. */ - synchronized List getFileTypes() throws UserDefinedFileTypesException { + synchronized List getFileTypes() throws CustomFileTypesException { loadFileTypes(); /** @@ -104,10 +104,10 @@ final class UserDefinedFileTypesManager { * * @return A list of file types, possibly empty. * - * @throws UserDefinedFileTypesException if there is a problem accessing the + * @throws CustomFileTypesException if there is a problem accessing the * file types. */ - synchronized List getUserDefinedFileTypes() throws UserDefinedFileTypesException { + synchronized List getUserDefinedFileTypes() throws CustomFileTypesException { loadFileTypes(); /** @@ -122,10 +122,10 @@ final class UserDefinedFileTypesManager { /** * Loads or re-loads the custom file types defined by Autopsy and by users. * - * @throws UserDefinedFileTypesException if there is a problem loading the + * @throws CustomFileTypesException if there is a problem loading the * file types. */ - private void loadFileTypes() throws UserDefinedFileTypesException { + private void loadFileTypes() throws CustomFileTypesException { allFileTypes.clear(); userDefinedFileTypes.clear(); @@ -140,10 +140,10 @@ final class UserDefinedFileTypesManager { /** * Loads or re-loads the custom file types defined by Autopsy. * - * @throws UserDefinedFileTypesException if there is a problem loading the + * @throws CustomFileTypesException if there is a problem loading the * file types. */ - private void loadPredefinedFileTypes() throws UserDefinedFileTypesException { + private void loadPredefinedFileTypes() throws CustomFileTypesException { byte[] byteArray; FileType fileType; @@ -298,17 +298,17 @@ final class UserDefinedFileTypesManager { /* * parseHexBinary() throws this if the argument passed in is not hex */ - throw new UserDefinedFileTypesException("Error creating predefined file types", ex); // + throw new CustomFileTypesException("Error creating predefined file types", ex); // } } /** * Loads or re-loads the custom file types defined by users. * - * @throws UserDefinedFileTypesException if there is a problem loading the + * @throws CustomFileTypesException if there is a problem loading the * file types. */ - private void loadUserDefinedFileTypes() throws UserDefinedFileTypesException { + private void loadUserDefinedFileTypes() throws CustomFileTypesException { try { File serialized = new File(getFileTypeDefinitionsFilePath(SERIALIZED_SETTINGS_FILE)); if (serialized.exists()) { @@ -331,7 +331,7 @@ final class UserDefinedFileTypesManager { */ allFileTypes.clear(); userDefinedFileTypes.clear(); - throw new UserDefinedFileTypesException("UserDefinedFileTypesManager.loadFileTypes.errorMessage", ex); + throw new CustomFileTypesException("UserDefinedFileTypesManager.loadFileTypes.errorMessage", ex); } } @@ -350,7 +350,7 @@ final class UserDefinedFileTypesManager { * * @param newFileTypes A list of user-defined file types. */ - synchronized void setUserDefinedFileTypes(List newFileTypes) throws UserDefinedFileTypesException { + synchronized void setUserDefinedFileTypes(List newFileTypes) throws CustomFileTypesException { String filePath = getFileTypeDefinitionsFilePath(SERIALIZED_SETTINGS_FILE); writeFileTypes(newFileTypes, filePath); } @@ -373,15 +373,15 @@ final class UserDefinedFileTypesManager { * @param fileTypes A collection of file types. * @param filePath The path to the destination file. * - * @throws UserDefinedFileTypesException if there is a problem writing the + * @throws CustomFileTypesException if there is a problem writing the * file types. */ - private static void writeFileTypes(List fileTypes, String filePath) throws UserDefinedFileTypesException { + private static void writeFileTypes(List fileTypes, String filePath) throws CustomFileTypesException { try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) { UserDefinedFileTypesSettings settings = new UserDefinedFileTypesSettings(fileTypes); out.writeObject(settings); } catch (IOException ex) { - throw new UserDefinedFileTypesException(String.format("Failed to write settings to %s", filePath), ex); //NON-NLS + throw new CustomFileTypesException(String.format("Failed to write settings to %s", filePath), ex); //NON-NLS } } @@ -393,10 +393,10 @@ final class UserDefinedFileTypesManager { * * @return The custom file types. * - * @throws UserDefinedFileTypesException if there is a problem reading the + * @throws CustomFileTypesException if there is a problem reading the * file types. */ - private static List readSerializedFileTypes() throws UserDefinedFileTypesException { + private static List readSerializedFileTypes() throws CustomFileTypesException { File serializedDefs = new File(getFileTypeDefinitionsFilePath(SERIALIZED_SETTINGS_FILE)); try { try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(serializedDefs))) { @@ -404,7 +404,7 @@ final class UserDefinedFileTypesManager { return filesSetsSettings.getUserDefinedFileTypes(); } } catch (IOException | ClassNotFoundException ex) { - throw new UserDefinedFileTypesException("Couldn't read serialized settings.", ex); //NON-NLS + throw new CustomFileTypesException("Couldn't read serialized settings.", ex); //NON-NLS } } @@ -540,15 +540,15 @@ final class UserDefinedFileTypesManager { /** * .An exception thrown by the custom file types manager. */ - static class UserDefinedFileTypesException extends Exception { + static class CustomFileTypesException extends Exception { private static final long serialVersionUID = 1L; - UserDefinedFileTypesException(String message) { + CustomFileTypesException(String message) { super(message); } - UserDefinedFileTypesException(String message, Throwable throwable) { + CustomFileTypesException(String message, Throwable throwable) { super(message, throwable); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java index e33740805f..bb65ad7376 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java @@ -60,8 +60,8 @@ public class FileTypeDetector { */ public FileTypeDetector() throws FileTypeDetectorInitException { try { - userDefinedFileTypes = UserDefinedFileTypesManager.getInstance().getFileTypes(); - } catch (UserDefinedFileTypesManager.UserDefinedFileTypesException ex) { + userDefinedFileTypes = CustomFileTypesManager.getInstance().getFileTypes(); + } catch (CustomFileTypesManager.CustomFileTypesException ex) { throw new FileTypeDetectorInitException(Bundle.CouldNotInitializeFileTypeDetector(), ex); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java index 1361169c45..72e45983ba 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java @@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; -import org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException; +import org.sleuthkit.autopsy.modules.filetypeid.CustomFileTypesManager.CustomFileTypesException; /** * A panel to allow a user to make custom file type definitions. In addition to @@ -207,12 +207,12 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane @Override public void load() { try { - fileTypes = UserDefinedFileTypesManager.getInstance().getUserDefinedFileTypes(); + fileTypes = CustomFileTypesManager.getInstance().getUserDefinedFileTypes(); updateFileTypesListModel(); if (!typesListModel.isEmpty()) { typesList.setSelectedIndex(0); } - } catch (UserDefinedFileTypesException ex) { + } catch (CustomFileTypesException ex) { JOptionPane.showMessageDialog(null, ex.getLocalizedMessage(), NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title"), @@ -266,8 +266,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane @Override public void store() { try { - UserDefinedFileTypesManager.getInstance().setUserDefinedFileTypes(fileTypes); - } catch (UserDefinedFileTypesManager.UserDefinedFileTypesException ex) { + CustomFileTypesManager.getInstance().setUserDefinedFileTypes(fileTypes); + } catch (CustomFileTypesManager.CustomFileTypesException ex) { JOptionPane.showMessageDialog(null, ex.getLocalizedMessage(), NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"),