From 26cf95a285579a983cba0c0d50c3df339661fece Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 28 Nov 2017 09:41:29 -0500 Subject: [PATCH 01/38] Working on update code --- .../centralrepository/datamodel/EamDb.java | 3 + .../datamodel/EamDbUtil.java | 87 ++++++++++++++++++- .../datamodel/PostgresEamDbSettings.java | 2 +- .../datamodel/SqliteEamDbSettings.java | 5 +- 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index b021a1fcfc..1fe1ed5aa1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Set; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; /** * Main interface for interacting with the database @@ -29,6 +30,8 @@ import org.sleuthkit.autopsy.casemodule.Case; public interface EamDb { public static final int SCHEMA_VERSION = 1; + public static final CaseDbSchemaVersionNumber CURRENT_DB_SCHEMA_VERSION + = new CaseDbSchemaVersionNumber(1, 1); /** * Get the instance diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java index 5d70d6fdac..e851ff97be 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java @@ -25,9 +25,10 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.logging.Level; -import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDb.SCHEMA_VERSION; +import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDb.CURRENT_DB_SCHEMA_VERSION; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; /** * @@ -132,6 +133,7 @@ public class EamDbUtil { * * @return true on success, else false */ + /* public static boolean insertSchemaVersion(Connection conn) { PreparedStatement preparedStatement = null; String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; @@ -146,6 +148,38 @@ public class EamDbUtil { } finally { EamDbUtil.closePreparedStatement(preparedStatement); } + return true; + }*/ + + static boolean updateSchemaVersion(Connection conn){ + + Statement statement; + ResultSet resultSet; + //PreparedStatement preparedStatement = null; + String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; + try { + statement = conn.createStatement(); + resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_VERSION'"); + if(resultSet.next()){ + int id = resultSet.getInt("id"); + statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMajor() + " WHERE id=" + id); + } else { + statement.execute("INSERT INTO db_info (name, value) VALUES (SCHEMA_VERSION, " + CURRENT_DB_SCHEMA_VERSION.getMajor() + ")"); + } + + resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_MINOR_VERSION'"); + if(resultSet.next()){ + int id = resultSet.getInt("id"); + statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMinor() + " WHERE id=" + id); + } else { + statement.execute("INSERT INTO db_info (name, value) VALUES (SCHEMA_MINOR_VERSION, " + CURRENT_DB_SCHEMA_VERSION.getMinor() + ")"); + } + } catch (SQLException ex) { + LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex); + return false; + } finally { + } + return true; } @@ -174,6 +208,57 @@ public class EamDbUtil { } return true; } + + static void updateSchema(Connection conn){ + if (null == conn) { + // Add exception + return; + } + + ResultSet resultSet = null; + Statement statement; + try { + + statement = conn.createStatement(); + + int minorVersion = 0; + int majorVersion = 0; + resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'"); + if(resultSet.next()){ + String minorVersionStr = resultSet.getString("value"); + try{ + minorVersion = Integer.parseInt(minorVersionStr); + } catch (NumberFormatException ex){ + ex.printStackTrace(); + } + } + + resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_VERSION'"); + if(resultSet.next()){ + String majorVersionStr = resultSet.getString("value"); + try{ + majorVersion = Integer.parseInt(majorVersionStr); + } catch (NumberFormatException ex){ + ex.printStackTrace(); + } + } + + System.out.println("Current schema version: " + majorVersion + "." + minorVersion); + CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion); + + if(dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0){ + statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS + statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS + statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS + } + + updateSchemaVersion(conn); + } catch (SQLException ex) { + ex.printStackTrace(); + } finally { + EamDbUtil.closeResultSet(resultSet); + } + } /** * If the Central Repos use has been enabled. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java index bfb3f04b32..22ade065e3 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java @@ -485,7 +485,7 @@ public final class PostgresEamDbSettings { } boolean result = EamDbUtil.insertDefaultCorrelationTypes(conn) - && EamDbUtil.insertSchemaVersion(conn); + && EamDbUtil.updateSchemaVersion(conn); EamDbUtil.closeConnection(conn); return result; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java index b4ea1aa8a2..20ad88a7cc 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java @@ -87,6 +87,9 @@ public final class SqliteEamDbSettings { } + + System.out.println("\n#### UPDATING DATABASE!!!"); + EamDbUtil.updateSchema(getEphemeralConnection()); } public void saveSettings() { @@ -434,7 +437,7 @@ public final class SqliteEamDbSettings { } boolean result = EamDbUtil.insertDefaultCorrelationTypes(conn) - && EamDbUtil.insertSchemaVersion(conn); + && EamDbUtil.updateSchemaVersion(conn); EamDbUtil.closeConnection(conn); return result; } From d1e0f7243b578614b7ea919c850655184ad85649 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 1 Dec 2017 11:17:10 -0500 Subject: [PATCH 02/38] Moved updateSchema code --- .../datamodel/AbstractSqlEamDb.java | 69 +++++++++++++++++ .../centralrepository/datamodel/EamDb.java | 6 ++ .../datamodel/EamDbUtil.java | 74 ++++++------------- .../datamodel/SqliteEamDb.java | 14 ++++ .../eventlisteners/Installer.java | 3 + .../optionspanel/GlobalSettingsPanel.java | 8 ++ 6 files changed, 124 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index f9c2435472..f132a468d5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -36,7 +36,9 @@ import java.util.Map; import java.util.Set; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; +import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil.updateSchemaVersion; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; import org.sleuthkit.datamodel.TskData; /** @@ -2206,5 +2208,72 @@ public abstract class AbstractSqlEamDb implements EamDb { return eamGlobalFileInstance; } + + void updateSchema() { + + ResultSet resultSet = null; + Statement statement; + Connection conn = null; + try { + conn = connect(); + conn.setAutoCommit(false); + statement = conn.createStatement(); + + int minorVersion = 0; + int majorVersion = 0; + resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'"); + if (resultSet.next()) { + String minorVersionStr = resultSet.getString("value"); + try { + minorVersion = Integer.parseInt(minorVersionStr); + } catch (NumberFormatException ex) { + ex.printStackTrace(); + } + } + + resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_VERSION'"); + if (resultSet.next()) { + String majorVersionStr = resultSet.getString("value"); + try { + majorVersion = Integer.parseInt(majorVersionStr); + } catch (NumberFormatException ex) { + ex.printStackTrace(); + } + } + + System.out.println("Current schema version: " + majorVersion + "." + minorVersion); + CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion); + + if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0) { + statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS + statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS + statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS + } + + if (!updateSchemaVersion(conn)) { + + // Log error + return; + } + + conn.commit(); + } catch (SQLException | EamDbException ex) { + try { + if(conn != null){ + conn.rollback(); + } + } catch (SQLException ex2) { + // We're alredy in an error state + } + ex.printStackTrace(); + } finally { + EamDbUtil.closeResultSet(resultSet); + try { + conn.setAutoCommit(true); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 1fe1ed5aa1..8d6a49fc9d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -585,4 +585,10 @@ public interface EamDb { * @throws EamDbException */ public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException; + + /** + * Update the schema of the database (if needed) + * @throws EamDbException + */ + public void updateSchema() throws EamDbException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java index e851ff97be..eb66856673 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java @@ -150,9 +150,8 @@ public class EamDbUtil { } return true; }*/ - - static boolean updateSchemaVersion(Connection conn){ - + static boolean updateSchemaVersion(Connection conn) { + Statement statement; ResultSet resultSet; //PreparedStatement preparedStatement = null; @@ -160,15 +159,15 @@ public class EamDbUtil { try { statement = conn.createStatement(); resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_VERSION'"); - if(resultSet.next()){ + if (resultSet.next()) { int id = resultSet.getInt("id"); statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMajor() + " WHERE id=" + id); } else { statement.execute("INSERT INTO db_info (name, value) VALUES (SCHEMA_VERSION, " + CURRENT_DB_SCHEMA_VERSION.getMajor() + ")"); } - + resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_MINOR_VERSION'"); - if(resultSet.next()){ + if (resultSet.next()) { int id = resultSet.getInt("id"); statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMinor() + " WHERE id=" + id); } else { @@ -179,7 +178,7 @@ public class EamDbUtil { return false; } finally { } - + return true; } @@ -208,55 +207,30 @@ public class EamDbUtil { } return true; } - - static void updateSchema(Connection conn){ - if (null == conn) { - // Add exception + + /** + * + */ + public static void updateDatabase() { + if (!EamDb.isEnabled()) { return; } - ResultSet resultSet = null; - Statement statement; try { - - statement = conn.createStatement(); - - int minorVersion = 0; - int majorVersion = 0; - resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_MINOR_VERSION'"); - if(resultSet.next()){ - String minorVersionStr = resultSet.getString("value"); - try{ - minorVersion = Integer.parseInt(minorVersionStr); - } catch (NumberFormatException ex){ - ex.printStackTrace(); - } + EamDb db = EamDb.getInstance(); + + if (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.POSTGRESQL) { + // Try to get a lock here } - resultSet = statement.executeQuery("SELECT value FROM db_info WHERE name='SCHEMA_VERSION'"); - if(resultSet.next()){ - String majorVersionStr = resultSet.getString("value"); - try{ - majorVersion = Integer.parseInt(majorVersionStr); - } catch (NumberFormatException ex){ - ex.printStackTrace(); - } - } - - System.out.println("Current schema version: " + majorVersion + "." + minorVersion); - CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion); - - if(dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0){ - statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS - statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS - statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS - } - - updateSchemaVersion(conn); - } catch (SQLException ex) { + db.updateSchema(); + + } catch (EamDbException ex) { ex.printStackTrace(); } finally { - EamDbUtil.closeResultSet(resultSet); + if (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.POSTGRESQL) { + // Release lock here + } } } @@ -264,7 +238,7 @@ public class EamDbUtil { * If the Central Repos use has been enabled. * * @return true if the Central Repo may be configured, false if it should - * not be able to be + * not be able to be */ public static boolean useCentralRepo() { return Boolean.parseBoolean(ModuleSettings.getConfigSetting(CENTRAL_REPO_NAME, CENTRAL_REPO_USE_KEY)); @@ -275,7 +249,7 @@ public class EamDbUtil { * configured. * * @param centralRepoCheckBoxIsSelected - true if the central repo can be - * used + * used */ public static void setUseCentralRepo(boolean centralRepoCheckBoxIsSelected) { ModuleSettings.setConfigSetting(CENTRAL_REPO_NAME, CENTRAL_REPO_USE_KEY, Boolean.toString(centralRepoCheckBoxIsSelected)); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 3e79f5abca..f774909b5b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -988,6 +988,20 @@ public class SqliteEamDb extends AbstractSqlEamDb { } } + /** + * Update the schema of the database (if needed) + * @throws EamDbException + */ + @Override + public void updateSchema() throws EamDbException { + try{ + acquireExclusiveLock(); + super.updateSchema(); + } finally { + releaseExclusiveLock(); + } + } + /** * Acquire the lock that provides exclusive access to the case database. * Call this method in a try block with a call to diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 8af34bc718..03bd73b966 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -52,6 +52,9 @@ public class Installer extends ModuleInstall { ieListener.installListeners(); // TODO: create a thread pool to process Runners. + + System.out.println("\n#######\nIn Installer:restored()\n\n#########"); + } @Override diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 8b6ce90e96..905b5060fe 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -77,6 +77,11 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i IngestManager.getInstance().addIngestJobEventListener(ingestJobEventListener); ingestStateUpdated(); } + + private void updateDatabase(){ + // Add UI stuff later + EamDbUtil.updateDatabase(); + } /** * This method is called from within the constructor to initialize the form. @@ -317,15 +322,18 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i EamDbSettingsDialog dialog = new EamDbSettingsDialog(); load(); // reload db settings content and update buttons if (dialog.wasConfigurationChanged()) { + updateDatabase(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } }//GEN-LAST:event_bnDbConfigureActionPerformed private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed //if saved setting is disabled checkbox should be disabled already + store(); enableDatabaseConfigureButton(cbUseCentralRepo.isSelected()); enableButtonSubComponents(cbUseCentralRepo.isSelected() && !EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED)); this.ingestStateUpdated(); + updateDatabase(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_cbUseCentralRepoActionPerformed From fe07114cbc3a254fcd4ad815e8eb7a9fa6494f4c Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 1 Dec 2017 15:32:19 -0500 Subject: [PATCH 03/38] Fixing some database queries. Improved error handling. --- .../datamodel/AbstractSqlEamDb.java | 16 ++++++++++++---- .../centralrepository/datamodel/EamDbUtil.java | 4 ++-- .../eventlisteners/Installer.java | 4 +++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index b9d445f8b6..2f44aef4be 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -34,6 +34,7 @@ import java.time.LocalDate; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.logging.Level; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil.updateSchemaVersion; @@ -2232,7 +2233,7 @@ public abstract class AbstractSqlEamDb implements EamDb { try { minorVersion = Integer.parseInt(minorVersionStr); } catch (NumberFormatException ex) { - ex.printStackTrace(); + throw new EamDbException("Bad value for schema minor version - database is corrupt"); } } @@ -2242,12 +2243,16 @@ public abstract class AbstractSqlEamDb implements EamDb { try { majorVersion = Integer.parseInt(majorVersionStr); } catch (NumberFormatException ex) { - ex.printStackTrace(); + throw new EamDbException("Bad value for schema version - database is corrupt"); } } System.out.println("Current schema version: " + majorVersion + "." + minorVersion); CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion); + if(dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)){ + LOGGER.log(Level.INFO, "Central Repository is up to date"); + return; + } // Update from 1.0 to 1.1 if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 1)) < 0) { @@ -2255,16 +2260,19 @@ public abstract class AbstractSqlEamDb implements EamDb { statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS - statement.execute("INSERT INTO organizations (name) VALUES (" + EamDbUtil.getDefaultOrgName() + ")"); + // There's an outide chance that the user has already made an organization with the default name, + // and the default org being missing will not impact any database operations, so continue on + // regardless of whether this succeeds. + EamDbUtil.insertDefaultOrganization(conn); } if (!updateSchemaVersion(conn)) { - // Log error return; } conn.commit(); + LOGGER.log(Level.INFO, "Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION); } catch (SQLException | EamDbException ex) { try { if(conn != null){ diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java index d047eb278c..7a4dd45f00 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java @@ -164,7 +164,7 @@ public class EamDbUtil { int id = resultSet.getInt("id"); statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMajor() + " WHERE id=" + id); } else { - statement.execute("INSERT INTO db_info (name, value) VALUES (SCHEMA_VERSION, " + CURRENT_DB_SCHEMA_VERSION.getMajor() + ")"); + statement.execute("INSERT INTO db_info (name, value) VALUES ('SCHEMA_VERSION', '" + CURRENT_DB_SCHEMA_VERSION.getMajor() + "')"); } resultSet = statement.executeQuery("SELECT id FROM db_info WHERE name='SCHEMA_MINOR_VERSION'"); @@ -172,7 +172,7 @@ public class EamDbUtil { int id = resultSet.getInt("id"); statement.execute("UPDATE db_info SET value=" + CURRENT_DB_SCHEMA_VERSION.getMinor() + " WHERE id=" + id); } else { - statement.execute("INSERT INTO db_info (name, value) VALUES (SCHEMA_MINOR_VERSION, " + CURRENT_DB_SCHEMA_VERSION.getMinor() + ")"); + statement.execute("INSERT INTO db_info (name, value) VALUES ('SCHEMA_MINOR_VERSION', '" + CURRENT_DB_SCHEMA_VERSION.getMinor() + "')"); } } catch (SQLException ex) { LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 03bd73b966..dbae33431c 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners; import org.openide.modules.ModuleInstall; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; import org.sleuthkit.autopsy.coreutils.Logger; /** @@ -54,7 +56,7 @@ public class Installer extends ModuleInstall { // TODO: create a thread pool to process Runners. System.out.println("\n#######\nIn Installer:restored()\n\n#########"); - + EamDbUtil.updateDatabase(); } @Override From 8a4b4f3f81aaa997cbf4fb55bfa911eb931d3a34 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 1 Dec 2017 16:22:31 -0500 Subject: [PATCH 04/38] Testing --- .../centralrepository/datamodel/AbstractSqlEamDb.java | 6 +++++- .../autopsy/centralrepository/datamodel/EamDbUtil.java | 3 ++- .../autopsy/centralrepository/eventlisteners/Installer.java | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 2f44aef4be..e1ea3649b0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -2221,6 +2221,8 @@ public abstract class AbstractSqlEamDb implements EamDb { Statement statement; Connection conn = null; try { + throw new EamDbException("Test failure"); + /* conn = connect(); conn.setAutoCommit(false); statement = conn.createStatement(); @@ -2273,7 +2275,8 @@ public abstract class AbstractSqlEamDb implements EamDb { conn.commit(); LOGGER.log(Level.INFO, "Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION); - } catch (SQLException | EamDbException ex) { + } catch (SQLException | EamDbException ex) {*/ + } catch (EamDbException ex) { try { if(conn != null){ conn.rollback(); @@ -2282,6 +2285,7 @@ public abstract class AbstractSqlEamDb implements EamDb { // We're alredy in an error state } ex.printStackTrace(); + throw ex; } finally { EamDbUtil.closeResultSet(resultSet); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java index 7a4dd45f00..66bc6d4221 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java @@ -28,7 +28,7 @@ import java.util.logging.Level; import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDb.CURRENT_DB_SCHEMA_VERSION; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; -import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; /** * @@ -227,6 +227,7 @@ public class EamDbUtil { db.updateSchema(); } catch (EamDbException ex) { + MessageNotifyUtil.Message.error(ex.getLocalizedMessage()); ex.printStackTrace(); } finally { if (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.POSTGRESQL) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index dbae33431c..bf384fbb89 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -55,7 +55,6 @@ public class Installer extends ModuleInstall { // TODO: create a thread pool to process Runners. - System.out.println("\n#######\nIn Installer:restored()\n\n#########"); EamDbUtil.updateDatabase(); } From e442bf58b05de1adb67b95e0b7b7545b2c2bf7dc Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 1 Dec 2017 17:32:52 -0500 Subject: [PATCH 05/38] 3219: Replace JCalendarButton with LGoodDatePick for DateSearchPanel --- Core/ivy.xml | 1 + Core/nbproject/project.properties | 3 + Core/nbproject/project.xml | 4 + .../autopsy/filesearch/Bundle.properties | 4 - .../autopsy/filesearch/DateSearchFilter.java | 10 +- .../autopsy/filesearch/DateSearchPanel.form | 109 +++----- .../autopsy/filesearch/DateSearchPanel.java | 240 ++++-------------- 7 files changed, 98 insertions(+), 273 deletions(-) diff --git a/Core/ivy.xml b/Core/ivy.xml index eea67feb19..c2b6142ebc 100755 --- a/Core/ivy.xml +++ b/Core/ivy.xml @@ -22,5 +22,6 @@ + diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 7c36c61db7..9d3e275ca5 100755 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -6,6 +6,7 @@ file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4. file.reference.jdom-2.0.5-contrib.jar=release/modules/ext/jdom-2.0.5-contrib.jar file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar +file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar file.reference.metadata-extractor-2.9.1.jar=release/modules/ext/metadata-extractor-2.9.1.jar file.reference.postgresql-9.4.1211.jre7.jar=release/modules/ext/postgresql-9.4.1211.jre7.jar @@ -25,10 +26,12 @@ file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8 file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial +javadoc.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar license.file=../LICENSE-2.0.txt nbm.homepage=http://www.sleuthkit.org/ nbm.module.author=Brian Carrier nbm.needs.restart=true source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar +source.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar spec.version.base=10.9 diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 525e6da6a7..0b1523da09 100755 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -332,6 +332,10 @@ ext/tika-core-1.14.jar release/modules/ext/tika-core-1.14.jar + + ext/LGoodDatePicker-10.3.1.jar + release/modules/ext/LGoodDatePicker-10.3.1.jar + ext/Tsk_DataModel_PostgreSQL.jar release/modules/ext/Tsk_DataModel_PostgreSQL.jar diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties index bb91c8e05c..6d83acae14 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties @@ -12,11 +12,7 @@ DateSearchPanel.createdCheckBox.text=Created DateSearchPanel.accessedCheckBox.text=Accessed DateSearchPanel.changedCheckBox.text=Changed DateSearchPanel.modifiedCheckBox.text=Modified -DateSearchPanel.dateToButtonCalendar.text= -DateSearchPanel.dateToTextField.text= DateSearchPanel.jLabel1.text=to -DateSearchPanel.dateFromTextField.text= -DateSearchPanel.dateFromButtonCalendar.text= NameSearchPanel.nameCheckBox.text=Name: NameSearchPanel.noteNameLabel.text=*Note: Name match is case insensitive and matches any part of the file name. Regular expressions are not currently supported. NameSearchPanel.searchTextField.text= diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java index 3291c5ae42..64666e66d9 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java @@ -82,7 +82,7 @@ class DateSearchFilter extends AbstractFileSearchFilter { // convert the date from the selected timezone to get the GMT long fromDate = 0; - String startDateValue = panel.getDateFromTextField().getText(); + String startDateValue = panel.getFromDate(); Calendar startDate = getCalendarDate(startDateValue); if (!startDateValue.isEmpty()) { if (startDate != null) { @@ -91,7 +91,7 @@ class DateSearchFilter extends AbstractFileSearchFilter { } long toDate = 0; - String endDateValue = panel.getDateToTextField().getText(); + String endDateValue = panel.getToDate(); Calendar endDate = getCalendarDate(endDateValue); if (!endDateValue.isEmpty()) { if (endDate != null) { @@ -199,7 +199,7 @@ class DateSearchFilter extends AbstractFileSearchFilter { @Override public void addActionListener(ActionListener l) { - getComponent().addActionListener(l); + getComponent().addDateChangeListener(); } @Override @@ -210,8 +210,8 @@ class DateSearchFilter extends AbstractFileSearchFilter { public boolean isValid() { DateSearchPanel panel = this.getComponent(); - Calendar startDate = getCalendarDate(panel.getDateFromTextField().getText()); - Calendar endDate = getCalendarDate(panel.getDateToTextField().getText()); + Calendar startDate = getCalendarDate(panel.getFromDate()); + Calendar endDate = getCalendarDate(panel.getToDate()); if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) { setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate()); diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form index 59082745da..1912ad3742 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form @@ -55,28 +55,11 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -98,27 +81,31 @@ + + + + + + + + + + - - - - - + + - - - - - - - - + + + + + @@ -147,20 +134,6 @@ - - - - - - - - - - - - - - @@ -207,20 +180,6 @@ - - - - - - - - - - - - - - @@ -275,25 +234,21 @@ - + - - - + - - - + + + - + - - - + - - - + + + diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java index b9f490041b..c1ef741233 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java @@ -21,22 +21,25 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DateFormat; -import java.text.ParseException; -import java.util.Date; import java.util.List; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFormattedTextField; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; +import com.github.lgooddatepicker.components.DatePicker; +import com.github.lgooddatepicker.optionalusertools.PickerUtilities; +import com.github.lgooddatepicker.components.DatePickerSettings; +import com.github.lgooddatepicker.optionalusertools.DateChangeListener; +import com.github.lgooddatepicker.zinternaltools.DateChangeEvent; /** * Subpanel with controls for file data filtering. */ class DateSearchPanel extends javax.swing.JPanel { + private final DatePickerSettings fromDateSettings = new DatePickerSettings(); + private final DatePickerSettings toDateSettings = new DatePickerSettings(); DateFormat dateFormat; List timeZones; @@ -49,10 +52,11 @@ class DateSearchPanel extends javax.swing.JPanel { } private void customizeComponents() { - - dateFromTextField.setComponentPopupMenu(rightClickMenu); - dateToTextField.setComponentPopupMenu(rightClickMenu); - + fromDateSettings.setFormatForDatesCommonEra(PickerUtilities.createFormatterFromPatternString("MM/dd/yyyy", fromDateSettings.getLocale())); + toDateSettings.setFormatForDatesCommonEra(PickerUtilities.createFormatterFromPatternString("MM/dd/yyyy", toDateSettings.getLocale())); + fromDateSettings.setAllowKeyboardEditing(false); + toDateSettings.setAllowKeyboardEditing(false); + ActionListener actList = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -77,41 +81,7 @@ class DateSearchPanel extends javax.swing.JPanel { copyMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList); - this.dateFromTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); - } - - @Override - public void removeUpdate(DocumentEvent e) { - firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); - } - - @Override - public void changedUpdate(DocumentEvent e) { - firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); - } - }); - - this.dateToTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); - } - - @Override - public void removeUpdate(DocumentEvent e) { - firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); - } - - @Override - public void changedUpdate(DocumentEvent e) { - firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); - } - }); - - + this.setComponentsEnabled(); } @@ -131,12 +101,12 @@ class DateSearchPanel extends javax.swing.JPanel { return dateCheckBox; } - JFormattedTextField getDateFromTextField() { - return dateFromTextField; + String getFromDate() { + return fromDatePicker.getText(); } - JFormattedTextField getDateToTextField() { - return dateToTextField; + String getToDate() { + return toDatePicker.getText(); } JCheckBox getModifiedCheckBox() { @@ -157,11 +127,9 @@ class DateSearchPanel extends javax.swing.JPanel { private void setComponentsEnabled() { boolean enable = this.dateCheckBox.isSelected(); - this.dateFromTextField.setEnabled(enable); - this.dateFromButtonCalendar.setEnabled(enable); + this.fromDatePicker.setEnabled(enable); this.jLabel1.setEnabled(enable); - this.dateToTextField.setEnabled(enable); - this.dateToButtonCalendar.setEnabled(enable); + this.toDatePicker.setEnabled(enable); this.jLabel2.setEnabled(enable); this.jLabel3.setEnabled(enable); this.jLabel4.setEnabled(enable); @@ -186,21 +154,19 @@ class DateSearchPanel extends javax.swing.JPanel { copyMenuItem = new javax.swing.JMenuItem(); pasteMenuItem = new javax.swing.JMenuItem(); selectAllMenuItem = new javax.swing.JMenuItem(); - dateToTextField = new JFormattedTextField(this.dateFormat); jLabel1 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); dateCheckBox = new javax.swing.JCheckBox(); timeZoneComboBox = new JComboBox<>(this.timeZones.toArray(new String[this.timeZones.size()])); timeZoneComboBox.setRenderer(new DateSearchFilter.ComboBoxRenderer()); jLabel3 = new javax.swing.JLabel(); - dateFromTextField = new JFormattedTextField(this.dateFormat); jLabel2 = new javax.swing.JLabel(); modifiedCheckBox = new javax.swing.JCheckBox(); changedCheckBox = new javax.swing.JCheckBox(); accessedCheckBox = new javax.swing.JCheckBox(); createdCheckBox = new javax.swing.JCheckBox(); - dateFromButtonCalendar = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton(); - dateToButtonCalendar = new org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton(); + fromDatePicker = new DatePicker(fromDateSettings); + toDatePicker = new DatePicker(toDateSettings); cutMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.cutMenuItem.text")); // NOI18N rightClickMenu.add(cutMenuItem); @@ -214,14 +180,6 @@ class DateSearchPanel extends javax.swing.JPanel { selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.selectAllMenuItem.text")); // NOI18N rightClickMenu.add(selectAllMenuItem); - dateToTextField.setEditable(false); - dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N - dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() { - public void focusLost(java.awt.event.FocusEvent evt) { - dateToTextFieldFocusLost(evt); - } - }); - jLabel1.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel1.text")); // NOI18N jLabel4.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel4.text")); // NOI18N @@ -236,14 +194,6 @@ class DateSearchPanel extends javax.swing.JPanel { jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N - dateFromTextField.setEditable(false); - dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N - dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() { - public void focusLost(java.awt.event.FocusEvent evt) { - dateFromTextFieldFocusLost(evt); - } - }); - jLabel2.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel2.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel2.text")); // NOI18N @@ -279,44 +229,20 @@ class DateSearchPanel extends javax.swing.JPanel { } }); - dateFromButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromButtonCalendar.text")); // NOI18N - dateFromButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() { - public void propertyChange(java.beans.PropertyChangeEvent evt) { - dateFromPopupChanged(evt); - } - }); + fromDatePicker.setAutoscrolls(true); - dateToButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToButtonCalendar.text")); // NOI18N - dateToButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() { - public void propertyChange(java.beans.PropertyChangeEvent evt) { - dateToPopupChanged(evt); - } - }); + toDatePicker.setAutoscrolls(true); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(layout.createSequentialGroup() - .addComponent(dateCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel3))) - .addContainerGap(26, Short.MAX_VALUE)) + .addContainerGap() + .addComponent(jLabel2) + .addGap(18, 18, 18) + .addComponent(jLabel3) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -333,23 +259,28 @@ class DateSearchPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(changedCheckBox))) .addGap(33, 33, 33)) + .addGroup(layout.createSequentialGroup() + .addComponent(dateCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(fromDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(toDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(dateCheckBox) - .addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(dateCheckBox) .addGap(18, 18, 18)) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(fromDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(toDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) @@ -369,45 +300,6 @@ class DateSearchPanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents - private void dateFromTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateFromTextFieldFocusLost - // set the "from" calendar button to listen to change in the text field - String fromDateString = this.dateFromTextField.getText(); - if (!fromDateString.equals("")) { - try { - Date fromDate = dateFormat.parse(fromDateString); - dateFromButtonCalendar.setTargetDate(fromDate); - } catch (ParseException ex) { - // for now, no need to show the error message to the user her - } - } - }//GEN-LAST:event_dateFromTextFieldFocusLost - - private void dateToTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateToTextFieldFocusLost - // set the "to" calendar button to listen to change in the text field - String toDateString = this.dateToTextField.getText(); - if (!toDateString.equals("")) { - try { - Date toDate = dateFormat.parse(toDateString); - dateToButtonCalendar.setTargetDate(toDate); - } catch (ParseException ex) { - // for now, no need to show the error message to the user here - } - } - }//GEN-LAST:event_dateToTextFieldFocusLost - - private void dateFromPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateFromPopupChanged - if (evt.getNewValue() instanceof Date) { - setFromDate((Date) evt.getNewValue()); - } - }//GEN-LAST:event_dateFromPopupChanged - - private void dateToPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateToPopupChanged - if (evt.getNewValue() instanceof Date) { - setToDate((Date) evt.getNewValue()); - } - - }//GEN-LAST:event_dateToPopupChanged - private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed this.setComponentsEnabled(); firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); @@ -428,36 +320,6 @@ class DateSearchPanel extends javax.swing.JPanel { private void changedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changedCheckBoxActionPerformed firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); }//GEN-LAST:event_changedCheckBoxActionPerformed - - /** - * Validate and set the datetime field on the screen given a datetime - * string. - * - * @param date The date object - */ - private void setFromDate(Date date) { - String dateStringResult = ""; - if (date != null) { - dateStringResult = dateFormat.format(date); - } - - dateFromTextField.setText(dateStringResult); - dateFromButtonCalendar.setTargetDate(date); - } - - /** - * Validate and set the datetime field on the screen given a date. - * - * @param date The date object - */ - private void setToDate(Date date) { - String dateStringResult = ""; - if (date != null) { - dateStringResult = dateFormat.format(date); - } - dateToTextField.setText(dateStringResult); - dateToButtonCalendar.setTargetDate(date); - } boolean isValidSearch() { return this.accessedCheckBox.isSelected() || @@ -472,10 +334,7 @@ class DateSearchPanel extends javax.swing.JPanel { private javax.swing.JCheckBox createdCheckBox; private javax.swing.JMenuItem cutMenuItem; private javax.swing.JCheckBox dateCheckBox; - private org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton dateFromButtonCalendar; - private javax.swing.JFormattedTextField dateFromTextField; - private org.jbundle.thin.base.screen.jcalendarbutton.JCalendarButton dateToButtonCalendar; - private javax.swing.JFormattedTextField dateToTextField; + private com.github.lgooddatepicker.components.DatePicker fromDatePicker; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; @@ -485,10 +344,17 @@ class DateSearchPanel extends javax.swing.JPanel { private javax.swing.JPopupMenu rightClickMenu; private javax.swing.JMenuItem selectAllMenuItem; private javax.swing.JComboBox timeZoneComboBox; + private com.github.lgooddatepicker.components.DatePicker toDatePicker; // End of variables declaration//GEN-END:variables - void addActionListener(ActionListener l) { - dateFromTextField.addActionListener(l); - dateToTextField.addActionListener(l); + void addDateChangeListener() { + DateChangeListener dcl = (DateChangeEvent event) -> { + firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); + }; + + fromDatePicker.addDateChangeListener(dcl); + toDatePicker.addDateChangeListener(dcl); } + } + From e64d4801bb1e219f78cd8fd95e426dd077d41443 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 5 Dec 2017 12:43:05 -0500 Subject: [PATCH 06/38] 3248 make navigate to file work when already in directory --- .../DirectoryTreeTopComponent.java | 3 +- .../directorytree/ViewContextAction.java | 28 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 9738f1f4a6..a5f8f1e62a 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -149,6 +149,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat } } }); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE, Case.Events.DATA_SOURCE_ADDED), this); this.em.addPropertyChangeListener(this); IngestManager.getInstance().addIngestJobEventListener(this); @@ -642,7 +643,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * @param newNodes */ @NbBundle.Messages("DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.") - private void respondSelection(final Node[] oldNodes, final Node[] newNodes) { + void respondSelection(final Node[] oldNodes, final Node[] newNodes) { if (!Case.isCaseOpen()) { return; } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index a1aa1c9a0f..95c5f50c23 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -73,7 +73,7 @@ public class ViewContextAction extends AbstractAction { public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) { super(displayName); this.content = artifactNode.getLookup().lookup(AbstractFile.class); - if(this.content != null) { + if (this.content != null) { AbstractFile file = (AbstractFile) content; if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree()) || (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) { @@ -122,8 +122,7 @@ public class ViewContextAction extends AbstractAction { @Override @Messages({ "ViewContextAction.errorMessage.cannotFindDirectory=Failed to locate directory.", - "ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.", - }) + "ViewContextAction.errorMessage.cannotSelectDirectory=Failed to select directory in tree.",}) public void actionPerformed(ActionEvent event) { EventQueue.invokeLater(() -> { /* @@ -132,7 +131,6 @@ public class ViewContextAction extends AbstractAction { DirectoryTreeTopComponent treeViewTopComponent = DirectoryTreeTopComponent.findInstance(); ExplorerManager treeViewExplorerMgr = treeViewTopComponent.getExplorerManager(); Node parentTreeViewNode = treeViewExplorerMgr.getRootContext().getChildren().findChild(DataSourcesNode.NAME); - /* * Get the parent content for the content to be selected in the * results view. If the parent content is null, then the specified @@ -204,11 +202,21 @@ public class ViewContextAction extends AbstractAction { undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content)); TreeView treeView = treeViewTopComponent.getTree(); treeView.expandNode(parentTreeViewNode); - try { - treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode}); - } catch (PropertyVetoException ex) { - MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory()); - logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS + if (treeViewTopComponent.getSelectedNode().getDisplayName().equals(parentTreeViewNode.getDisplayName())) { + //In the case where our tree view already has the destination directory selected + //due to an optimization in the ExplorerManager.setExploredContextAndSelection method + //the property change we listen for to call DirectoryTreeTopComponent.respondSelection + //will not be sent so we call it manually ourselves after making + //the directory listing the active tab. + treeViewTopComponent.setDirectoryListingActive(); + treeViewTopComponent.respondSelection(treeViewExplorerMgr.getSelectedNodes(), new Node[]{parentTreeViewNode}); + } else { + try { + treeViewExplorerMgr.setExploredContextAndSelection(parentTreeViewNode, new Node[]{parentTreeViewNode}); + } catch (PropertyVetoException ex) { + MessageNotifyUtil.Message.error(Bundle.ViewContextAction_errorMessage_cannotSelectDirectory()); + logger.log(Level.SEVERE, "Failed to select the parent node in the tree view", ex); //NON-NLS + } } }); } @@ -264,5 +272,5 @@ public class ViewContextAction extends AbstractAction { return parent == null ? lineage : parent.accept(this); } } - + } From 97be15f9d3fd6d4082a8452f5fb14197f7db7ce2 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 5 Dec 2017 14:29:59 -0500 Subject: [PATCH 07/38] Finished upgrade code. --- .../datamodel/AbstractSqlEamDb.java | 169 +++++++++--------- .../centralrepository/datamodel/EamDb.java | 16 +- .../datamodel/EamDbUtil.java | 60 +++++-- .../datamodel/PostgresEamDb.java | 36 ++++ .../datamodel/SqliteEamDb.java | 21 ++- .../eventlisteners/Installer.java | 30 +++- .../ingestmodule/IngestModule.java | 1 - .../optionspanel/GlobalSettingsPanel.java | 39 +++- .../CoordinationService.java | 3 +- 9 files changed, 256 insertions(+), 119 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 3fc827f7d5..8eda401abe 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -80,7 +80,7 @@ public abstract class AbstractSqlEamDb implements EamDb { /** * Add a new name/value pair in the db_info table. * - * @param name Key to set + * @param name Key to set * @param value Value to set * * @throws EamDbException @@ -143,7 +143,7 @@ public abstract class AbstractSqlEamDb implements EamDb { /** * Update the value for a name in the name/value db_info table. * - * @param name Name to find + * @param name Name to find * @param value Value to assign to name. * * @throws EamDbException @@ -229,7 +229,7 @@ public abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closeConnection(conn); } - + // get a new version with the updated ID return getCaseByUUID(eamCase.getCaseUUID()); } @@ -258,12 +258,11 @@ public abstract class AbstractSqlEamDb implements EamDb { autopsyCase.getCaseNotes()); return newCase(curCeCase); } - + @Override public CorrelationCase getCase(Case autopsyCase) throws EamDbException { return getCaseByUUID(autopsyCase.getName()); } - /** * Updates an existing Case in the database @@ -437,8 +436,8 @@ public abstract class AbstractSqlEamDb implements EamDb { /** * Retrieves Data Source details based on data source device ID * - * @param correlationCase the current CorrelationCase used for ensuring - * uniqueness of DataSource + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource * @param dataSourceDeviceId the data source device ID number * * @return The data source @@ -611,7 +610,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath * - * @param aType EamArtifact.Type to search for + * @param aType EamArtifact.Type to search for * @param filePath File path to search for * * @return List of 0 or more EamArtifactInstances @@ -667,7 +666,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @param value The correlation value * * @return Number of artifact instances having ArtifactType and - * ArtifactValue. + * ArtifactValue. */ @Override public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException { @@ -782,11 +781,11 @@ public abstract class AbstractSqlEamDb implements EamDb { * associated with the caseDisplayName and dataSource of the given * eamArtifact instance. * - * @param caseUUID Case ID to search for + * @param caseUUID Case ID to search for * @param dataSourceID Data source ID to search for * * @return Number of artifact instances having caseDisplayName and - * dataSource + * dataSource */ @Override public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException { @@ -1073,7 +1072,7 @@ public abstract class AbstractSqlEamDb implements EamDb { if (null == correlationCaseWithId) { correlationCaseWithId = newCase(eamInstance.getCorrelationCase()); } - + if (null == getDataSource(correlationCaseWithId, eamInstance.getCorrelationDataSource().getDeviceID())) { newDataSource(eamInstance.getCorrelationDataSource()); } @@ -1190,7 +1189,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @param value Value to search for * * @return List of cases containing this artifact with instances marked as - * bad + * bad * * @throws EamDbException */ @@ -1233,24 +1232,26 @@ public abstract class AbstractSqlEamDb implements EamDb { return caseNames.stream().collect(Collectors.toList()); } - + /** * Remove a reference set and all entries contained in it. + * * @param referenceSetID - * @throws EamDbException + * @throws EamDbException */ @Override - public void deleteReferenceSet(int referenceSetID) throws EamDbException{ + public void deleteReferenceSet(int referenceSetID) throws EamDbException { deleteReferenceSetEntries(referenceSetID); deleteReferenceSetEntry(referenceSetID); - } - + } + /** * Remove the entry for this set from the reference_sets table + * * @param referenceSetID - * @throws EamDbException + * @throws EamDbException */ - private void deleteReferenceSetEntry(int referenceSetID) throws EamDbException{ + private void deleteReferenceSetEntry(int referenceSetID) throws EamDbException { Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -1265,21 +1266,22 @@ public abstract class AbstractSqlEamDb implements EamDb { } finally { EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closeConnection(conn); - } + } } - + /** * Remove all entries for this reference set from the reference tables * (Currently only removes entries from the reference_file table) + * * @param referenceSetID - * @throws EamDbException + * @throws EamDbException */ - private void deleteReferenceSetEntries(int referenceSetID) throws EamDbException{ + private void deleteReferenceSetEntries(int referenceSetID) throws EamDbException { Connection conn = connect(); PreparedStatement preparedStatement = null; String sql = "DELETE FROM %s WHERE reference_set_id=?"; - + // When other reference types are added, this will need to loop over all the tables String fileTableName = EamDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID)); @@ -1292,12 +1294,14 @@ public abstract class AbstractSqlEamDb implements EamDb { } finally { EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closeConnection(conn); - } + } } - + /** - * Check whether a reference set with the given parameters exists in the central repository. - * Used to check whether reference sets saved in the settings are still present. + * Check whether a reference set with the given parameters exists in the + * central repository. Used to check whether reference sets saved in the + * settings are still present. + * * @param referenceSetID * @param setName * @param version @@ -1305,37 +1309,39 @@ public abstract class AbstractSqlEamDb implements EamDb { * @throws EamDbException */ @Override - public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException{ + public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException { EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID); - if(refSet == null){ + if (refSet == null) { return false; } - - return(refSet.getSetName().equals(setName) && refSet.getVersion().equals(version)); + + return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version)); } - + /** - * Check if the given file hash is in this reference set. - * Only searches the reference_files table. + * Check if the given file hash is in this reference set. Only searches the + * reference_files table. + * * @param hash * @param referenceSetID * @return true if the hash is found in the reference set - * @throws EamDbException + * @throws EamDbException */ @Override - public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException{ + public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException { return isValueInReferenceSet(hash, referenceSetID, CorrelationAttribute.FILES_TYPE_ID); - } - + } + /** * Check if the given value is in a specific reference set + * * @param value * @param referenceSetID - * @param correlationTypeID + * @param correlationTypeID * @return true if the value is found in the reference set */ @Override - public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException{ + public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException { Connection conn = connect(); @@ -1343,7 +1349,7 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; ResultSet resultSet = null; String sql = "SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?"; - + String fileTableName = EamDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID)); try { @@ -1509,15 +1515,16 @@ public abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } - + /** * Get the organization associated with the given reference set. + * * @param referenceSetID ID of the reference set * @return The organization object - * @throws EamDbException + * @throws EamDbException */ @Override - public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException{ + public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException { EamGlobalSet globalSet = getReferenceSetByID(referenceSetID); return (getOrganizationByID(globalSet.getOrgID())); @@ -1527,7 +1534,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * Update an existing organization. * * @param updatedOrganization the values the Organization with the same ID - * will be updated to in the database. + * will be updated to in the database. * * @throws EamDbException */ @@ -1553,8 +1560,8 @@ public abstract class AbstractSqlEamDb implements EamDb { } @Messages({"AbstractSqlEamDb.deleteOrganization.inUseException.message=Can not delete organization " - + "which is currently in use by a case or reference set in the central repository.", - "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."}) + + "which is currently in use by a case or reference set in the central repository.", + "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."}) @Override public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException { Connection conn = connect(); @@ -1667,7 +1674,7 @@ public abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } - + /** * Get all reference sets * @@ -1676,7 +1683,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @throws EamDbException */ @Override - public List getAllReferenceSets() throws EamDbException{ + public List getAllReferenceSets() throws EamDbException { List results = new ArrayList<>(); Connection conn = connect(); @@ -1705,8 +1712,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * Add a new reference instance * * @param eamGlobalFileInstance The reference instance to add - * @param correlationType Correlation Type that this Reference - * Instance is + * @param correlationType Correlation Type that this Reference Instance is * * @throws EamDbException */ @@ -1732,17 +1738,19 @@ public abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } - + /** - * Check whether a reference set with the given name/version is in the central repo. - * Used to check for name collisions when creating reference sets. + * Check whether a reference set with the given name/version is in the + * central repo. Used to check for name collisions when creating reference + * sets. + * * @param referenceSetName * @param version * @return true if a matching set is found - * @throws EamDbException + * @throws EamDbException */ @Override - public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException{ + public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException { Connection conn = connect(); PreparedStatement preparedStatement1 = null; @@ -1757,13 +1765,13 @@ public abstract class AbstractSqlEamDb implements EamDb { return (resultSet.next()); } catch (SQLException ex) { - throw new EamDbException("Error testing whether reference set exists (name: " + referenceSetName + throw new EamDbException("Error testing whether reference set exists (name: " + referenceSetName + " version: " + version, ex); // NON-NLS } finally { EamDbUtil.closePreparedStatement(preparedStatement1); EamDbUtil.closeResultSet(resultSet); EamDbUtil.closeConnection(conn); - } + } } /** @@ -1811,7 +1819,7 @@ public abstract class AbstractSqlEamDb implements EamDb { /** * Get all reference entries having a given correlation type and value * - * @param aType Type to use for matching + * @param aType Type to use for matching * @param aValue Value to use for matching * * @return List of all global file instances with a type and value @@ -1941,7 +1949,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * artifacts. * * @return List of enabled EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @@ -1976,7 +1984,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * correlate artifacts. * * @return List of supported EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @@ -2077,7 +2085,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * Convert a ResultSet to a EamCase object * * @param resultSet A resultSet with a set of values to create a EamCase - * object. + * object. * * @return fully populated EamCase object, or null * @@ -2147,7 +2155,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * Convert a ResultSet to a EamArtifactInstance object * * @param resultSet A resultSet with a set of values to create a - * EamArtifactInstance object. + * EamArtifactInstance object. * * @return fully populated EamArtifactInstance, or null * @@ -2220,18 +2228,18 @@ public abstract class AbstractSqlEamDb implements EamDb { } /** - * Update the schema of the database (if needed) - * @throws EamDbException + * Upgrade the schema of the database (if needed) + * + * @throws EamDbException */ @Override - public void updateSchema() throws EamDbException { + public void upgradeSchema() throws EamDbException, SQLException { ResultSet resultSet = null; Statement statement; Connection conn = null; try { - throw new EamDbException("Test failure"); - /* + conn = connect(); conn.setAutoCommit(false); statement = conn.createStatement(); @@ -2244,7 +2252,7 @@ public abstract class AbstractSqlEamDb implements EamDb { try { minorVersion = Integer.parseInt(minorVersionStr); } catch (NumberFormatException ex) { - throw new EamDbException("Bad value for schema minor version - database is corrupt"); + throw new EamDbException("Bad value for schema minor version (" + minorVersionStr + ") - database is corrupt"); } } @@ -2254,13 +2262,12 @@ public abstract class AbstractSqlEamDb implements EamDb { try { majorVersion = Integer.parseInt(majorVersionStr); } catch (NumberFormatException ex) { - throw new EamDbException("Bad value for schema version - database is corrupt"); + throw new EamDbException("Bad value for schema version (" + majorVersionStr + ") - database is corrupt"); } } - System.out.println("Current schema version: " + majorVersion + "." + minorVersion); CaseDbSchemaVersionNumber dbSchemaVersion = new CaseDbSchemaVersionNumber(majorVersion, minorVersion); - if(dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)){ + if (dbSchemaVersion.equals(CURRENT_DB_SCHEMA_VERSION)) { LOGGER.log(Level.INFO, "Central Repository is up to date"); return; } @@ -2270,7 +2277,7 @@ public abstract class AbstractSqlEamDb implements EamDb { statement.execute("ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;"); //NON-NLS statement.execute("ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;"); //NON-NLS statement.execute("ALTER TABLE reference_sets ADD COLUMN type INTEGER;"); //NON-NLS - + // There's an outide chance that the user has already made an organization with the default name, // and the default org being missing will not impact any database operations, so continue on // regardless of whether this succeeds. @@ -2278,25 +2285,23 @@ public abstract class AbstractSqlEamDb implements EamDb { } if (!updateSchemaVersion(conn)) { - // Log error - return; + throw new EamDbException("Error updating schema version"); } conn.commit(); LOGGER.log(Level.INFO, "Central Repository upgraded to version " + CURRENT_DB_SCHEMA_VERSION); - } catch (SQLException | EamDbException ex) {*/ - } catch (EamDbException ex) { + } catch (SQLException | EamDbException ex) { try { - if(conn != null){ + if (conn != null) { conn.rollback(); } } catch (SQLException ex2) { - // We're alredy in an error state + LOGGER.log(Level.SEVERE, "Database rollback failed", ex2); } - ex.printStackTrace(); throw ex; } finally { EamDbUtil.closeResultSet(resultSet); + EamDbUtil.closeConnection(conn); } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 97e2750e95..f8ab7bfc60 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -18,10 +18,12 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; +import java.sql.SQLException; import java.util.List; import java.util.Set; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; /** @@ -598,8 +600,18 @@ public interface EamDb { public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException; /** - * Update the schema of the database (if needed) + * Upgrade the schema of the database (if needed) * @throws EamDbException */ - public void updateSchema() throws EamDbException; + public void upgradeSchema() throws EamDbException, SQLException; + + /** + * Gets an exclusive lock (if applicable). + * Will return the lock if successful, null if unsuccessful because locking + * isn't supported, and throw an exception if we should have been able to get the + * lock but failed (meaning the database is in use). + * @return the lock, or null if locking is not supported + * @throws EamDbException if the coordination service is running but we fail to get the lock + */ + public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java index 66bc6d4221..7a06401967 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java @@ -26,9 +26,10 @@ import java.sql.Statement; import java.util.List; import java.util.logging.Level; import static org.sleuthkit.autopsy.centralrepository.datamodel.EamDb.CURRENT_DB_SCHEMA_VERSION; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; /** * @@ -210,41 +211,66 @@ public class EamDbUtil { } /** + * Upgrade the current central reposity to the newest version. If the upgrade + * fails, the central repository will be disabled and the current settings + * will be cleared. * + * @return true if the upgrade succeeds, false otherwise. */ - public static void updateDatabase() { + public static boolean upgradeDatabase() { if (!EamDb.isEnabled()) { - return; + return true; } - + + CoordinationService.Lock lock = null; try { EamDb db = EamDb.getInstance(); - if (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.POSTGRESQL) { - // Try to get a lock here - } - - db.updateSchema(); + // This may return null if locking isn't supported, which is fine. It will + // throw an exception if locking is supported but we can't get the lock + // (meaning the database is in use by another user) + lock = db.getExclusiveMultiUserDbLock(); - } catch (EamDbException ex) { - MessageNotifyUtil.Message.error(ex.getLocalizedMessage()); - ex.printStackTrace(); + db.upgradeSchema(); + + } catch (EamDbException | SQLException ex) { + LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + + // Disable the central repo and clear the current settings. + try{ + if (null != EamDb.getInstance()) { + EamDb.getInstance().shutdownConnections(); + } + } catch (EamDbException ex2){ + LOGGER.log(Level.SEVERE, "Error shutting down central repo connection pool", ex); + } + setUseCentralRepo(false); + EamDbPlatformEnum.setSelectedPlatform(EamDbPlatformEnum.DISABLED.name()); + EamDbPlatformEnum.saveSelectedPlatform(); + + return false; } finally { - if (EamDbPlatformEnum.getSelectedPlatform() == EamDbPlatformEnum.POSTGRESQL) { - // Release lock here + if(lock != null){ + try{ + lock.release(); + } catch (CoordinationServiceException ex){ + LOGGER.log(Level.SEVERE, "Error releasing database lock", ex); + } } } + return true; } - + /** * Get the default organization name + * * @return the default org name */ static String getDefaultOrgName() { return DEFAULT_ORG_NAME; } - - /** + + /** * Check whether the given org is the default organization. * * @param org diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java index c139554c9c..46d579ad87 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDb.java @@ -21,8 +21,13 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.apache.commons.dbcp2.BasicDataSource; +import org.sleuthkit.autopsy.casemodule.CaseActionCancelledException; +import org.sleuthkit.autopsy.casemodule.CaseActionException; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService; +import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; /** @@ -185,5 +190,36 @@ public class PostgresEamDb extends AbstractSqlEamDb { protected String getConflictClause() { return CONFLICT_CLAUSE; } + + /** + * Gets an exclusive lock (if applicable). + * Will return the lock if successful, null if unsuccessful because locking + * isn't supported, and throw an exception if we should have been able to get the + * lock but failed (meaning the database is in use). + * @return the lock, or null if locking is not supported + * @throws EamDbException if the coordination service is running but we fail to get the lock + */ + @Override + public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{ + try { + // First check if multi user mode is enabled - if not there's no point trying to get a lock + if( ! UserPreferences.getIsMultiUserModeEnabled()){ + return null; + } + + String databaseNodeName = dbSettings.getHost() + "_" + dbSettings.getDbName(); + CoordinationService.Lock lock = CoordinationService.getInstance().tryGetExclusiveLock(CoordinationService.CategoryNode.CENTRAL_REPO, databaseNodeName, 5, TimeUnit.MINUTES); + + if(lock != null){ + return lock; + } + throw new EamDbException("Error acquiring database lock"); + } catch (InterruptedException ex){ + throw new EamDbException("Error acquiring database lock"); + } catch (CoordinationService.CoordinationServiceException ex) { + // This likely just means the coordination service isn't running, which is ok + return null; + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index f6853de545..55e60dd380 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -30,6 +30,7 @@ import org.apache.commons.dbcp2.BasicDataSource; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService; /** * Sqlite implementation of the Central Repository database. @@ -987,19 +988,33 @@ public class SqliteEamDb extends AbstractSqlEamDb { } /** - * Update the schema of the database (if needed) + * Upgrade the schema of the database (if needed) * @throws EamDbException */ @Override - public void updateSchema() throws EamDbException { + public void upgradeSchema() throws EamDbException, SQLException { try{ acquireExclusiveLock(); - super.updateSchema(); + super.upgradeSchema(); } finally { releaseExclusiveLock(); } } + /** + * Gets an exclusive lock (if applicable). + * Will return the lock if successful, null if unsuccessful because locking + * isn't supported, and throw an exception if we should have been able to get the + * lock but failed (meaning the database is in use). + * @return the lock, or null if locking is not supported + * @throws EamDbException if the coordination service is running but we fail to get the lock + */ + @Override + public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{ + // Multiple users are not supported for SQLite + return null; + } + /** * Acquire the lock that provides exclusive access to the case database. * Call this method in a try block with a call to diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index bf384fbb89..680738b597 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -18,10 +18,14 @@ */ package org.sleuthkit.autopsy.centralrepository.eventlisteners; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; import org.openide.modules.ModuleInstall; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; +import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; /** @@ -42,20 +46,32 @@ public class Installer extends ModuleInstall { } return instance; } - + private Installer() { super(); } - - + + @NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository upgrade failed", + "Installer.centralRepoUpgradeFailed.message=Failed to upgrade central repository. It has been disabled." + }) @Override public void restored() { Case.addPropertyChangeListener(pcl); ieListener.installListeners(); - // TODO: create a thread pool to process Runners. - - EamDbUtil.updateDatabase(); + // Perform the database upgrade and inform the user if it fails + if (!EamDbUtil.upgradeDatabase()) { + if (RuntimeProperties.runningWithGUI()) { + WindowManager.getDefault().invokeWhenUIReady(() -> { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "Installer.centralRepoUpgradeFailed.message"), + NbBundle.getMessage(this.getClass(), + "Installer.centralRepoUpgradeFailed.title"), + JOptionPane.ERROR_MESSAGE); + }); + } + } } @Override diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 9e1e36cb8a..5e933453dc 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -47,7 +47,6 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 905b5060fe..fde18b8573 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -18,11 +18,14 @@ */ package org.sleuthkit.autopsy.centralrepository.optionspanel; +import java.awt.Cursor; import org.sleuthkit.autopsy.coreutils.Logger; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.events.AutopsyEvent; @@ -78,9 +81,31 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestStateUpdated(); } + @Messages({"GlobalSettingsPanel.updateFailed.title=Update failed", + "GlobalSettingsPanel.updateFailed.message=Failed to update database. Central repository has been disabled." + }) private void updateDatabase(){ - // Add UI stuff later - EamDbUtil.updateDatabase(); + + if(EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED)){ + return; + } + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + try { + boolean result = EamDbUtil.upgradeDatabase(); + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + if(! result){ + //progressIndicator.finish(); + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "GlobalSettingsPanel.updateFailed.message"), + NbBundle.getMessage(this.getClass(), + "GlobalSettingsPanel.updateFailed.title"), + JOptionPane.WARNING_MESSAGE); + } + } finally { + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } } /** @@ -320,9 +345,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed store(); EamDbSettingsDialog dialog = new EamDbSettingsDialog(); + updateDatabase(); load(); // reload db settings content and update buttons if (dialog.wasConfigurationChanged()) { - updateDatabase(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } }//GEN-LAST:event_bnDbConfigureActionPerformed @@ -330,10 +355,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed //if saved setting is disabled checkbox should be disabled already store(); - enableDatabaseConfigureButton(cbUseCentralRepo.isSelected()); - enableButtonSubComponents(cbUseCentralRepo.isSelected() && !EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED)); - this.ingestStateUpdated(); updateDatabase(); + load(); + //cbUseCentralRepo.setSelected(EamDbUtil.useCentralRepo()); + //enableDatabaseConfigureButton(cbUseCentralRepo.isSelected()); + //enableButtonSubComponents(cbUseCentralRepo.isSelected() && !EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED)); + this.ingestStateUpdated(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_cbUseCentralRepoActionPerformed diff --git a/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java b/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java index 2664a32787..5a34a80d58 100755 --- a/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java +++ b/Core/src/org/sleuthkit/autopsy/coordinationservice/CoordinationService.java @@ -451,7 +451,8 @@ public final class CoordinationService { CASES("cases"), MANIFESTS("manifests"), - CONFIG("config"); + CONFIG("config"), + CENTRAL_REPO("centralRepository"); private final String displayName; From 3654c319a6a5dc5257b8f8fe78fac761f82c948d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Tue, 5 Dec 2017 14:34:07 -0500 Subject: [PATCH 08/38] 3219: update Experimental LGoodDatePicker version to 10.3.1 --- Core/ivy.xml | 1 - CoreLibs/ivy.xml | 2 +- Experimental/ivy.xml | 2 +- Experimental/nbproject/project.properties | 6 +- Experimental/nbproject/project.xml | 16 +-- .../autoingest/AutoIngestMetricsDialog.form | 27 +++-- .../autoingest/AutoIngestMetricsDialog.java | 18 +-- .../autoingest/FileExporterSettingsPanel.form | 104 +++++++++--------- .../autoingest/FileExporterSettingsPanel.java | 96 ++++++++-------- 9 files changed, 132 insertions(+), 140 deletions(-) diff --git a/Core/ivy.xml b/Core/ivy.xml index c2b6142ebc..eea67feb19 100755 --- a/Core/ivy.xml +++ b/Core/ivy.xml @@ -22,6 +22,5 @@ - diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index bfd9112f9e..38ef973d89 100755 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -13,7 +13,7 @@ - + diff --git a/Experimental/ivy.xml b/Experimental/ivy.xml index e50fab6472..93d6dafa8d 100755 --- a/Experimental/ivy.xml +++ b/Experimental/ivy.xml @@ -5,7 +5,7 @@ - + diff --git a/Experimental/nbproject/project.properties b/Experimental/nbproject/project.properties index d47542bdb5..1bd0e2fc90 100755 --- a/Experimental/nbproject/project.properties +++ b/Experimental/nbproject/project.properties @@ -1,10 +1,10 @@ file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar file.reference.jackson-core-2.7.0.jar=release/modules/ext/jackson-core-2.7.0.jar -file.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1.jar +file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar file.reference.postgresql-9.4-1201-jdbc41.jar=release/modules/ext/postgresql-9.4-1201-jdbc41.jar file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar javac.source=1.8 javac.compilerargs=-Xlint -Xlint:-serial -javadoc.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-javadoc.jar -source.reference.LGoodDatePicker-4.3.1.jar=release/modules/ext/LGoodDatePicker-4.3.1-sources.jar +javadoc.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar +source.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-sources.jar diff --git a/Experimental/nbproject/project.xml b/Experimental/nbproject/project.xml index 78e13b64ed..8293608102 100755 --- a/Experimental/nbproject/project.xml +++ b/Experimental/nbproject/project.xml @@ -145,18 +145,18 @@ org.sleuthkit.autopsy.experimental.autoingest org.sleuthkit.autopsy.experimental.configuration - - ext/mchange-commons-java-0.2.9.jar - release/modules/ext/mchange-commons-java-0.2.9.jar - - - ext/LGoodDatePicker-4.3.1.jar - release/modules/ext/LGoodDatePicker-4.3.1.jar - ext/tika-core-1.14.jar release/modules/ext/tika-core-1.14.jar + + ext/LGoodDatePicker-10.3.1.jar + release/modules/ext/LGoodDatePicker-10.3.1.jar + + + ext/mchange-commons-java-0.2.9.jar + release/modules/ext/mchange-commons-java-0.2.9.jar + ext/jackson-core-2.7.0.jar release/modules/ext/jackson-core-2.7.0.jar diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form index cbe7b53c2f..1ec767ba21 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form @@ -31,9 +31,9 @@ - + - + @@ -51,8 +51,10 @@ - - + + + + @@ -103,16 +105,6 @@ - - - - - - - - - - @@ -120,5 +112,12 @@ + + + + + + + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java index af0679be5f..990d04e244 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.experimental.autoingest; -import com.github.lgooddatepicker.datepicker.DatePicker; import java.awt.Container; import java.awt.Cursor; import java.awt.Window; @@ -139,8 +138,8 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { jScrollPane1 = new javax.swing.JScrollPane(); reportTextArea = new javax.swing.JTextArea(); metricsButton = new javax.swing.JButton(); - datePicker = new DatePicker(); startingDataLabel = new javax.swing.JLabel(); + datePicker = new com.github.lgooddatepicker.components.DatePicker(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setAlwaysOnTop(true); @@ -166,10 +165,10 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { } }); - datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(startingDataLabel, org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.startingDataLabel.text")); // NOI18N + datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -180,9 +179,9 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { .addComponent(jScrollPane1) .addGroup(layout.createSequentialGroup() .addComponent(startingDataLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(metricsButton)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) @@ -195,8 +194,9 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(metricsButton) - .addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(startingDataLabel)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(startingDataLabel) + .addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -220,7 +220,7 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton closeButton; - private com.github.lgooddatepicker.datepicker.DatePicker datePicker; + private com.github.lgooddatepicker.components.DatePicker datePicker; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JButton metricsButton; private javax.swing.JTextArea reportTextArea; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.form index 7ec8ed3539..4bd74cd7ed 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.form @@ -71,10 +71,10 @@ - + @@ -136,12 +136,12 @@ - - - + + + @@ -161,7 +161,7 @@ - + @@ -173,13 +173,6 @@ - - - - - - - @@ -202,6 +195,13 @@ + + + + + + + @@ -236,7 +236,7 @@ - + @@ -259,20 +259,16 @@ - - - - - - - - - - - - - - + + + + + + + + + + @@ -380,12 +376,12 @@ - - - + + + @@ -396,12 +392,12 @@ - - - + + + @@ -409,15 +405,15 @@ - - - + + + @@ -431,10 +427,10 @@ + - @@ -477,10 +473,10 @@ - + @@ -488,13 +484,13 @@ - + @@ -503,8 +499,8 @@ - + @@ -533,14 +529,6 @@ - - - - - - - - @@ -554,8 +542,8 @@ - + @@ -593,6 +581,14 @@ + + + + + + + + @@ -610,12 +606,12 @@ - - - + + + @@ -630,9 +626,9 @@ - + @@ -700,10 +696,10 @@ + - diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java index 64acf1163a..1352f22099 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java @@ -18,9 +18,9 @@ */ package org.sleuthkit.autopsy.experimental.autoingest; -import com.github.lgooddatepicker.datetimepicker.DateTimePicker; +import com.github.lgooddatepicker.components.DateTimePicker; import com.github.lgooddatepicker.optionalusertools.PickerUtilities; -import com.github.lgooddatepicker.timepicker.TimePickerSettings; +import com.github.lgooddatepicker.components.TimePickerSettings; import java.awt.Color; import java.awt.Component; import java.awt.event.FocusEvent; @@ -632,7 +632,7 @@ public final class FileExporterSettingsPanel extends JPanel { comboBoxValueType.setEnabled(null == attributeTypeMap.get(artifactConditionToPopulateWith.getAttributeTypeName())); if (valueType == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { Instant instant = Instant.ofEpochMilli(artifactConditionToPopulateWith.getDateTimeValue().toDate().getTime()); - dateTimePicker.setDateTime(LocalDateTime.ofInstant(instant, ZoneId.systemDefault())); + dateTimePicker.setDateTimeStrict(LocalDateTime.ofInstant(instant, ZoneId.systemDefault())); } else { tbAttributeValue.setText(artifactConditionToPopulateWith.getStringRepresentationOfValue()); } @@ -650,30 +650,30 @@ public final class FileExporterSettingsPanel extends JPanel { mainPanel = new javax.swing.JPanel(); tbRootDirectory = new javax.swing.JTextField(); pnEditRule = new javax.swing.JPanel(); - comboBoxMimeValue = new javax.swing.JComboBox(); + comboBoxMimeValue = new javax.swing.JComboBox<>(); cbMimeType = new javax.swing.JCheckBox(); spFileSizeValue = new javax.swing.JSpinner(); - comboBoxFileSizeUnits = new javax.swing.JComboBox(); + comboBoxFileSizeUnits = new javax.swing.JComboBox<>(); cbFileSize = new javax.swing.JCheckBox(); - comboBoxFileSizeComparison = new javax.swing.JComboBox(); - comboBoxMimeTypeComparison = new javax.swing.JComboBox(); + comboBoxFileSizeComparison = new javax.swing.JComboBox<>(); + comboBoxMimeTypeComparison = new javax.swing.JComboBox<>(); tbRuleName = new javax.swing.JTextField(); bnSaveRule = new javax.swing.JButton(); - comboBoxArtifactName = new javax.swing.JComboBox(); - comboBoxAttributeName = new javax.swing.JComboBox(); - comboBoxAttributeComparison = new javax.swing.JComboBox(); + comboBoxArtifactName = new javax.swing.JComboBox<>(); + comboBoxAttributeName = new javax.swing.JComboBox<>(); + comboBoxAttributeComparison = new javax.swing.JComboBox<>(); tbAttributeValue = new javax.swing.JTextField(); bnAddAttribute = new javax.swing.JButton(); - comboBoxValueType = new javax.swing.JComboBox(); + comboBoxValueType = new javax.swing.JComboBox<>(); cbAttributeType = new javax.swing.JCheckBox(); - dateTimePicker = new DateTimePicker(null, timeSettings); lbArtifact = new javax.swing.JLabel(); lbAttribute = new javax.swing.JLabel(); bnDeleteAttribute = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); - lsAttributeList = new javax.swing.JList(); + lsAttributeList = new javax.swing.JList<>(); lbRuleName = new javax.swing.JLabel(); lbSaveRuleHelper = new javax.swing.JLabel(); + dateTimePicker = new DateTimePicker(null, timeSettings); bnBrowseReportDirectory = new javax.swing.JButton(); tbReportDirectory = new javax.swing.JTextField(); ruleListScrollPane = new javax.swing.JScrollPane(); @@ -690,11 +690,11 @@ public final class FileExporterSettingsPanel extends JPanel { setBorder(javax.swing.BorderFactory.createEtchedBorder()); setName(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.Title")); // NOI18N - mainPanel.setAutoscrolls(true); mainPanel.setPreferredSize(new java.awt.Dimension(657, 425)); + mainPanel.setAutoscrolls(true); - tbRootDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.RuleOutputTooltip_1")); // NOI18N tbRootDirectory.setMaximumSize(new java.awt.Dimension(2000, 2000)); + tbRootDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.RuleOutputTooltip_1")); // NOI18N pnEditRule.setBorder(javax.swing.BorderFactory.createEtchedBorder()); pnEditRule.setAutoscrolls(true); @@ -716,7 +716,7 @@ public final class FileExporterSettingsPanel extends JPanel { } }); - spFileSizeValue.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(1024), Integer.valueOf(0), null, Integer.valueOf(1))); + spFileSizeValue.setModel(new javax.swing.SpinnerNumberModel(1024, 0, null, 1)); spFileSizeValue.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeValueToolTip_1")); // NOI18N comboBoxFileSizeUnits.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeUnitToolTip_1")); // NOI18N @@ -729,15 +729,15 @@ public final class FileExporterSettingsPanel extends JPanel { } }); - comboBoxFileSizeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeComparisonTooltip_1")); // NOI18N comboBoxFileSizeComparison.setMinimumSize(new java.awt.Dimension(32, 20)); + comboBoxFileSizeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.FileSizeComparisonTooltip_1")); // NOI18N - comboBoxMimeTypeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.MimeTypeComparisonTooltip_1")); // NOI18N comboBoxMimeTypeComparison.setMinimumSize(new java.awt.Dimension(32, 20)); + comboBoxMimeTypeComparison.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.MimeTypeComparisonTooltip_1")); // NOI18N - tbRuleName.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.CurrentlySelectedRuleNameTooltip_1")); // NOI18N tbRuleName.setMaximumSize(new java.awt.Dimension(10, 1000)); tbRuleName.setPreferredSize(new java.awt.Dimension(733, 20)); + tbRuleName.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.CurrentlySelectedRuleNameTooltip_1")); // NOI18N tbRuleName.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { tbRuleNameKeyTyped(evt); @@ -746,8 +746,8 @@ public final class FileExporterSettingsPanel extends JPanel { bnSaveRule.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/save-icon.png"))); // NOI18N bnSaveRule.setText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.SaveText")); // NOI18N - bnSaveRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.SaveTooltip_1")); // NOI18N bnSaveRule.setEnabled(false); + bnSaveRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.SaveTooltip_1")); // NOI18N bnSaveRule.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnSaveRuleActionPerformed(evt); @@ -772,17 +772,17 @@ public final class FileExporterSettingsPanel extends JPanel { } }); - comboBoxAttributeComparison.setToolTipText("Select the conditional operator"); comboBoxAttributeComparison.setMinimumSize(new java.awt.Dimension(32, 23)); + comboBoxAttributeComparison.setToolTipText("Select the conditional operator"); - tbAttributeValue.setToolTipText("Type a value here"); tbAttributeValue.setMinimumSize(new java.awt.Dimension(6, 23)); tbAttributeValue.setPreferredSize(new java.awt.Dimension(6, 23)); + tbAttributeValue.setToolTipText("Type a value here"); bnAddAttribute.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/left-arrow-16-icon.png"))); // NOI18N bnAddAttribute.setText("Add Attribute"); - bnAddAttribute.setToolTipText("Click to add an attribute to the current rule"); bnAddAttribute.setEnabled(false); + bnAddAttribute.setToolTipText("Click to add an attribute to the current rule"); bnAddAttribute.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnAddAttributeActionPerformed(evt); @@ -804,15 +804,13 @@ public final class FileExporterSettingsPanel extends JPanel { } }); - dateTimePicker.setToolTipText("Choose a date and time"); - lbArtifact.setText("Artifact"); lbAttribute.setText("Attribute"); bnDeleteAttribute.setText("Delete Attribute"); - bnDeleteAttribute.setToolTipText("Click to remove the selected attribute"); bnDeleteAttribute.setEnabled(false); + bnDeleteAttribute.setToolTipText("Click to remove the selected attribute"); bnDeleteAttribute.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnDeleteAttributeActionPerformed(evt); @@ -829,6 +827,8 @@ public final class FileExporterSettingsPanel extends JPanel { lbSaveRuleHelper.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); lbSaveRuleHelper.setText("To save, a rule must have a name and at least one condition."); + dateTimePicker.setToolTipText("Choose a date and time"); + javax.swing.GroupLayout pnEditRuleLayout = new javax.swing.GroupLayout(pnEditRule); pnEditRule.setLayout(pnEditRuleLayout); pnEditRuleLayout.setHorizontalGroup( @@ -845,12 +845,6 @@ public final class FileExporterSettingsPanel extends JPanel { .addComponent(lbSaveRuleHelper, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(bnSaveRule, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(pnEditRuleLayout.createSequentialGroup() - .addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 306, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(tbAttributeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)) .addGroup(pnEditRuleLayout.createSequentialGroup() .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnEditRuleLayout.createSequentialGroup() @@ -867,7 +861,13 @@ public final class FileExporterSettingsPanel extends JPanel { .addGroup(pnEditRuleLayout.createSequentialGroup() .addComponent(bnAddAttribute, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnDeleteAttribute))) + .addComponent(bnDeleteAttribute)) + .addGroup(pnEditRuleLayout.createSequentialGroup() + .addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, 306, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tbAttributeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE))) .addGap(0, 0, Short.MAX_VALUE)))) .addGroup(pnEditRuleLayout.createSequentialGroup() .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -910,17 +910,15 @@ public final class FileExporterSettingsPanel extends JPanel { .addGap(78, 78, 78) .addComponent(lbAttribute) .addGap(8, 8, 8) - .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(pnEditRuleLayout.createSequentialGroup() - .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(comboBoxAttributeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(comboBoxArtifactName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(comboBoxValueType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tbAttributeValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(comboBoxAttributeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(comboBoxArtifactName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(comboBoxValueType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(tbAttributeValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(comboBoxAttributeComparison, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(dateTimePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnEditRuleLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bnAddAttribute) @@ -953,14 +951,14 @@ public final class FileExporterSettingsPanel extends JPanel { } }); - tbReportDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.ReportOutputFolderTooltip_1")); // NOI18N tbReportDirectory.setMaximumSize(new java.awt.Dimension(2000, 2000)); + tbReportDirectory.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.ReportOutputFolderTooltip_1")); // NOI18N javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root"); trRuleList.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1)); - trRuleList.setToolTipText("This tree shows the rules to collect files for automatic file export"); trRuleList.setName("trRuleList"); // NOI18N trRuleList.setShowsRootHandles(true); + trRuleList.setToolTipText("This tree shows the rules to collect files for automatic file export"); ruleListScrollPane.setViewportView(trRuleList); trRuleList.getAccessibleContext().setAccessibleParent(ruleListScrollPane); @@ -1039,8 +1037,8 @@ public final class FileExporterSettingsPanel extends JPanel { bnDeleteRule.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/minus-icon.png"))); // NOI18N bnDeleteRule.setText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.DeleteText")); // NOI18N - bnDeleteRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.DeleteTooltip_1")); // NOI18N bnDeleteRule.setEnabled(false); + bnDeleteRule.setToolTipText(org.openide.util.NbBundle.getMessage(FileExporterSettingsPanel.class, "FileExporterSettingsPanel.DeleteTooltip_1")); // NOI18N bnDeleteRule.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnDeleteRuleActionPerformed(evt); @@ -1260,7 +1258,7 @@ public final class FileExporterSettingsPanel extends JPanel { } if (intrinsicType == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) { - LocalDateTime localDateTime = dateTimePicker.getDateTime(); + LocalDateTime localDateTime = dateTimePicker.getDateTimeStrict(); if (localDateTime == null) { throw new IllegalArgumentException("Bad date/time combination"); } @@ -2028,7 +2026,7 @@ public final class FileExporterSettingsPanel extends JPanel { private javax.swing.JComboBox comboBoxMimeTypeComparison; private javax.swing.JComboBox comboBoxMimeValue; private javax.swing.JComboBox comboBoxValueType; - private com.github.lgooddatepicker.datetimepicker.DateTimePicker dateTimePicker; + private com.github.lgooddatepicker.components.DateTimePicker dateTimePicker; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel lbArtifact; private javax.swing.JLabel lbAttribute; From e25c97d031b2698ef401dd31e881d40bcbc90b08 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 5 Dec 2017 14:41:30 -0500 Subject: [PATCH 09/38] Cleanup --- .../datamodel/EamDbUtil.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java index 7a06401967..7c91f24648 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDbUtil.java @@ -135,28 +135,10 @@ public class EamDbUtil { * * @return true on success, else false */ - /* - public static boolean insertSchemaVersion(Connection conn) { - PreparedStatement preparedStatement = null; - String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; - try { - preparedStatement = conn.prepareStatement(sql); - preparedStatement.setString(1, "SCHEMA_VERSION"); - preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION)); - preparedStatement.executeUpdate(); - } catch (SQLException ex) { - LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex); - return false; - } finally { - EamDbUtil.closePreparedStatement(preparedStatement); - } - return true; - }*/ static boolean updateSchemaVersion(Connection conn) { Statement statement; ResultSet resultSet; - //PreparedStatement preparedStatement = null; String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)"; try { statement = conn.createStatement(); @@ -178,7 +160,6 @@ public class EamDbUtil { } catch (SQLException ex) { LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex); return false; - } finally { } return true; From 6e9a9e274b8f6bf5fa92cd1d53d473cb4aae27f4 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 5 Dec 2017 14:44:26 -0500 Subject: [PATCH 10/38] Cleanup --- .../autopsy/centralrepository/eventlisteners/Installer.java | 1 - .../centralrepository/optionspanel/GlobalSettingsPanel.java | 4 ---- 2 files changed, 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 680738b597..7ca97535d9 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners; import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; import org.openide.modules.ModuleInstall; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index fde18b8573..914d4c4d34 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -95,7 +95,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i boolean result = EamDbUtil.upgradeDatabase(); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); if(! result){ - //progressIndicator.finish(); JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "GlobalSettingsPanel.updateFailed.message"), @@ -357,9 +356,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i store(); updateDatabase(); load(); - //cbUseCentralRepo.setSelected(EamDbUtil.useCentralRepo()); - //enableDatabaseConfigureButton(cbUseCentralRepo.isSelected()); - //enableButtonSubComponents(cbUseCentralRepo.isSelected() && !EamDbPlatformEnum.getSelectedPlatform().equals(DISABLED)); this.ingestStateUpdated(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_cbUseCentralRepoActionPerformed From 7ce38a15aa73ac5db1349c4f8ebf94272a36d950 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Tue, 5 Dec 2017 16:52:21 -0500 Subject: [PATCH 11/38] 3219: Fix some issues with the datesearchpanel --- Core/nbproject/project.xml | 2 +- .../autopsy/filesearch/DateSearchPanel.form | 26 ++-- .../autopsy/filesearch/DateSearchPanel.java | 111 +++++++++++++++++- 3 files changed, 121 insertions(+), 18 deletions(-) diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 0b1523da09..a9e862ca39 100755 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -334,7 +334,7 @@ ext/LGoodDatePicker-10.3.1.jar - release/modules/ext/LGoodDatePicker-10.3.1.jar + release/modules/ext/LGoodDatePicker-10.3.1.jar ext/Tsk_DataModel_PostgreSQL.jar diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form index 1912ad3742..0d2d2b3d19 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form @@ -172,22 +172,22 @@ - - - + + + - - - + + + @@ -235,17 +235,19 @@ - - - + + + + - - - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java index c1ef741233..c406896b50 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java @@ -32,6 +32,9 @@ import com.github.lgooddatepicker.optionalusertools.PickerUtilities; import com.github.lgooddatepicker.components.DatePickerSettings; import com.github.lgooddatepicker.optionalusertools.DateChangeListener; import com.github.lgooddatepicker.zinternaltools.DateChangeEvent; +import java.text.ParseException; +import java.time.Instant; +import java.util.Date; /** * Subpanel with controls for file data filtering. @@ -191,11 +194,11 @@ class DateSearchPanel extends javax.swing.JPanel { } }); - jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N + jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N - jLabel2.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel2.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel2.text")); // NOI18N + jLabel2.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N modifiedCheckBox.setSelected(true); modifiedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.modifiedCheckBox.text")); // NOI18N @@ -229,9 +232,27 @@ class DateSearchPanel extends javax.swing.JPanel { } }); - fromDatePicker.setAutoscrolls(true); + fromDatePicker.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + fromDatePickerFocusLost(evt); + } + }); + fromDatePicker.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + fromDatePickerPropertyChange(evt); + } + }); - toDatePicker.setAutoscrolls(true); + toDatePicker.addFocusListener(new java.awt.event.FocusAdapter() { + public void focusLost(java.awt.event.FocusEvent evt) { + toDatePickerFocusLost(evt); + } + }); + toDatePicker.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + toDatePickerPropertyChange(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -320,7 +341,87 @@ class DateSearchPanel extends javax.swing.JPanel { private void changedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changedCheckBoxActionPerformed firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null); }//GEN-LAST:event_changedCheckBoxActionPerformed - + + private void fromDatePickerPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_fromDatePickerPropertyChange + if (evt.getNewValue() instanceof Date) { + setFromDate((Date) evt.getNewValue()); + } + }//GEN-LAST:event_fromDatePickerPropertyChange + + private void toDatePickerPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_toDatePickerPropertyChange + if (evt.getNewValue() instanceof Date) { + setToDate((Date) evt.getNewValue()); + } + }//GEN-LAST:event_toDatePickerPropertyChange + + private void fromDatePickerFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_fromDatePickerFocusLost + // set the "from" calendar button to listen to change in the text field + String fromDateString = this.fromDatePicker.getText(); + if (!fromDateString.equals("")) { + try { + Date fromDate = dateFormat.parse(fromDateString); + fromDatePicker.setDate(fromDate.toInstant().atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate()); + } catch (ParseException ex) { + // for now, no need to show the error message to the user her + } + } + }//GEN-LAST:event_fromDatePickerFocusLost + + private void toDatePickerFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_toDatePickerFocusLost + // set the "to" calendar button to listen to change in the text field + String toDateString = this.toDatePicker.getText(); + if (!toDateString.equals("")) { + try { + Date toDate = dateFormat.parse(toDateString); + toDatePicker.setDate(toDate.toInstant().atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate()); + } catch (ParseException ex) { + // for now, no need to show the error message to the user here + } + } + }//GEN-LAST:event_toDatePickerFocusLost + + /** + * Validate and set the datetime field on the screen given a datetime + * string. + * + * @param date The date object + */ + private void setFromDate(Date date) { + String dateStringResult = ""; + Instant ins = null; + if (date != null) { + dateStringResult = dateFormat.format(date); + ins = date.toInstant(); + } + + fromDatePicker.setText(dateStringResult); + if (ins != null) { + fromDatePicker.setDate(ins.atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate()); + } else { + fromDatePicker.setDate(null); + } + } + + /** + * Validate and set the datetime field on the screen given a date. + * + * @param date The date object + */ + private void setToDate(Date date) { + String dateStringResult = ""; + Instant ins = null; + if (date != null) { + dateStringResult = dateFormat.format(date); + ins = date.toInstant(); + } + toDatePicker.setText(dateStringResult); + if (ins != null) { + toDatePicker.setDate(ins.atZone(dateFormat.getTimeZone().toZoneId()).toLocalDate()); + } else { + toDatePicker.setDate(null); + } + } + boolean isValidSearch() { return this.accessedCheckBox.isSelected() || this.changedCheckBox.isSelected() || From a2b7763111b7aa6987f0dd87fb9039d7cfc00f64 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Tue, 5 Dec 2017 17:09:13 -0500 Subject: [PATCH 12/38] 3219: clean up the jcalendarbutton references --- CoreLibs/nbproject/project.properties | 1 - CoreLibs/nbproject/project.xml | 7 ------- 2 files changed, 8 deletions(-) diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 13a62b62ee..a76f795030 100755 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -44,7 +44,6 @@ file.reference.imgscalr-lib-4.2-sources.jar=release/modules/ext/imgscalr-lib-4.2 file.reference.imgscalr-lib-4.2.jar=release/modules/ext/imgscalr-lib-4.2.jar file.reference.javaee-api-5.0-2.jar=release/modules/ext/javaee-api-5.0-2.jar file.reference.javassist-3.12.1.GA.jar=release/modules/ext/javassist-3.12.1.GA.jar -file.reference.jcalendarbutton-1.4.6.jar=release/modules/ext/jcalendarbutton-1.4.6.jar file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 6fcef46ccd..d77c0b6f83 100755 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -212,7 +212,6 @@ jfxtras.scene.control jfxtras.scene.layout jfxtras.util - net.sourceforge.jcalendarbutton org.apache.avalon.framework org.apache.avalon.framework.activity org.apache.avalon.framework.component @@ -587,7 +586,6 @@ org.hyperic.sigar.vmware org.hyperic.sigar.win32 org.imgscalr - org.jbundle.thin.base.screen.jcalendarbutton org.joda.time org.joda.time.base org.joda.time.chrono @@ -630,7 +628,6 @@ org.slf4j.helpers org.slf4j.impl org.slf4j.spi - org.sourceforge.jcalendarbutton org.w3c.dom org.w3c.dom.css org.w3c.dom.events @@ -763,10 +760,6 @@ ext/poi-excelant-3.15.jar release/modules/ext/poi-excelant-3.15.jar - - ext/jcalendarbutton-1.4.6.jar - release/modules/ext/jcalendarbutton-1.4.6.jar - ext/imageio-psd-3.2.jar release/modules/ext/imageio-psd-3.2.jar From 0a8ea5a0be13ef1f7cdda9eb67cdef63f2e46b1b Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Wed, 6 Dec 2017 08:41:00 -0500 Subject: [PATCH 13/38] Add correlation type field to reference sets --- .../datamodel/AbstractSqlEamDb.java | 14 +- .../centralrepository/datamodel/EamDb.java | 124 ++++++++++-------- .../datamodel/EamGlobalSet.java | 29 +++- .../datamodel/PostgresEamDbSettings.java | 1 + .../datamodel/SqliteEamDb.java | 6 +- .../datamodel/SqliteEamDbSettings.java | 1 + .../HashDbCreateDatabaseDialog.java | 3 +- .../modules/hashdatabase/HashDbManager.java | 2 +- .../ImportCentralRepoDbProgressDialog.java | 3 +- 9 files changed, 113 insertions(+), 70 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 8eda401abe..03aa502350 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1608,7 +1608,7 @@ public abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement1 = null; PreparedStatement preparedStatement2 = null; ResultSet resultSet = null; - String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, import_date) VALUES (?, ?, ?, ?, ?, ?)"; + String sql1 = "INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?)"; String sql2 = "SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1"; try { @@ -1618,7 +1618,8 @@ public abstract class AbstractSqlEamDb implements EamDb { preparedStatement1.setString(3, eamGlobalSet.getVersion()); preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue()); preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly()); - preparedStatement1.setString(6, eamGlobalSet.getImportDate().toString()); + preparedStatement1.setInt(6, eamGlobalSet.getType().getId()); + preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString()); preparedStatement1.executeUpdate(); @@ -1678,18 +1679,20 @@ public abstract class AbstractSqlEamDb implements EamDb { /** * Get all reference sets * + * @param correlationType Type of sets to return + * * @return List of all reference sets in the central repository * * @throws EamDbException */ @Override - public List getAllReferenceSets() throws EamDbException { + public List getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException { List results = new ArrayList<>(); Connection conn = connect(); PreparedStatement preparedStatement1 = null; ResultSet resultSet = null; - String sql1 = "SELECT * FROM reference_sets"; + String sql1 = "SELECT * FROM reference_sets WHERE type=" + correlationType.getId(); try { preparedStatement1 = conn.prepareStatement(sql1); @@ -2193,7 +2196,7 @@ public abstract class AbstractSqlEamDb implements EamDb { return eamOrganization; } - private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) throws SQLException { + private EamGlobalSet getEamGlobalSetFromResultSet(ResultSet resultSet) throws SQLException, EamDbException { if (null == resultSet) { return null; } @@ -2205,6 +2208,7 @@ public abstract class AbstractSqlEamDb implements EamDb { resultSet.getString("version"), TskData.FileKnown.valueOf(resultSet.getByte("known_status")), resultSet.getBoolean("read_only"), + EamDb.getInstance().getCorrelationTypeById(resultSet.getInt("type")), LocalDate.parse(resultSet.getString("import_date")) ); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index f8ab7bfc60..2b05cb1d70 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -33,7 +33,7 @@ public interface EamDb { public static final int SCHEMA_VERSION = 1; public static final CaseDbSchemaVersionNumber CURRENT_DB_SCHEMA_VERSION - = new CaseDbSchemaVersionNumber(1, 1); + = new CaseDbSchemaVersionNumber(1, 1); /** * Get the instance @@ -103,7 +103,7 @@ public interface EamDb { /** * Add a new name/value pair in the db_info table. * - * @param name Key to set + * @param name Key to set * @param value Value to set * * @throws EamDbException @@ -124,7 +124,7 @@ public interface EamDb { /** * Update the value for a name in the name/value db_info table. * - * @param name Name to find + * @param name Name to find * @param value Value to assign to name. * * @throws EamDbException @@ -146,8 +146,6 @@ public interface EamDb { * @param autopsyCase The case to add */ CorrelationCase newCase(Case autopsyCase) throws EamDbException; - - /** * Updates an existing Case in the database @@ -158,13 +156,13 @@ public interface EamDb { /** * Retrieves Central Repo case based on an Autopsy Case - * + * * @param autopsyCase Autopsy case to find corresponding CR case for * @return CR Case - * @throws EamDbException + * @throws EamDbException */ CorrelationCase getCase(Case autopsyCase) throws EamDbException; - + /** * Retrieves Case details based on Case UUID * @@ -191,8 +189,8 @@ public interface EamDb { /** * Retrieves Data Source details based on data source device ID * - * @param correlationCase the current CorrelationCase used for ensuring - * uniqueness of DataSource + * @param correlationCase the current CorrelationCase used for ensuring + * uniqueness of DataSource * @param dataSourceDeviceId the data source device ID number * * @return The data source @@ -229,7 +227,7 @@ public interface EamDb { * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath * - * @param aType EamArtifact.Type to search for + * @param aType EamArtifact.Type to search for * @param filePath File path to search for * * @return List of 0 or more EamArtifactInstances @@ -246,7 +244,7 @@ public interface EamDb { * @param value Value to search for * * @return Number of artifact instances having ArtifactType and - * ArtifactValue. + * ArtifactValue. */ Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException; @@ -283,11 +281,11 @@ public interface EamDb { * associated with the caseDisplayName and dataSource of the given * eamArtifact instance. * - * @param caseUUID Case ID to search for + * @param caseUUID Case ID to search for * @param dataSourceID Data source ID to search for * * @return Number of artifact instances having caseDisplayName and - * dataSource + * dataSource */ Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException; @@ -349,7 +347,7 @@ public interface EamDb { * @param value Value to search for * * @return List of cases containing this artifact with instances marked as - * bad + * bad * * @throws EamDbException */ @@ -357,14 +355,17 @@ public interface EamDb { /** * Remove a reference set and all values contained in it. + * * @param referenceSetID - * @throws EamDbException + * @throws EamDbException */ public void deleteReferenceSet(int referenceSetID) throws EamDbException; - + /** - * Check whether a reference set with the given parameters exists in the central repository. - * Used to check whether reference sets saved in the settings are still present. + * Check whether a reference set with the given parameters exists in the + * central repository. Used to check whether reference sets saved in the + * settings are still present. + * * @param referenceSetID * @param referenceSetName * @param version @@ -372,36 +373,40 @@ public interface EamDb { * @throws EamDbException */ public boolean referenceSetIsValid(int referenceSetID, String referenceSetName, String version) throws EamDbException; - + /** - * Check whether a reference set with the given name/version is in the central repo. - * Used to check for name collisions when creating reference sets. + * Check whether a reference set with the given name/version is in the + * central repo. Used to check for name collisions when creating reference + * sets. + * * @param referenceSetName * @param version * @return true if a matching set is found - * @throws EamDbException + * @throws EamDbException */ public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException; - + /** - * Check if the given file hash is in this reference set. - * Only searches the reference_files table. + * Check if the given file hash is in this reference set. Only searches the + * reference_files table. + * * @param hash * @param referenceSetID * @return true if the hash is found in the reference set - * @throws EamDbException + * @throws EamDbException */ public boolean isFileHashInReferenceSet(String hash, int referenceSetID) throws EamDbException; - + /** * Check if the given value is in a specific reference set + * * @param value * @param referenceSetID - * @param correlationTypeID + * @param correlationTypeID * @return true if the hash is found in the reference set */ - public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException; - + public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException; + /** * Is the artifact known as bad according to the reference entries? * @@ -418,7 +423,7 @@ public interface EamDb { * @param eamOrg The organization to add * * @return the Organization ID of the newly created organization. - * + * * @throws EamDbException */ long newOrganization(EamOrganization eamOrg) throws EamDbException; @@ -445,9 +450,10 @@ public interface EamDb { /** * Get the organization associated with the given reference set. + * * @param referenceSetID ID of the reference set * @return The organization object - * @throws EamDbException + * @throws EamDbException */ EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException; @@ -455,7 +461,7 @@ public interface EamDb { * Update an existing organization. * * @param updatedOrganization the values the Organization with the same ID - * will be updated to in the database. + * will be updated to in the database. * * @throws EamDbException */ @@ -463,13 +469,13 @@ public interface EamDb { /** * Delete an organization if it is not being used by any case. - * + * * @param organizationToDelete the organization to be deleted - * - * @throws EamDbException + * + * @throws EamDbException */ void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException; - + /** * Add a new Global Set * @@ -491,33 +497,34 @@ public interface EamDb { * @throws EamDbException */ EamGlobalSet getReferenceSetByID(int globalSetID) throws EamDbException; - + /** * Get all reference sets * + * @param correlationType Type of sets to return + * * @return List of all reference sets in the central repository * * @throws EamDbException */ - List getAllReferenceSets() throws EamDbException; + List getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException; /** * Add a new reference instance * * @param eamGlobalFileInstance The reference instance to add - * @param correlationType Correlation Type that this Reference - * Instance is + * @param correlationType Correlation Type that this Reference Instance is * * @throws EamDbException */ void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException; - + /** * Insert the bulk collection of Global File Instances * * @param globalInstances a Set of EamGlobalFileInstances to insert into the - * db. - * @param contentType the Type of the global instances + * db. + * @param contentType the Type of the global instances * * @throws EamDbException */ @@ -526,7 +533,7 @@ public interface EamDb { /** * Get all reference entries having a given correlation type and value * - * @param aType Type to use for matching + * @param aType Type to use for matching * @param aValue Value to use for matching * * @return List of all global file instances with a type and value @@ -551,7 +558,7 @@ public interface EamDb { * used to correlate artifacts. * * @return List of EamArtifact.Type's. If none are defined in the database, - * the default list will be returned. + * the default list will be returned. * * @throws EamDbException */ @@ -562,7 +569,7 @@ public interface EamDb { * artifacts. * * @return List of enabled EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @@ -573,7 +580,7 @@ public interface EamDb { * correlate artifacts. * * @return List of supported EamArtifact.Type's. If none are defined in the - * database, the default list will be returned. + * database, the default list will be returned. * * @throws EamDbException */ @@ -598,20 +605,23 @@ public interface EamDb { * @throws EamDbException */ public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException; - + /** * Upgrade the schema of the database (if needed) - * @throws EamDbException + * + * @throws EamDbException */ public void upgradeSchema() throws EamDbException, SQLException; - + /** - * Gets an exclusive lock (if applicable). - * Will return the lock if successful, null if unsuccessful because locking - * isn't supported, and throw an exception if we should have been able to get the - * lock but failed (meaning the database is in use). + * Gets an exclusive lock (if applicable). Will return the lock if + * successful, null if unsuccessful because locking isn't supported, and + * throw an exception if we should have been able to get the lock but failed + * (meaning the database is in use). + * * @return the lock, or null if locking is not supported - * @throws EamDbException if the coordination service is running but we fail to get the lock + * @throws EamDbException if the coordination service is running but we fail + * to get the lock */ public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamGlobalSet.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamGlobalSet.java index 23a4c257ae..a434afb32b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamGlobalSet.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamGlobalSet.java @@ -32,6 +32,7 @@ public class EamGlobalSet { private String version; private TskData.FileKnown fileKnownStatus; private boolean isReadOnly; + private CorrelationAttribute.Type type; private LocalDate importDate; public EamGlobalSet( @@ -41,6 +42,7 @@ public class EamGlobalSet { String version, TskData.FileKnown knownStatus, boolean isReadOnly, + CorrelationAttribute.Type type, LocalDate importDate) { this.globalSetID = globalSetID; this.orgID = orgID; @@ -48,6 +50,7 @@ public class EamGlobalSet { this.version = version; this.fileKnownStatus = knownStatus; this.isReadOnly = isReadOnly; + this.type = type; this.importDate = importDate; } @@ -57,8 +60,9 @@ public class EamGlobalSet { String version, TskData.FileKnown knownStatus, boolean isReadOnly, + CorrelationAttribute.Type type, LocalDate importDate) { - this(-1, orgID, setName, version, knownStatus, isReadOnly, importDate); + this(-1, orgID, setName, version, knownStatus, isReadOnly, type, importDate); } /** @@ -77,8 +81,9 @@ public class EamGlobalSet { String setName, String version, TskData.FileKnown knownStatus, - boolean isReadOnly) { - this(-1, orgID, setName, version, knownStatus, isReadOnly, LocalDate.now()); + boolean isReadOnly, + CorrelationAttribute.Type type) { + this(-1, orgID, setName, version, knownStatus, isReadOnly, type, LocalDate.now()); } /** @@ -164,6 +169,24 @@ public class EamGlobalSet { public void setFileKnownStatus(TskData.FileKnown fileKnownStatus) { this.fileKnownStatus = fileKnownStatus; } + + /** + * Get the type of reference set + * + * @return the type (files, phone numbers, etc) + */ + public CorrelationAttribute.Type getType() { + return type; + } + + /** + * Sets the type of reference set + * + * @param type + */ + void setType(CorrelationAttribute.Type type) { + this.type = type; + } /** * @return the importDate diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java index f58d313e47..869d13dc70 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java @@ -356,6 +356,7 @@ public final class PostgresEamDbSettings { createReferenceSetsTable.append("version text NOT NULL,"); createReferenceSetsTable.append("known_status integer NOT NULL,"); createReferenceSetsTable.append("read_only boolean NOT NULL,"); + createReferenceSetsTable.append("type integer NOT NULL,"); createReferenceSetsTable.append("import_date text NOT NULL,"); createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,"); createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 55e60dd380..c9931675a8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -807,15 +807,17 @@ public class SqliteEamDb extends AbstractSqlEamDb { /** * Get all reference sets * + * @param correlationType Type of sets to return + * * @return List of all reference sets in the central repository * * @throws EamDbException */ @Override - public List getAllReferenceSets() throws EamDbException{ + public List getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException { try{ acquireSharedLock(); - return super.getAllReferenceSets(); + return super.getAllReferenceSets(correlationType); } finally { releaseSharedLock(); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java index 9355dbacde..f006cc7e24 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java @@ -298,6 +298,7 @@ public final class SqliteEamDbSettings { createReferenceSetsTable.append("version text NOT NULL,"); createReferenceSetsTable.append("known_status integer NOT NULL,"); createReferenceSetsTable.append("read_only boolean NOT NULL,"); + createReferenceSetsTable.append("type integer NOT NULL,"); createReferenceSetsTable.append("import_date text NOT NULL,"); createReferenceSetsTable.append("foreign key (org_id) references organizations(id) ON UPDATE SET NULL ON DELETE SET NULL,"); createReferenceSetsTable.append("CONSTRAINT hash_set_unique UNIQUE (set_name, version)"); diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java index 13dd9bcd63..701b2995a8 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbCreateDatabaseDialog.java @@ -31,6 +31,7 @@ import javax.swing.JOptionPane; import org.apache.commons.io.FilenameUtils; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil; @@ -527,7 +528,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog { try{ int referenceSetID = EamDb.getInstance().newReferenceSet(new EamGlobalSet(selectedOrg.getOrgID(), hashSetNameTextField.getText(), - "", fileKnown, false)); + "", fileKnown, false, EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID))); newHashDb = HashDbManager.getInstance().addExistingCentralRepoHashSet(hashSetNameTextField.getText(), "", referenceSetID, true, sendIngestMessagesCheckbox.isSelected(), type, false); diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java index 34770aa6fa..c032bdc83e 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/HashDbManager.java @@ -490,7 +490,7 @@ public class HashDbManager implements PropertyChangeListener { List crHashSets = new ArrayList<>(); if(EamDb.isEnabled()){ try{ - List crSets = EamDb.getInstance().getAllReferenceSets(); + List crSets = EamDb.getInstance().getAllReferenceSets(EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID)); for(EamGlobalSet globalSet:crSets){ // Defaults for fields not stored in the central repository: diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/ImportCentralRepoDbProgressDialog.java b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/ImportCentralRepoDbProgressDialog.java index 37d3a20009..bbcc503b08 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/ImportCentralRepoDbProgressDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/ImportCentralRepoDbProgressDialog.java @@ -237,7 +237,8 @@ class ImportCentralRepoDbProgressDialog extends javax.swing.JDialog implements P // Create an empty hashset in the central repository EamDb dbManager = EamDb.getInstance(); - referenceSetID.set(dbManager.newReferenceSet(new EamGlobalSet(orgId, hashSetName, version, knownStatus, readOnly))); + referenceSetID.set(dbManager.newReferenceSet(new EamGlobalSet(orgId, hashSetName, version, knownStatus, + readOnly, EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID)))); // Get the "FILES" content type. This is a database lookup so we // only want to do it once. From 535729f8989dc36386c2b6ef004c49d62c9b1d66 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Wed, 6 Dec 2017 11:34:15 -0500 Subject: [PATCH 14/38] 3219: update copyright year in the header --- Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java | 2 +- .../experimental/autoingest/FileExporterSettingsPanel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java index c406896b50..1c38b7e35b 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java index 1352f22099..4413d948f4 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/FileExporterSettingsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2015 Basis Technology Corp. + * Copyright 2015-2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); From 4ad81039420228b2a0b59a6d451b783c58b10599 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 6 Dec 2017 16:04:03 -0500 Subject: [PATCH 15/38] Added 'Run Ingest Modules' option. --- .../autopsy/datamodel/DirectoryNode.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java index 68aeb01e8c..5a2bb87660 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import javax.swing.Action; @@ -32,8 +33,10 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; +import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM; @@ -42,7 +45,7 @@ import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM; * are more directories. */ public class DirectoryNode extends AbstractFsContentNode { - + private static final Logger LOGGER = Logger.getLogger(DirectoryNode.class.getName()); public static final String DOTDOTDIR = NbBundle.getMessage(DirectoryNode.class, "DirectoryNode.parFolder.text"); @@ -88,17 +91,19 @@ public class DirectoryNode extends AbstractFsContentNode { actionsList.add(null); // creates a menu separator } actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "DirectoryNode.viewInNewWin.text"), this)); - actionsList.add(ViewFileInTimelineAction.createViewFileAction(getContent())); + actionsList.add(ViewFileInTimelineAction.createViewFileAction(content)); actionsList.add(null); // creates a menu separator actionsList.add(ExtractAction.getInstance()); actionsList.add(null); // creates a menu separator + actionsList.add(new RunIngestModulesAction(Collections.singletonList(content))); + actionsList.add(null); // creates a menu separator actionsList.add(AddContentTagAction.getInstance()); - + final Collection selectedFilesList = new HashSet<>(Utilities.actionsGlobalContext().lookupAll(AbstractFile.class)); - if(selectedFilesList.size() == 1) { + if (selectedFilesList.size() == 1) { actionsList.add(DeleteFileContentTagAction.getInstance()); } - + actionsList.addAll(ContextMenuExtensionPoint.getActions()); return actionsList.toArray(new Action[actionsList.size()]); } From d47727ffbb0ac165fd416e2d081ee4a209788417 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 6 Dec 2017 17:14:58 -0500 Subject: [PATCH 16/38] Added wait cursor for Multi-User Case window init. --- .../casemodule/CaseOpenMultiUserAction.java | 25 ++++++++++++------- .../autopsy/casemodule/CueBannerPanel.java | 14 ++++++++--- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java index 7a12b69cf7..270d2f9fb7 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.casemodule; +import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JDialog; @@ -44,11 +45,12 @@ public final class CaseOpenMultiUserAction extends CallableSystemAction implemen private static final long serialVersionUID = 1L; private static JDialog multiUserCaseWindow; - + private static final String DISPLAY_NAME = Bundle.CTL_CaseOpenMultiUserAction(); - public CaseOpenMultiUserAction() {} - + public CaseOpenMultiUserAction() { + } + @Override public boolean isEnabled() { return UserPreferences.getIsMultiUserModeEnabled(); @@ -62,11 +64,16 @@ public final class CaseOpenMultiUserAction extends CallableSystemAction implemen */ @Override public void actionPerformed(ActionEvent event) { - if(multiUserCaseWindow == null) { - multiUserCaseWindow = MultiUserCasesDialog.getInstance(); + WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + try { + if (multiUserCaseWindow == null) { + multiUserCaseWindow = MultiUserCasesDialog.getInstance(); + } + multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + multiUserCaseWindow.setVisible(true); + } finally { + WindowManager.getDefault().getMainWindow().setCursor(null); } - multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - multiUserCaseWindow.setVisible(true); } @Override @@ -83,7 +90,7 @@ public final class CaseOpenMultiUserAction extends CallableSystemAction implemen public HelpCtx getHelpCtx() { return HelpCtx.DEFAULT_HELP; } - + @Override public boolean asynchronous() { return false; // run on edt diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java index 2c81d100e4..6ddd505f64 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.casemodule; +import java.awt.Cursor; import java.awt.Dialog; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -106,7 +107,7 @@ public class CueBannerPanel extends javax.swing.JPanel { boolean enableOpenRecentCaseButton = (RecentCases.getInstance().getTotalRecentCases() > 0); openRecentCaseButton.setEnabled(enableOpenRecentCaseButton); openRecentCaseLabel.setEnabled(enableOpenRecentCaseButton); - + boolean enableOpenMultiUserCaseButton = UserPreferences.getIsMultiUserModeEnabled(); openMultiUserCaseButton.setEnabled(enableOpenMultiUserCaseButton); openMultiUserCaseLabel.setEnabled(enableOpenMultiUserCaseButton); @@ -276,9 +277,14 @@ public class CueBannerPanel extends javax.swing.JPanel { }//GEN-LAST:event_openRecentCaseButtonActionPerformed private void openMultiUserCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMultiUserCaseButtonActionPerformed - MultiUserCasesDialog multiUserCaseWindow = MultiUserCasesDialog.getInstance(); - multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - multiUserCaseWindow.setVisible(true); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + try { + MultiUserCasesDialog multiUserCaseWindow = MultiUserCasesDialog.getInstance(); + multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + multiUserCaseWindow.setVisible(true); + } finally { + setCursor(null); + } }//GEN-LAST:event_openMultiUserCaseButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From 2c7f929abdf3d8302b76a001ac1ff81172bf4b35 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 6 Dec 2017 17:27:02 -0500 Subject: [PATCH 17/38] First cut at implementing the search back off --- .../autopsy/keywordsearch/SearchRunner.java | 83 +++++++++++++------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index def0583553..b113a59fb0 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.keywordsearch; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -30,6 +31,9 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import javax.swing.SwingUtilities; @@ -38,6 +42,7 @@ import org.netbeans.api.progress.aggregate.AggregateProgressFactory; import org.netbeans.api.progress.aggregate.AggregateProgressHandle; import org.netbeans.api.progress.aggregate.ProgressContributor; import org.openide.util.Cancellable; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; @@ -58,14 +63,17 @@ final class SearchRunner { private IngestServices services = IngestServices.getInstance(); private Ingester ingester = null; private volatile boolean updateTimerRunning = false; - private Timer updateTimer; + private Future jobProcessingTaskFuture; + private final ScheduledThreadPoolExecutor jobProcessingExecutor; + private static final int NUM_SEARCH_SCHEDULING_THREADS = 1; + private static final String SEARCH_SCHEDULER_THREAD_NAME = "periodic-search-scheduler-%d"; // maps a jobID to the search private Map jobs = new HashMap<>(); //guarded by "this" SearchRunner() { ingester = Ingester.getDefault(); - updateTimer = new Timer(NbBundle.getMessage(this.getClass(), "SearchRunner.updateTimer.title.text"), true); // run as a daemon + jobProcessingExecutor = new ScheduledThreadPoolExecutor(NUM_SEARCH_SCHEDULING_THREADS, new ThreadFactoryBuilder().setNameFormat(SEARCH_SCHEDULER_THREAD_NAME).build()); } /** @@ -98,7 +106,7 @@ final class SearchRunner { // start the timer, if needed if ((jobs.size() > 0) && (updateTimerRunning == false)) { final long updateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; - updateTimer.scheduleAtFixedRate(new UpdateTimerTask(), updateIntervalMs, updateIntervalMs); + jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), updateIntervalMs, MILLISECONDS); updateTimerRunning = true; } } @@ -129,6 +137,11 @@ final class SearchRunner { logger.log(Level.INFO, "Commiting search index before final search for search job {0}", job.getJobId()); //NON-NLS commit(); doFinalSearch(job); //this will block until it's done + + // we are done with all the searches. stop the PeriodicSearchTask. + // A new one will be created for future jobs. + updateTimerRunning = false; + jobProcessingTaskFuture.cancel(true); } } @@ -156,6 +169,13 @@ final class SearchRunner { } jobs.remove(jobId); + + if (jobs.isEmpty()) { + // no more jobs left. stop the PeriodicSearchTask. + // A new one will be created for future jobs. + updateTimerRunning = false; + jobProcessingTaskFuture.cancel(true); + } } } @@ -223,23 +243,24 @@ final class SearchRunner { } /** - * Timer triggered re-search for each job (does a single index commit first) + * Task triggered re-search for each job (does a single index commit first) */ - private class UpdateTimerTask extends TimerTask { + private final class PeriodicSearchTask implements Runnable { - private final Logger logger = Logger.getLogger(SearchRunner.UpdateTimerTask.class.getName()); + private final Logger logger = Logger.getLogger(SearchRunner.PeriodicSearchTask.class.getName()); @Override public void run() { // If no jobs then cancel the task. If more job(s) come along, a new task will start up. - if (jobs.isEmpty()) { - this.cancel(); //terminate this timer task + if (jobs.isEmpty() || jobProcessingTaskFuture.isCancelled()) { updateTimerRunning = false; return; } commit(); + final StopWatch stopWatch = new StopWatch(); + stopWatch.start(); synchronized (SearchRunner.this) { // Spawn a search thread for each job for (Entry j : jobs.entrySet()) { @@ -247,13 +268,40 @@ final class SearchRunner { // If no lists or the worker is already running then skip it if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) { logger.log(Level.INFO, "Executing periodic search for search job {0}", job.getJobId()); - Searcher searcher = new Searcher(job); + Searcher searcher = new Searcher(job); // SwingWorker job.setCurrentSearcher(searcher); //save the ref searcher.execute(); //start thread job.setWorkerRunning(true); + + try { + // wait for the searcher to finish + searcher.get(); + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, "Error performing keyword search: {0}", ex.getMessage()); //NON-NLS + services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(), + NbBundle.getMessage(this.getClass(), + "SearchRunner.Searcher.done.err.msg"), ex.getMessage())); + }// catch and ignore if we were cancelled + catch (java.util.concurrent.CancellationException ex) { + } } } } + stopWatch.stop(); + + // calculate "hold off" time + final long timeToTextSleepMs = getTimeToNextSleep(stopWatch.getElapsedTimeSecs()); + + // schedule next PeriodicSearchTask + jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSleepMs, MILLISECONDS); + + // exit this thread + return; + } + + + private long getTimeToNextSleep(long lastSerchTimeMs) { + return lastSerchTimeMs; } } @@ -522,23 +570,6 @@ final class SearchRunner { return null; } - @Override - protected void done() { - // call get to see if there were any errors - try { - logger.log(Level.INFO, "Searcher calling get() on itself in done()"); //NON-NLS - get(); - logger.log(Level.INFO, "Searcher finished calling get() on itself in done()"); //NON-NLS - } catch (InterruptedException | ExecutionException e) { - logger.log(Level.SEVERE, "Error performing keyword search: " + e.getMessage()); //NON-NLS - services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "SearchRunner.Searcher.done.err.msg"), e.getMessage())); - } // catch and ignore if we were cancelled - catch (java.util.concurrent.CancellationException ex) { - } - } - /** * Sync-up the updated keywords from the currently used lists in the XML */ From a45715e8c240cb576bfe5fa0093be56d3a69a7f7 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 6 Dec 2017 17:31:13 -0500 Subject: [PATCH 18/38] Minor revision. --- .../casemodule/CaseOpenMultiUserAction.java | 15 +++++++-------- .../autopsy/casemodule/CueBannerPanel.java | 14 +++++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java index 270d2f9fb7..9e181bf23c 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java @@ -65,15 +65,14 @@ public final class CaseOpenMultiUserAction extends CallableSystemAction implemen @Override public void actionPerformed(ActionEvent event) { WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - try { - if (multiUserCaseWindow == null) { - multiUserCaseWindow = MultiUserCasesDialog.getInstance(); - } - multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - multiUserCaseWindow.setVisible(true); - } finally { - WindowManager.getDefault().getMainWindow().setCursor(null); + + if (multiUserCaseWindow == null) { + multiUserCaseWindow = MultiUserCasesDialog.getInstance(); } + multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + multiUserCaseWindow.setVisible(true); + + WindowManager.getDefault().getMainWindow().setCursor(null); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java index 6ddd505f64..933b0de554 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java @@ -278,13 +278,13 @@ public class CueBannerPanel extends javax.swing.JPanel { private void openMultiUserCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMultiUserCaseButtonActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - try { - MultiUserCasesDialog multiUserCaseWindow = MultiUserCasesDialog.getInstance(); - multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - multiUserCaseWindow.setVisible(true); - } finally { - setCursor(null); - } + + MultiUserCasesDialog multiUserCaseWindow = MultiUserCasesDialog.getInstance(); + multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + multiUserCaseWindow.setVisible(true); + + setCursor(null); + }//GEN-LAST:event_openMultiUserCaseButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From 8c39e23ec9f07b623d96a492ee64591e83d7dbb0 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Wed, 6 Dec 2017 17:35:49 -0500 Subject: [PATCH 19/38] add file's known status to CR --- .../datamodel/CorrelationAttributeInstance.java | 10 +--------- .../ingestmodule/IngestModule.java | 13 ++++++------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 7db48d28db..927b9a3c8f 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -96,7 +96,7 @@ public class CorrelationAttributeInstance implements Serializable { this(-1, eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus); } - public CorrelationAttributeInstance( + CorrelationAttributeInstance( int ID, CorrelationCase eamCase, CorrelationDataSource eamDataSource, @@ -198,12 +198,4 @@ public class CorrelationAttributeInstance implements Serializable { public GlobalStatus getGlobalStatus() { return globalStatus; } - - /** - * @param globalStatus the globalStatus to set - */ - public void setGlobalStatus(GlobalStatus globalStatus) { - this.globalStatus = globalStatus; - } - } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 9e1e36cb8a..10f3ca9051 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -105,22 +105,21 @@ class IngestModule implements FileIngestModule { return ProcessResult.OK; } - // If unknown to both the hash module and as a globally known artifact in the EAM DB, correlate to other cases - if (af.getKnown() == TskData.FileKnown.UNKNOWN) { - // query db for artifact instances having this MD5 and knownStatus = "Bad". + /* Search the central repo to see if this file was previously + * marked as being bad. Create artifact if it was. */ + if (af.getKnown() != TskData.FileKnown.KNOWN) { try { - // if af.getKnown() is "UNKNOWN" and this artifact instance was marked bad in a previous case, - // create TSK_INTERESTING_FILE artifact on BB. List caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(filesType, md5); if (!caseDisplayNames.isEmpty()) { postCorrelatedBadFileToBlackboard(af, caseDisplayNames); } } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex); // NON-NLS + LOGGER.log(Level.SEVERE, "Error searching database for artifact.", ex); // NON-NLS return ProcessResult.ERROR; } } + // insert this file into the central repository try { CorrelationAttribute eamArtifact = new CorrelationAttribute(filesType, md5); CorrelationAttributeInstance cefi = new CorrelationAttributeInstance( @@ -128,7 +127,7 @@ class IngestModule implements FileIngestModule { eamDataSource, af.getParentPath() + af.getName(), null, - TskData.FileKnown.UNKNOWN, + af.getKnown(), CorrelationAttributeInstance.GlobalStatus.LOCAL ); eamArtifact.addInstance(cefi); From 775e8afb2f32dc647472355ae5b2cf0e4bb011ac Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Wed, 6 Dec 2017 17:59:15 -0500 Subject: [PATCH 20/38] Added some todo comments --- .../autopsy/centralrepository/datamodel/EamArtifactUtil.java | 4 +++- .../centralrepository/eventlisteners/CaseEventListener.java | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index c2bb0e0016..5e61b261c1 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -227,7 +227,7 @@ public class EamArtifactUtil { * * @return The new EamArtifact or null if creation failed */ - public static CorrelationAttribute getEamArtifactFromContent(Content content, TskData.FileKnown knownStatus, String comment) { + public static CorrelationAttribute getCorrelationAttributeFromContent(Content content, TskData.FileKnown knownStatus, String comment) { if (!(content instanceof AbstractFile)) { return null; @@ -241,6 +241,7 @@ public class EamArtifactUtil { // We need a hash to make the artifact String md5 = af.getMd5Hash(); + // @@@ Should also check for empty data hash if (md5 == null || md5.isEmpty()) { return null; } @@ -258,6 +259,7 @@ public class EamArtifactUtil { CorrelationDataSource.fromTSKDataSource(correlationCase, af.getDataSource()), af.getParentPath() + af.getName(), comment, + // @@@ Shouldn't this use the knownStatus argument? TskData.FileKnown.BAD, CorrelationAttributeInstance.GlobalStatus.LOCAL ); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 88cf1ed59e..b053d9df17 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -191,7 +191,7 @@ final class CaseEventListener implements PropertyChangeListener { } } - final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(af, + final CorrelationAttribute eamArtifact = EamArtifactUtil.getCorrelationAttributeFromContent(af, knownStatus, comment); if (eamArtifact != null) { @@ -394,7 +394,7 @@ final class CaseEventListener implements PropertyChangeListener { } //if the file will have no tags with a status which would prevent the current status from being changed if (!hasTagWithConflictingKnownStatus) { - final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(contentTag.getContent(), + final CorrelationAttribute eamArtifact = EamArtifactUtil.getCorrelationAttributeFromContent(contentTag.getContent(), tagName.getKnownStatus(), ""); if (eamArtifact != null) { EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); From 70330c908033ba301565985e437cb257dee1c941 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 09:34:41 -0500 Subject: [PATCH 21/38] Clarify the use of the known_status field --- .../centralrepository/datamodel/AbstractSqlEamDb.java | 6 ++++-- .../datamodel/CorrelationAttributeInstance.java | 10 ++++++++-- .../centralrepository/datamodel/SqliteEamDb.java | 9 ++++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 8eda401abe..1dc372f81a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1001,12 +1001,14 @@ public abstract class AbstractSqlEamDb implements EamDb { } /** - * Sets an eamArtifact instance to the given knownStatus. If eamArtifact + * Sets an eamArtifact instance to the given knownStatus. + * knownStatus should be BAD if the file has been tagged with a notable tag and + * UNKNOWN otherwise. If eamArtifact * exists, it is updated. If eamArtifact does not exist it is added with the * given status. * * @param eamArtifact Artifact containing exactly one (1) ArtifactInstance. - * @param knownStatus The status to change the artifact to + * @param knownStatus The status to change the artifact to. Should never be KNOWN */ @Override public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 7db48d28db..196d5ab388 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -179,14 +179,20 @@ public class CorrelationAttributeInstance implements Serializable { } /** - * @return the knownStatus + * Get this knownStatus. This only indicates whether an item has been + * tagged as notable and should never return KNOWN. + * + * @return BAD if the item has been tagged as notable, UNKNOWN otherwise */ public TskData.FileKnown getKnownStatus() { return knownStatus; } /** - * @param knownStatus the knownStatus to set + * Set the knownStatus. This only indicates whether an item has been + * tagged as notable and should never be set to KNOWN. + * + * @param knownStatus Should be BAD if the item is tagged as notable, UNKNOWN otherwise */ public void setKnownStatus(TskData.FileKnown knownStatus) { this.knownStatus = knownStatus; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 55e60dd380..0ed78b3631 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -550,11 +550,14 @@ public class SqliteEamDb extends AbstractSqlEamDb { } /** - * Sets an eamArtifact instance as the given knownStatus. If eamArtifact - * exists, it is updated. If eamArtifact does not exist nothing happens + * Sets an eamArtifact instance to the given knownStatus. + * knownStatus should be BAD if the file has been tagged with a notable tag and + * UNKNOWN otherwise. If eamArtifact + * exists, it is updated. If eamArtifact does not exist it is added with the + * given status. * * @param eamArtifact Artifact containing exactly one (1) ArtifactInstance. - * @param knownStatus The known status of the artifact + * @param knownStatus The status to change the artifact to. Should never be KNOWN */ @Override public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException { From d3418db3d1e78df7fc6d6d97bb3ba330987cb518 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 8 Dec 2017 11:30:29 -0500 Subject: [PATCH 22/38] 3300 fix npe by adding tags to casedb in tagsmanager constructor --- .../autopsy/casemodule/services/TagNameDefinition.java | 2 +- .../org/sleuthkit/autopsy/casemodule/services/TagsManager.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefinition.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefinition.java index e1d81d2b65..e1d90d2f15 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefinition.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefinition.java @@ -179,7 +179,7 @@ final class TagNameDefinition implements Comparable { return displayName + "," + description + "," + color.name() + "," + knownStatus.toString(); } - private TagName saveToCase(SleuthkitCase caseDb) { + TagName saveToCase(SleuthkitCase caseDb) { TagName tagName = null; try { tagName = caseDb.addOrUpdateTagName(displayName, description, color, knownStatus); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index f96fe08f23..8d7eda2ec4 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -128,6 +128,9 @@ public class TagsManager implements Closeable { */ TagsManager(SleuthkitCase caseDb) { this.caseDb = caseDb; + for (TagNameDefinition tagName : TagNameDefinition.getTagNameDefinitions()) { + tagName.saveToCase(caseDb); + } } /** From f9f064c40d6d081594d3f375c78cb6fda33ab917 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 11:37:09 -0500 Subject: [PATCH 23/38] Revert to old known_status handling. --- .../autopsy/centralrepository/datamodel/EamArtifactUtil.java | 3 +-- .../autopsy/centralrepository/ingestmodule/IngestModule.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index 5e61b261c1..8669994d2e 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -259,8 +259,7 @@ public class EamArtifactUtil { CorrelationDataSource.fromTSKDataSource(correlationCase, af.getDataSource()), af.getParentPath() + af.getName(), comment, - // @@@ Shouldn't this use the knownStatus argument? - TskData.FileKnown.BAD, + knownStatus, CorrelationAttributeInstance.GlobalStatus.LOCAL ); eamArtifact.addInstance(cei); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 10f3ca9051..2cccdd48c8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -47,7 +47,6 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; /** @@ -127,7 +126,7 @@ class IngestModule implements FileIngestModule { eamDataSource, af.getParentPath() + af.getName(), null, - af.getKnown(), + TskData.FileKnown.UNKNOWN, CorrelationAttributeInstance.GlobalStatus.LOCAL ); eamArtifact.addInstance(cefi); From b4348c96c38fce5a75bbd351f6dcfd45e8a510ac Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Fri, 8 Dec 2017 11:42:35 -0500 Subject: [PATCH 24/38] Added comment. --- .../autopsy/centralrepository/ingestmodule/IngestModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 2cccdd48c8..f41c781bac 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -126,7 +126,7 @@ class IngestModule implements FileIngestModule { eamDataSource, af.getParentPath() + af.getName(), null, - TskData.FileKnown.UNKNOWN, + TskData.FileKnown.UNKNOWN, // NOTE: Known status in the CR is based on tagging, not hashes like the Case Database. CorrelationAttributeInstance.GlobalStatus.LOCAL ); eamArtifact.addInstance(cefi); From 0371633067c67121cb74529fa4b1cc33481d7d4e Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 11:52:21 -0500 Subject: [PATCH 25/38] Oops --- .../DataContentViewerOtherCases.java | 2 +- .../datamodel/AbstractSqlEamDb.java | 3 +- .../CorrelationAttributeInstance.java | 44 +++---------------- .../datamodel/EamArtifactUtil.java | 6 +-- .../ingestmodule/IngestModule.java | 3 +- 5 files changed, 12 insertions(+), 46 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index fbc955ca72..7d44b3a33f 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -453,7 +453,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D Collection eamGlobalFileInstances = dbManager.getReferenceInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); eamGlobalFileInstances.forEach((eamGlobalFileInstance) -> { eamArtifactInstances.add(new CorrelationAttributeInstance( - null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus(), CorrelationAttributeInstance.GlobalStatus.GLOBAL + null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus() )); }); return eamArtifactInstances; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 9560d635c4..bf0541009a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -2159,8 +2159,7 @@ public abstract class AbstractSqlEamDb implements EamDb { new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), resultSet.getString("file_path"), resultSet.getString("comment"), - TskData.FileKnown.valueOf(resultSet.getByte("known_status")), - CorrelationAttributeInstance.GlobalStatus.LOCAL + TskData.FileKnown.valueOf(resultSet.getByte("known_status")) ); return eamArtifactInstance; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 927b9a3c8f..26cad43a66 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -28,29 +28,12 @@ import org.sleuthkit.datamodel.TskData; * CorrelationAttribute. Includes its data source, path, etc. * */ -@Messages({"EamArtifactInstances.globalStatus.local=Local", - "EamArtifactInstances.globalStatus.global=Global", +@Messages({ "EamArtifactInstances.knownStatus.bad=Bad", "EamArtifactInstances.knownStatus.known=Known", "EamArtifactInstances.knownStatus.unknown=Unknown"}) public class CorrelationAttributeInstance implements Serializable { - public enum GlobalStatus { - LOCAL(Bundle.EamArtifactInstances_globalStatus_local()), - GLOBAL(Bundle.EamArtifactInstances_globalStatus_global()); - - private final String globalStatus; - - private GlobalStatus(String globalStatus) { - this.globalStatus = globalStatus; - } - - @Override - public String toString() { - return globalStatus; - } - } - private static final long serialVersionUID = 1L; private int ID; @@ -59,13 +42,12 @@ public class CorrelationAttributeInstance implements Serializable { private String filePath; private String comment; private TskData.FileKnown knownStatus; - private GlobalStatus globalStatus; public CorrelationAttributeInstance( CorrelationCase eamCase, CorrelationDataSource eamDataSource ) { - this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); + this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN); } public CorrelationAttributeInstance( @@ -73,7 +55,7 @@ public class CorrelationAttributeInstance implements Serializable { CorrelationDataSource eamDataSource, String filePath ) { - this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); + this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN); } public CorrelationAttributeInstance( @@ -82,7 +64,7 @@ public class CorrelationAttributeInstance implements Serializable { String filePath, String comment ) { - this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); + this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN); } public CorrelationAttributeInstance( @@ -90,10 +72,9 @@ public class CorrelationAttributeInstance implements Serializable { CorrelationDataSource eamDataSource, String filePath, String comment, - TskData.FileKnown knownStatus, - GlobalStatus globalStatus + TskData.FileKnown knownStatus ) { - this(-1, eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus); + this(-1, eamCase, eamDataSource, filePath, comment, knownStatus); } CorrelationAttributeInstance( @@ -102,8 +83,7 @@ public class CorrelationAttributeInstance implements Serializable { CorrelationDataSource eamDataSource, String filePath, String comment, - TskData.FileKnown knownStatus, - GlobalStatus globalStatus + TskData.FileKnown knownStatus ) { this.ID = ID; this.correlationCase = eamCase; @@ -112,7 +92,6 @@ public class CorrelationAttributeInstance implements Serializable { this.filePath = filePath.toLowerCase(); this.comment = comment; this.knownStatus = knownStatus; - this.globalStatus = globalStatus; } public Boolean equals(CorrelationAttributeInstance otherInstance) { @@ -120,7 +99,6 @@ public class CorrelationAttributeInstance implements Serializable { && (this.getCorrelationCase().equals(otherInstance.getCorrelationCase())) && (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource())) && (this.getFilePath().equals(otherInstance.getFilePath())) - && (this.getGlobalStatus().equals(otherInstance.getGlobalStatus())) && (this.getKnownStatus().equals(otherInstance.getKnownStatus())) && (this.getComment().equals(otherInstance.getComment()))); } @@ -131,7 +109,6 @@ public class CorrelationAttributeInstance implements Serializable { + this.getCorrelationCase().getCaseUUID() + this.getCorrelationDataSource().getName() + this.getFilePath() - + this.getGlobalStatus() + this.getKnownStatus() + this.getComment(); } @@ -191,11 +168,4 @@ public class CorrelationAttributeInstance implements Serializable { public void setKnownStatus(TskData.FileKnown knownStatus) { this.knownStatus = knownStatus; } - - /** - * @return the globalStatus - */ - public GlobalStatus getGlobalStatus() { - return globalStatus; - } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index 8669994d2e..60908aea77 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -105,8 +105,7 @@ public class EamArtifactUtil { CorrelationDataSource.fromTSKDataSource(correlationCase, bbSourceFile.getDataSource()), bbSourceFile.getParentPath() + bbSourceFile.getName(), "", - TskData.FileKnown.UNKNOWN, - CorrelationAttributeInstance.GlobalStatus.LOCAL + TskData.FileKnown.UNKNOWN ); // add the instance details @@ -259,8 +258,7 @@ public class EamArtifactUtil { CorrelationDataSource.fromTSKDataSource(correlationCase, af.getDataSource()), af.getParentPath() + af.getName(), comment, - knownStatus, - CorrelationAttributeInstance.GlobalStatus.LOCAL + knownStatus ); eamArtifact.addInstance(cei); return eamArtifact; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index f41c781bac..09f3c63449 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -126,8 +126,7 @@ class IngestModule implements FileIngestModule { eamDataSource, af.getParentPath() + af.getName(), null, - TskData.FileKnown.UNKNOWN, // NOTE: Known status in the CR is based on tagging, not hashes like the Case Database. - CorrelationAttributeInstance.GlobalStatus.LOCAL + TskData.FileKnown.UNKNOWN // NOTE: Known status in the CR is based on tagging, not hashes like the Case Database. ); eamArtifact.addInstance(cefi); dbManager.prepareBulkArtifact(eamArtifact); From 4f82f34d9d7271f133c7bcccc6a62bb7a171f4c4 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 12:18:05 -0500 Subject: [PATCH 26/38] Added logic to calculate hold off period --- .../autopsy/keywordsearch/SearchRunner.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index b113a59fb0..989d1838ce 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -62,6 +62,7 @@ final class SearchRunner { private static SearchRunner instance = null; private IngestServices services = IngestServices.getInstance(); private Ingester ingester = null; + private long defaultUpdateIntervalMs; private volatile boolean updateTimerRunning = false; private Future jobProcessingTaskFuture; private final ScheduledThreadPoolExecutor jobProcessingExecutor; @@ -72,6 +73,7 @@ final class SearchRunner { private Map jobs = new HashMap<>(); //guarded by "this" SearchRunner() { + defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; ingester = Ingester.getDefault(); jobProcessingExecutor = new ScheduledThreadPoolExecutor(NUM_SEARCH_SCHEDULING_THREADS, new ThreadFactoryBuilder().setNameFormat(SEARCH_SCHEDULER_THREAD_NAME).build()); } @@ -105,8 +107,9 @@ final class SearchRunner { // start the timer, if needed if ((jobs.size() > 0) && (updateTimerRunning == false)) { - final long updateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; - jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), updateIntervalMs, MILLISECONDS); + // reset the default periodic search frequency to the user setting + defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; + jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), defaultUpdateIntervalMs, MILLISECONDS); updateTimerRunning = true; } } @@ -290,18 +293,25 @@ final class SearchRunner { stopWatch.stop(); // calculate "hold off" time - final long timeToTextSleepMs = getTimeToNextSleep(stopWatch.getElapsedTimeSecs()); + final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); // schedule next PeriodicSearchTask - jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSleepMs, MILLISECONDS); + jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSearchMs, MILLISECONDS); // exit this thread return; } - private long getTimeToNextSleep(long lastSerchTimeMs) { - return lastSerchTimeMs; + private long getTimeToNextPeriodicSearch(long lastSerchTimeMs) { + // If periodic search takes more than 1/4 of the current periodic search interval, then double the search interval + if (lastSerchTimeMs < defaultUpdateIntervalMs / 4) { + return defaultUpdateIntervalMs; + } + // double the search interval + defaultUpdateIntervalMs = defaultUpdateIntervalMs * 2; + logger.log(Level.WARNING, "Last periodic search took {0} ms. Increasing search interval to {1} ms", new Object[]{lastSerchTimeMs, defaultUpdateIntervalMs}); + return defaultUpdateIntervalMs; } } From f44e570d4a4e2bb5a62bbc05e9de1ddbcbbc9f6b Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 12:50:23 -0500 Subject: [PATCH 27/38] Remove scope column and reference set entries from the content viewer --- .../DataContentViewerOtherCases.java | 31 ------------------- ...DataContentViewerOtherCasesTableModel.java | 7 +---- 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index 7d44b3a33f..ad642a9cbc 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -433,36 +433,6 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D return Collections.emptyList(); } - /** - * Get the global file instances matching the given eamArtifact and convert - * them to central repository artifact instances. - * - * @param eamArtifact Artifact to use for ArtifactTypeEnum matching - * - * @return List of central repository artifact instances, empty list if none - * found - */ - public Collection getReferenceInstancesAsArtifactInstances(CorrelationAttribute eamArtifact) { - Collection eamArtifactInstances = new ArrayList<>(); - // FUTURE: support other reference types - if (eamArtifact.getCorrelationType().getId() != CorrelationAttribute.FILES_TYPE_ID) { - return Collections.emptyList(); - } - try { - EamDb dbManager = EamDb.getInstance(); - Collection eamGlobalFileInstances = dbManager.getReferenceInstancesByTypeValue(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue()); - eamGlobalFileInstances.forEach((eamGlobalFileInstance) -> { - eamArtifactInstances.add(new CorrelationAttributeInstance( - null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus() - )); - }); - return eamArtifactInstances; - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Error getting reference instances from database.", ex); // NON-NLS - } - return Collections.emptyList(); - } - @Override public boolean isSupported(Node node) { if (!EamDb.isEnabled()) { @@ -517,7 +487,6 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D // get correlation and reference set instances from DB corAttrInstances.addAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId)); - corAttrInstances.addAll(getReferenceInstancesAsArtifactInstances(corAttr)); corAttrInstances.forEach((corAttrInstance) -> { CorrelationAttribute newCeArtifact = new CorrelationAttribute( diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index 58395b7ad5..61bcd68211 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -36,8 +36,7 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { "DataContentViewerOtherCasesTableModel.path=Path", "DataContentViewerOtherCasesTableModel.type=Correlation Type", "DataContentViewerOtherCasesTableModel.value=Correlation Value", - "DataContentViewerOtherCasesTableModel.scope=Scope", - "DataContentViewerOtherCasesTableModel.known=Known", + "DataContentViewerOtherCasesTableModel.known=Tagged", "DataContentViewerOtherCasesTableModel.comment=Comment", "DataContentViewerOtherCasesTableModel.noData=No Data.",}) enum TableColumns { @@ -48,7 +47,6 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { TYPE(Bundle.DataContentViewerOtherCasesTableModel_type(), 100), VALUE(Bundle.DataContentViewerOtherCasesTableModel_value(), 200), KNOWN(Bundle.DataContentViewerOtherCasesTableModel_known(), 50), - SCOPE(Bundle.DataContentViewerOtherCasesTableModel_scope(), 50), FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 450), COMMENT(Bundle.DataContentViewerOtherCasesTableModel_comment(), 200), DEVICE(Bundle.DataContentViewerOtherCasesTableModel_device(), 250); @@ -156,9 +154,6 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { case VALUE: value = eamArtifact.getCorrelationValue(); break; - case SCOPE: - value = eamArtifactInstance.getGlobalStatus().toString(); - break; case KNOWN: value = eamArtifactInstance.getKnownStatus().getName(); break; From bec02796d8b562a7c9f03791f9ce8eea16a9ae51 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 13:17:43 -0500 Subject: [PATCH 28/38] Bug fixes --- .../sleuthkit/autopsy/keywordsearch/SearchRunner.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index 989d1838ce..2d3bf8093d 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -262,6 +262,7 @@ final class SearchRunner { commit(); + logger.log(Level.INFO, "Starting periodic searches"); final StopWatch stopWatch = new StopWatch(); stopWatch.start(); synchronized (SearchRunner.this) { @@ -290,7 +291,9 @@ final class SearchRunner { } } } + logger.log(Level.INFO, "Finished periodic searches"); stopWatch.stop(); + logger.log(Level.INFO, "ALL periodic searches took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS // calculate "hold off" time final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); @@ -303,14 +306,14 @@ final class SearchRunner { } - private long getTimeToNextPeriodicSearch(long lastSerchTimeMs) { + private long getTimeToNextPeriodicSearch(long lastSerchTimeSec) { // If periodic search takes more than 1/4 of the current periodic search interval, then double the search interval - if (lastSerchTimeMs < defaultUpdateIntervalMs / 4) { + if (lastSerchTimeSec * 1000 < defaultUpdateIntervalMs / 4) { return defaultUpdateIntervalMs; } // double the search interval defaultUpdateIntervalMs = defaultUpdateIntervalMs * 2; - logger.log(Level.WARNING, "Last periodic search took {0} ms. Increasing search interval to {1} ms", new Object[]{lastSerchTimeMs, defaultUpdateIntervalMs}); + logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000}); return defaultUpdateIntervalMs; } } From c376637e9bf2926cb438ccde30b1697d3450ffb7 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 13:54:32 -0500 Subject: [PATCH 29/38] Don't generate artifacts for empty files --- .../autopsy/centralrepository/datamodel/EamArtifactUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index 60908aea77..171444fa42 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -28,6 +28,7 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; @@ -240,8 +241,7 @@ public class EamArtifactUtil { // We need a hash to make the artifact String md5 = af.getMd5Hash(); - // @@@ Should also check for empty data hash - if (md5 == null || md5.isEmpty()) { + if (md5 == null || md5.isEmpty() || HashUtility.isNoDataMd5(md5)) { return null; } From 1b12742dcff054856af7cdc345c82eb7cf0187de Mon Sep 17 00:00:00 2001 From: "U-BASIS\\zhaohui" Date: Fri, 8 Dec 2017 14:13:45 -0500 Subject: [PATCH 30/38] 3294: Enter Key works for file search by attributes --- .../autopsy/filesearch/FileSearchPanel.form | 8 +------ .../autopsy/filesearch/FileSearchPanel.java | 21 +++++++------------ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form index a64489bb01..f6fd00903f 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form @@ -37,10 +37,7 @@ - - - - + @@ -70,9 +67,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java index f6c72df611..e39070cd70 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java @@ -27,6 +27,7 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; +import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -110,7 +111,12 @@ class FileSearchPanel extends javax.swing.JPanel { } }); } - + addListenerToAll(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + search(); + } + }); searchButton.setEnabled(isValidSearch()); } @@ -284,11 +290,6 @@ class FileSearchPanel extends javax.swing.JPanel { filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS)); searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N - searchButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - searchButtonActionPerformed(evt); - } - }); errorLabel.setForeground(new java.awt.Color(255, 51, 51)); errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N @@ -311,17 +312,11 @@ class FileSearchPanel extends javax.swing.JPanel { .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(searchButton) - .addGroup(layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(errorLabel))) + .addComponent(errorLabel)) .addContainerGap()) ); }// //GEN-END:initComponents - private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed - search(); - }//GEN-LAST:event_searchButtonActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel errorLabel; private javax.swing.JPanel filterPanel; From bbbbd095e2875335a4dcee6a2a7b236740a15e16 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 14:46:33 -0500 Subject: [PATCH 31/38] Resolved cancellation synchronization issues --- .../autopsy/keywordsearch/SearchRunner.java | 143 +++++++++--------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index 2d3bf8093d..c4475e16f3 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -23,13 +23,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; import java.util.concurrent.CancellationException; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -42,7 +42,6 @@ import org.netbeans.api.progress.aggregate.AggregateProgressFactory; import org.netbeans.api.progress.aggregate.AggregateProgressHandle; import org.netbeans.api.progress.aggregate.ProgressContributor; import org.openide.util.Cancellable; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; @@ -63,14 +62,14 @@ final class SearchRunner { private IngestServices services = IngestServices.getInstance(); private Ingester ingester = null; private long defaultUpdateIntervalMs; - private volatile boolean updateTimerRunning = false; + private volatile boolean periodicSearchTaskRunning = false; private Future jobProcessingTaskFuture; private final ScheduledThreadPoolExecutor jobProcessingExecutor; private static final int NUM_SEARCH_SCHEDULING_THREADS = 1; private static final String SEARCH_SCHEDULER_THREAD_NAME = "periodic-search-scheduler-%d"; // maps a jobID to the search - private Map jobs = new HashMap<>(); //guarded by "this" + private Map jobs = new ConcurrentHashMap<>(); //guarded by "this" SearchRunner() { defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; @@ -97,7 +96,7 @@ final class SearchRunner { public synchronized void startJob(IngestJobContext jobContext, List keywordListNames) { long jobId = jobContext.getJobId(); if (jobs.containsKey(jobId) == false) { - logger.log(Level.INFO, "Adding job {0}", jobId); //NON-NLS + logger.log(Level.INFO, "ELDEBUG Adding job {0}", jobId); //NON-NLS SearchJobInfo jobData = new SearchJobInfo(jobContext, keywordListNames); jobs.put(jobId, jobData); } @@ -106,11 +105,12 @@ final class SearchRunner { jobs.get(jobId).incrementModuleReferenceCount(); // start the timer, if needed - if ((jobs.size() > 0) && (updateTimerRunning == false)) { + if ((jobs.size() > 0) && (periodicSearchTaskRunning == false)) { // reset the default periodic search frequency to the user setting + logger.log(Level.INFO, "ELDEBUG Resetting time out to default"); //NON-NLS defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), defaultUpdateIntervalMs, MILLISECONDS); - updateTimerRunning = true; + periodicSearchTaskRunning = true; } } @@ -120,30 +120,31 @@ final class SearchRunner { * * @param jobId */ - public void endJob(long jobId) { + public synchronized void endJob(long jobId) { SearchJobInfo job; boolean readyForFinalSearch = false; - synchronized (this) { - job = jobs.get(jobId); - if (job == null) { - return; - } + job = jobs.get(jobId); + if (job == null) { + logger.log(Level.INFO, "ELDEBUG job not found, returning {0}", jobId); //NON-NLS + return; + } - // Only do final search if this is the last module/thread in this job to call endJob() - if (job.decrementModuleReferenceCount() == 0) { - jobs.remove(jobId); - readyForFinalSearch = true; - } + // Only do final search if this is the last module/thread in this job to call endJob() + if (job.decrementModuleReferenceCount() == 0) { + logger.log(Level.INFO, "ELDEBUG removing job {0}", jobId); //NON-NLS + jobs.remove(jobId); + readyForFinalSearch = true; } if (readyForFinalSearch) { logger.log(Level.INFO, "Commiting search index before final search for search job {0}", job.getJobId()); //NON-NLS commit(); doFinalSearch(job); //this will block until it's done - + // we are done with all the searches. stop the PeriodicSearchTask. // A new one will be created for future jobs. - updateTimerRunning = false; + logger.log(Level.INFO, "ELDEBUG Cancelling periodic search task"); //NON-NLS + periodicSearchTaskRunning = false; jobProcessingTaskFuture.cancel(true); } } @@ -154,31 +155,33 @@ final class SearchRunner { * * @param jobId */ - public void stopJob(long jobId) { - logger.log(Level.INFO, "Stopping job {0}", jobId); //NON-NLS + public synchronized void stopJob(long jobId) { + logger.log(Level.INFO, "ELDEBUG Stopping job {0}", jobId); //NON-NLS commit(); SearchJobInfo job; - synchronized (this) { - job = jobs.get(jobId); - if (job == null) { - return; - } + job = jobs.get(jobId); + if (job == null) { + logger.log(Level.INFO, "ELDEBUG job not found, returning {0}", jobId); //NON-NLS + return; + } - //stop currentSearcher - SearchRunner.Searcher currentSearcher = job.getCurrentSearcher(); - if ((currentSearcher != null) && (!currentSearcher.isDone())) { - currentSearcher.cancel(true); - } + //stop currentSearcher + SearchRunner.Searcher currentSearcher = job.getCurrentSearcher(); + if ((currentSearcher != null) && (!currentSearcher.isDone())) { + logger.log(Level.INFO, "ELDEBUG cancelling job {0}", jobId); //NON-NLS + currentSearcher.cancel(true); + } - jobs.remove(jobId); - - if (jobs.isEmpty()) { - // no more jobs left. stop the PeriodicSearchTask. - // A new one will be created for future jobs. - updateTimerRunning = false; - jobProcessingTaskFuture.cancel(true); - } + logger.log(Level.INFO, "ELDEBUG removing job {0}", jobId); //NON-NLS + jobs.remove(jobId); + + if (jobs.isEmpty()) { + // no more jobs left. stop the PeriodicSearchTask. + // A new one will be created for future jobs. + logger.log(Level.INFO, "ELDEBUG Cancelling periodic search task"); //NON-NLS + periodicSearchTaskRunning = false; + jobProcessingTaskFuture.cancel(true); } } @@ -256,47 +259,47 @@ final class SearchRunner { public void run() { // If no jobs then cancel the task. If more job(s) come along, a new task will start up. if (jobs.isEmpty() || jobProcessingTaskFuture.isCancelled()) { - updateTimerRunning = false; + logger.log(Level.INFO, "ELDEBUG Exiting periodic search task"); //NON-NLS + periodicSearchTaskRunning = false; return; } commit(); - logger.log(Level.INFO, "Starting periodic searches"); + logger.log(Level.INFO, "ELDEBUG Starting periodic searches"); final StopWatch stopWatch = new StopWatch(); stopWatch.start(); - synchronized (SearchRunner.this) { - // Spawn a search thread for each job - for (Entry j : jobs.entrySet()) { - SearchJobInfo job = j.getValue(); - // If no lists or the worker is already running then skip it - if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) { - logger.log(Level.INFO, "Executing periodic search for search job {0}", job.getJobId()); - Searcher searcher = new Searcher(job); // SwingWorker - job.setCurrentSearcher(searcher); //save the ref - searcher.execute(); //start thread - job.setWorkerRunning(true); - - try { - // wait for the searcher to finish - searcher.get(); - } catch (InterruptedException | ExecutionException ex) { - logger.log(Level.SEVERE, "Error performing keyword search: {0}", ex.getMessage()); //NON-NLS - services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(), - NbBundle.getMessage(this.getClass(), - "SearchRunner.Searcher.done.err.msg"), ex.getMessage())); - }// catch and ignore if we were cancelled - catch (java.util.concurrent.CancellationException ex) { - } + // NOTE: contents of "jobs" ConcurrentHashMap can be modified in stopJob() and endJob() while we are inside this loop + for (Iterator> iterator = jobs.entrySet().iterator(); iterator.hasNext();) { + SearchJobInfo job = iterator.next().getValue(); + // If no lists or the worker is already running then skip it + if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) { + // Spawn a search thread for each job + logger.log(Level.INFO, "ELDEBUG Executing periodic search for search job {0}", job.getJobId()); + Searcher searcher = new Searcher(job); // SwingWorker + job.setCurrentSearcher(searcher); //save the ref + searcher.execute(); //start thread + job.setWorkerRunning(true); + + try { + // wait for the searcher to finish + searcher.get(); + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, "Error performing keyword search: {0}", ex.getMessage()); //NON-NLS + services.postMessage(IngestMessage.createErrorMessage(KeywordSearchModuleFactory.getModuleName(), + NbBundle.getMessage(this.getClass(), + "SearchRunner.Searcher.done.err.msg"), ex.getMessage())); + }// catch and ignore if we were cancelled + catch (java.util.concurrent.CancellationException ex) { } } } - logger.log(Level.INFO, "Finished periodic searches"); + logger.log(Level.INFO, "ELDEBUG Finished periodic searches"); stopWatch.stop(); - logger.log(Level.INFO, "ALL periodic searches took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS + logger.log(Level.INFO, "ELDEBUG ALL periodic searches took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS // calculate "hold off" time - final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); + final long timeToTextSearchMs = getTimeToNextPeriodicSearch(defaultUpdateIntervalMs /*stopWatch.getElapsedTimeSecs()*/); // ELDEBUG // schedule next PeriodicSearchTask jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSearchMs, MILLISECONDS); @@ -313,7 +316,7 @@ final class SearchRunner { } // double the search interval defaultUpdateIntervalMs = defaultUpdateIntervalMs * 2; - logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000}); + logger.log(Level.WARNING, "ELDEBUG Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000}); return defaultUpdateIntervalMs; } } From 68d99777f1881c16d6eb85ca3b8a502f819ba8d9 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 14:59:19 -0500 Subject: [PATCH 32/38] Don't stop at first VirtualDirectory found. --- .../autopsy/directorytree/ExtractUnallocAction.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java index 86ad6c967e..e30619abf9 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java @@ -147,7 +147,13 @@ final class ExtractUnallocAction extends AbstractAction { uw.execute(); } } else { - logger.log(Level.WARNING, "Tried to get unallocated content from volume ID but " + u.VolumeId + u.llf == null ? "its list of unallocated files was null" : "the volume is locked"); //NON-NLS + if(lockedVols.contains(u.getFileName())){ + logger.log(Level.WARNING, "Tried to get unallocated content but the volume is locked"); // NON_NLS + } else if (u.llf == null){ + logger.log(Level.SEVERE, "Tried to get unallocated content but the list of unallocated files was null"); //NON-NLS + } else { + logger.log(Level.INFO, "No unallocated files found in volume"); //NON-NLS + } } } if (isImage && !copyList.isEmpty()) { @@ -448,11 +454,13 @@ final class ExtractUnallocAction extends AbstractAction { @Override public List visit(Directory dir) { try { + List results = new ArrayList<>(); for (Content c : dir.getChildren()) { if (c instanceof VirtualDirectory) { - return c.accept(this); + results.addAll(c.accept(this)); } } + return results; } catch (TskCoreException tce) { logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting Directory " + dir.getId(), tce); //NON-NLS } From 70018a8af319dfb8ad7d9ad449eaf80ee65d6618 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Fri, 8 Dec 2017 15:11:37 -0500 Subject: [PATCH 33/38] Specifically look for $Unalloc dir --- .../autopsy/directorytree/ExtractUnallocAction.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java index e30619abf9..bcfa01f997 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ExtractUnallocAction.java @@ -454,13 +454,11 @@ final class ExtractUnallocAction extends AbstractAction { @Override public List visit(Directory dir) { try { - List results = new ArrayList<>(); for (Content c : dir.getChildren()) { - if (c instanceof VirtualDirectory) { - results.addAll(c.accept(this)); + if ((c instanceof VirtualDirectory) && (c.getName().equals(VirtualDirectory.NAME_UNALLOC))) { + return c.accept(this); } } - return results; } catch (TskCoreException tce) { logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting Directory " + dir.getId(), tce); //NON-NLS } From 80d957a2c3eea6865d5a376897d04925ca346b58 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 15:42:59 -0500 Subject: [PATCH 34/38] Finishing up --- .../autopsy/keywordsearch/SearchRunner.java | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index c4475e16f3..fff28a14b6 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -96,7 +96,7 @@ final class SearchRunner { public synchronized void startJob(IngestJobContext jobContext, List keywordListNames) { long jobId = jobContext.getJobId(); if (jobs.containsKey(jobId) == false) { - logger.log(Level.INFO, "ELDEBUG Adding job {0}", jobId); //NON-NLS + logger.log(Level.INFO, "Adding job {0}", jobId); //NON-NLS SearchJobInfo jobData = new SearchJobInfo(jobContext, keywordListNames); jobs.put(jobId, jobData); } @@ -107,7 +107,7 @@ final class SearchRunner { // start the timer, if needed if ((jobs.size() > 0) && (periodicSearchTaskRunning == false)) { // reset the default periodic search frequency to the user setting - logger.log(Level.INFO, "ELDEBUG Resetting time out to default"); //NON-NLS + logger.log(Level.INFO, "Resetting periodic search time out to default value"); //NON-NLS defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), defaultUpdateIntervalMs, MILLISECONDS); periodicSearchTaskRunning = true; @@ -125,13 +125,11 @@ final class SearchRunner { boolean readyForFinalSearch = false; job = jobs.get(jobId); if (job == null) { - logger.log(Level.INFO, "ELDEBUG job not found, returning {0}", jobId); //NON-NLS return; } // Only do final search if this is the last module/thread in this job to call endJob() if (job.decrementModuleReferenceCount() == 0) { - logger.log(Level.INFO, "ELDEBUG removing job {0}", jobId); //NON-NLS jobs.remove(jobId); readyForFinalSearch = true; } @@ -141,11 +139,14 @@ final class SearchRunner { commit(); doFinalSearch(job); //this will block until it's done - // we are done with all the searches. stop the PeriodicSearchTask. - // A new one will be created for future jobs. - logger.log(Level.INFO, "ELDEBUG Cancelling periodic search task"); //NON-NLS - periodicSearchTaskRunning = false; - jobProcessingTaskFuture.cancel(true); + // new jobs could have been added while we were doing final search + if (jobs.isEmpty()) { + // no more jobs left. stop the PeriodicSearchTask. + // A new one will be created for future jobs. + logger.log(Level.INFO, "Cancelling periodic search task"); //NON-NLS + periodicSearchTaskRunning = false; + jobProcessingTaskFuture.cancel(true); + } } } @@ -156,30 +157,28 @@ final class SearchRunner { * @param jobId */ public synchronized void stopJob(long jobId) { - logger.log(Level.INFO, "ELDEBUG Stopping job {0}", jobId); //NON-NLS + logger.log(Level.INFO, "Stopping job {0}", jobId); //NON-NLS commit(); SearchJobInfo job; job = jobs.get(jobId); if (job == null) { - logger.log(Level.INFO, "ELDEBUG job not found, returning {0}", jobId); //NON-NLS return; } //stop currentSearcher SearchRunner.Searcher currentSearcher = job.getCurrentSearcher(); if ((currentSearcher != null) && (!currentSearcher.isDone())) { - logger.log(Level.INFO, "ELDEBUG cancelling job {0}", jobId); //NON-NLS + logger.log(Level.INFO, "Cancelling search job {0}", jobId); //NON-NLS currentSearcher.cancel(true); } - logger.log(Level.INFO, "ELDEBUG removing job {0}", jobId); //NON-NLS jobs.remove(jobId); if (jobs.isEmpty()) { // no more jobs left. stop the PeriodicSearchTask. // A new one will be created for future jobs. - logger.log(Level.INFO, "ELDEBUG Cancelling periodic search task"); //NON-NLS + logger.log(Level.INFO, "Cancelling periodic search task"); //NON-NLS periodicSearchTaskRunning = false; jobProcessingTaskFuture.cancel(true); } @@ -259,23 +258,30 @@ final class SearchRunner { public void run() { // If no jobs then cancel the task. If more job(s) come along, a new task will start up. if (jobs.isEmpty() || jobProcessingTaskFuture.isCancelled()) { - logger.log(Level.INFO, "ELDEBUG Exiting periodic search task"); //NON-NLS + logger.log(Level.INFO, "Exiting periodic search task"); //NON-NLS periodicSearchTaskRunning = false; return; } commit(); - logger.log(Level.INFO, "ELDEBUG Starting periodic searches"); + logger.log(Level.INFO, "Starting periodic searches"); final StopWatch stopWatch = new StopWatch(); stopWatch.start(); // NOTE: contents of "jobs" ConcurrentHashMap can be modified in stopJob() and endJob() while we are inside this loop for (Iterator> iterator = jobs.entrySet().iterator(); iterator.hasNext();) { SearchJobInfo job = iterator.next().getValue(); + + if (jobProcessingTaskFuture.isCancelled()) { + logger.log(Level.INFO, "Search has been cancelled. Exiting periodic search task."); //NON-NLS + periodicSearchTaskRunning = false; + return; + } + // If no lists or the worker is already running then skip it if (!job.getKeywordListNames().isEmpty() && !job.isWorkerRunning()) { // Spawn a search thread for each job - logger.log(Level.INFO, "ELDEBUG Executing periodic search for search job {0}", job.getJobId()); + logger.log(Level.INFO, "Executing periodic search for search job {0}", job.getJobId()); Searcher searcher = new Searcher(job); // SwingWorker job.setCurrentSearcher(searcher); //save the ref searcher.execute(); //start thread @@ -294,12 +300,11 @@ final class SearchRunner { } } } - logger.log(Level.INFO, "ELDEBUG Finished periodic searches"); stopWatch.stop(); - logger.log(Level.INFO, "ELDEBUG ALL periodic searches took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS + logger.log(Level.INFO, "All periodic searches took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS // calculate "hold off" time - final long timeToTextSearchMs = getTimeToNextPeriodicSearch(defaultUpdateIntervalMs /*stopWatch.getElapsedTimeSecs()*/); // ELDEBUG + final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); // ELDEBUG // schedule next PeriodicSearchTask jobProcessingTaskFuture = jobProcessingExecutor.schedule(new PeriodicSearchTask(), timeToTextSearchMs, MILLISECONDS); @@ -316,7 +321,7 @@ final class SearchRunner { } // double the search interval defaultUpdateIntervalMs = defaultUpdateIntervalMs * 2; - logger.log(Level.WARNING, "ELDEBUG Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000}); + logger.log(Level.WARNING, "Last periodic search took {0} sec. Increasing search interval to {1} sec", new Object[]{lastSerchTimeSec, defaultUpdateIntervalMs/1000}); return defaultUpdateIntervalMs; } } From 61803a5153b26fa122e05b9c557eed741b204133 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 15:49:12 -0500 Subject: [PATCH 35/38] Polishing --- .../org/sleuthkit/autopsy/keywordsearch/SearchRunner.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index fff28a14b6..1a85adb18b 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -69,7 +69,7 @@ final class SearchRunner { private static final String SEARCH_SCHEDULER_THREAD_NAME = "periodic-search-scheduler-%d"; // maps a jobID to the search - private Map jobs = new ConcurrentHashMap<>(); //guarded by "this" + private Map jobs = new ConcurrentHashMap<>(); SearchRunner() { defaultUpdateIntervalMs = ((long) KeywordSearchSettings.getUpdateFrequency().getTime()) * 60 * 1000; @@ -248,7 +248,7 @@ final class SearchRunner { } /** - * Task triggered re-search for each job (does a single index commit first) + * Task to perform periodic searches for each job (does a single index commit first) */ private final class PeriodicSearchTask implements Runnable { @@ -296,12 +296,12 @@ final class SearchRunner { NbBundle.getMessage(this.getClass(), "SearchRunner.Searcher.done.err.msg"), ex.getMessage())); }// catch and ignore if we were cancelled - catch (java.util.concurrent.CancellationException ex) { + catch (java.util.concurrent.CancellationException ex) { } } } stopWatch.stop(); - logger.log(Level.INFO, "All periodic searches took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS + logger.log(Level.INFO, "All periodic searches cumulatively took {0} secs", stopWatch.getElapsedTimeSecs()); //NON-NLS // calculate "hold off" time final long timeToTextSearchMs = getTimeToNextPeriodicSearch(stopWatch.getElapsedTimeSecs()); // ELDEBUG From bcac53c5c361b6e25139a2dba957e847375e3125 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 16:15:16 -0500 Subject: [PATCH 36/38] Polishing --- .../org/sleuthkit/autopsy/keywordsearch/SearchRunner.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index 1a85adb18b..a0c7972dad 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -143,7 +143,7 @@ final class SearchRunner { if (jobs.isEmpty()) { // no more jobs left. stop the PeriodicSearchTask. // A new one will be created for future jobs. - logger.log(Level.INFO, "Cancelling periodic search task"); //NON-NLS + logger.log(Level.INFO, "No more search jobs. Stoppping periodic search task"); //NON-NLS periodicSearchTaskRunning = false; jobProcessingTaskFuture.cancel(true); } @@ -157,7 +157,7 @@ final class SearchRunner { * @param jobId */ public synchronized void stopJob(long jobId) { - logger.log(Level.INFO, "Stopping job {0}", jobId); //NON-NLS + logger.log(Level.INFO, "Stopping search job {0}", jobId); //NON-NLS commit(); SearchJobInfo job; @@ -178,7 +178,7 @@ final class SearchRunner { if (jobs.isEmpty()) { // no more jobs left. stop the PeriodicSearchTask. // A new one will be created for future jobs. - logger.log(Level.INFO, "Cancelling periodic search task"); //NON-NLS + logger.log(Level.INFO, "No more search jobs. Stoppping periodic search task"); //NON-NLS periodicSearchTaskRunning = false; jobProcessingTaskFuture.cancel(true); } From e96245a5a26d7ce7d335385dc615c595a3993873 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Fri, 8 Dec 2017 16:17:29 -0500 Subject: [PATCH 37/38] Polishing --- .../src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java index a0c7972dad..3ffaa01622 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/SearchRunner.java @@ -143,7 +143,7 @@ final class SearchRunner { if (jobs.isEmpty()) { // no more jobs left. stop the PeriodicSearchTask. // A new one will be created for future jobs. - logger.log(Level.INFO, "No more search jobs. Stoppping periodic search task"); //NON-NLS + logger.log(Level.INFO, "No more search jobs. Stopping periodic search task"); //NON-NLS periodicSearchTaskRunning = false; jobProcessingTaskFuture.cancel(true); } @@ -178,7 +178,7 @@ final class SearchRunner { if (jobs.isEmpty()) { // no more jobs left. stop the PeriodicSearchTask. // A new one will be created for future jobs. - logger.log(Level.INFO, "No more search jobs. Stoppping periodic search task"); //NON-NLS + logger.log(Level.INFO, "No more search jobs. Stopping periodic search task"); //NON-NLS periodicSearchTaskRunning = false; jobProcessingTaskFuture.cancel(true); } From c0861d24d97bac3e339ece9fc17216dcc1f0bff5 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 8 Dec 2017 16:25:28 -0500 Subject: [PATCH 38/38] 3287 Fixed wait cursors with use of getGlassPane() --- .../sleuthkit/autopsy/casemodule/AddImageAction.java | 11 +++++++++-- .../runIngestModuleWizard/RunIngestModulesAction.java | 10 +++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java index 1ae20d1163..860fc6dcb5 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java @@ -29,6 +29,7 @@ import java.util.logging.Level; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.RootPaneContainer; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -56,13 +57,15 @@ import org.sleuthkit.datamodel.Image; */ @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.AddImageAction") @ActionRegistration(displayName = "#CTL_AddImage", lazy = false) -@ActionReferences(value = {@ActionReference(path = "Toolbars/Case", position = 100)}) +@ActionReferences(value = { + @ActionReference(path = "Toolbars/Case", position = 100)}) @ServiceProvider(service = AddImageAction.class) public final class AddImageAction extends CallableSystemAction implements Presenter.Toolbar { private static final long serialVersionUID = 1L; private static final Dimension SIZE = new Dimension(875, 550); private final ChangeSupport cleanupSupport = new ChangeSupport(this); + // private final static MouseAdapter mouseDisabler = new MouseAdapter() {}; // Keys into the WizardDescriptor properties that pass information between stages of the wizard // : @@ -116,6 +119,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen String optionsDlgTitle = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.title"); String optionsDlgMessage = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg"); if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) { + RootPaneContainer root = (RootPaneContainer) WindowManager.getDefault().getMainWindow(); + root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + root.getGlassPane().setVisible(true); WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); iterator = new AddImageWizardIterator(this); wizardDescriptor = new WizardDescriptor(iterator); @@ -129,7 +135,8 @@ public final class AddImageAction extends CallableSystemAction implements Presen dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor); Dimension d = dialog.getSize(); dialog.setSize(SIZE); - WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + root.getGlassPane().setVisible(false); dialog.setVisible(true); dialog.toFront(); diff --git a/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java b/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java index 2f15a74c64..e97ec1e6ed 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java @@ -26,6 +26,7 @@ import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; +import javax.swing.RootPaneContainer; import org.openide.DialogDisplayer; import org.openide.WizardDescriptor; import org.openide.util.NbBundle.Messages; @@ -50,6 +51,7 @@ public final class RunIngestModulesAction extends AbstractAction { * used instead of this wizard and is retained for backwards compatibility. */ private static final String EXECUTION_CONTEXT = "org.sleuthkit.autopsy.ingest.RunIngestModulesDialog"; + /** * Display any warnings that the ingestJobSettings have. * @@ -104,12 +106,15 @@ public final class RunIngestModulesAction extends AbstractAction { * argument in the title format string will be supplied by * WizardDescriptor.Panel.getComponent().getName(). */ - WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + RootPaneContainer root = (RootPaneContainer) WindowManager.getDefault().getMainWindow(); + root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + root.getGlassPane().setVisible(true); RunIngestModulesWizardIterator wizard = new RunIngestModulesWizardIterator(EXECUTION_CONTEXT, this.ingestType, this.dataSources); WizardDescriptor wiz = new WizardDescriptor(wizard); wiz.setTitleFormat(new MessageFormat("{0}")); wiz.setTitle(Bundle.RunIngestModulesAction_name()); - WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + root.getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + root.getGlassPane().setVisible(false); if (DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) { IngestJobSettings ingestJobSettings = wizard.getIngestJobSettings(); showWarnings(ingestJobSettings); @@ -117,7 +122,6 @@ public final class RunIngestModulesAction extends AbstractAction { } } - @Override public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException("Clone is not supported for the RunIngestModulesAction");