From aac459f4b5b9f2ea79abcb9f6ace082575af5bb7 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 7 Nov 2018 13:29:32 -0500 Subject: [PATCH 01/32] Made content viewer impl new streaming sqlite class --- .../autopsy/contentviewers/SQLiteViewer.java | 285 ++++++++---------- 1 file changed, 118 insertions(+), 167 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index 9c09ca01ca..541b057d9e 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -24,18 +24,11 @@ import java.awt.Cursor; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -48,11 +41,11 @@ import org.apache.commons.io.FilenameUtils; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.coreutils.SQLiteTableReaderException; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.autopsy.coreutils.SQLiteTableReader; /** * A file content viewer for SQLite database files. @@ -66,11 +59,15 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { private static final Logger logger = Logger.getLogger(FileViewer.class.getName()); private final SQLiteTableView selectedTableView = new SQLiteTableView(); private AbstractFile sqliteDbFile; - private File tmpDbFile; - private Connection connection; + + private SQLiteTableReader viewReader; + + private Map rowMap = new LinkedHashMap<>(); + private List> chunk = new ArrayList<>(); + private int numRows; // num of rows in the selected table private int currPage = 0; // curr page of rows being displayed - + /** * Constructs a file content viewer for SQLite database files. */ @@ -264,18 +261,18 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { }//GEN-LAST:event_tablesDropdownListActionPerformed /** - * The action when the Export Csv button is pressed. The file chooser window will pop - * up to choose where the user wants to save the csv file. The default location is case export directory. + * The action when the Export Csv button is pressed. The file chooser window + * will pop up to choose where the user wants to save the csv file. The + * default location is case export directory. * * @param evt the action event */ - @NbBundle.Messages({"SQLiteViewer.csvExport.fileName.empty=Please input a file name for exporting.", - "SQLiteViewer.csvExport.title=Export to csv file", - "SQLiteViewer.csvExport.confirm.msg=Do you want to overwrite the existing file?"}) + "SQLiteViewer.csvExport.title=Export to csv file", + "SQLiteViewer.csvExport.confirm.msg=Do you want to overwrite the existing file?"}) private void exportCsvButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportCsvButtonActionPerformed Case openCase = Case.getCurrentCase(); - File caseDirectory = new File(openCase.getExportDirectory()); + File caseDirectory = new File(openCase.getExportDirectory()); JFileChooser fileChooser = new JFileChooser(); fileChooser.setDragEnabled(false); fileChooser.setCurrentDirectory(caseDirectory); @@ -292,14 +289,14 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { File file = fileChooser.getSelectedFile(); if (file.exists() && FilenameUtils.getExtension(file.getName()).equalsIgnoreCase("csv")) { if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this, - Bundle.SQLiteViewer_csvExport_confirm_msg(), - Bundle.SQLiteViewer_csvExport_title(), + Bundle.SQLiteViewer_csvExport_confirm_msg(), + Bundle.SQLiteViewer_csvExport_title(), JOptionPane.YES_NO_OPTION)) { } else { return; - } + } } - + exportTableToCsv(file); } }//GEN-LAST:event_exportCsvButtonActionPerformed @@ -328,6 +325,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { public void setFile(AbstractFile file) { WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); sqliteDbFile = file; + initReader(); processSQLiteFile(); WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } @@ -342,17 +340,10 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { tablesDropdownList.setEnabled(true); tablesDropdownList.removeAllItems(); numEntriesField.setText(""); - - // close DB connection to file - if (null != connection) { - try { - connection.close(); - connection = null; - } catch (SQLException ex) { - logger.log(Level.SEVERE, "Failed to close DB connection to file.", ex); //NON-NLS - } - } - + viewReader.close(); + rowMap = new LinkedHashMap<>(); + chunk = new ArrayList<>(); + viewReader = null; sqliteDbFile = null; } @@ -368,17 +359,10 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { "SQLiteViewer.errorMessage.failedToinitJDBCDriver=The JDBC driver for SQLite could not be loaded.", "# {0} - exception message", "SQLiteViewer.errorMessage.unexpectedError=An unexpected error occurred:\n{0).",}) private void processSQLiteFile() { - - tablesDropdownList.removeAllItems(); - try { - String localDiskPath = SqliteUtil.writeAbstractFileToLocalDisk(sqliteDbFile); - SqliteUtil.findAndCopySQLiteMetaFile(sqliteDbFile); - // Load the SQLite JDBC driver, if necessary. - Class.forName("org.sqlite.JDBC"); //NON-NLS - connection = DriverManager.getConnection("jdbc:sqlite:" + localDiskPath); //NON-NLS + tablesDropdownList.removeAllItems(); - Collection dbTablesMap = getTables(); + Collection dbTablesMap = viewReader.getTableNames(); if (dbTablesMap.isEmpty()) { tablesDropdownList.addItem(Bundle.SQLiteViewer_comboBox_noTableEntry()); tablesDropdownList.setEnabled(false); @@ -387,46 +371,20 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { tablesDropdownList.addItem(tableName); }); } - } catch (ClassNotFoundException ex) { - logger.log(Level.SEVERE, String.format("Failed to initialize JDBC SQLite '%s' (objId=%d)", sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS - MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_failedToinitJDBCDriver()); - } catch (SQLException ex) { - logger.log(Level.SEVERE, String.format("Failed to get tables from DB file '%s' (objId=%d)", sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS + } catch (SQLiteTableReaderException ex) { + logger.log(Level.WARNING, String.format("Unable to get table names " + + "from sqlite file [%s] with id=[%d].", sqliteDbFile.getName(), + sqliteDbFile.getId(), ex.getMessage())); MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_failedToQueryDatabase()); - } catch (IOException | NoCurrentCaseException | TskCoreException ex) { - logger.log(Level.SEVERE, String.format("Failed to create temp copy of DB file '%s' (objId=%d)", sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS - MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_failedToExtractFile()); } } - /** - * Gets a collection of table names from the SQLite database file. - * - * @return A collection of table names - */ - private Collection getTables() throws SQLException { - Collection tableNames = new LinkedList<>(); - try (Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery( - "SELECT name FROM sqlite_master " - + " WHERE type= 'table' ")){ - while (resultSet.next()) { - tableNames.add(resultSet.getString("name")); //NON-NLS - } - } - return tableNames; - } - @NbBundle.Messages({"# {0} - tableName", "SQLiteViewer.selectTable.errorText=Error getting row count for table: {0}" }) private void selectTable(String tableName) { - - try (Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery( - "SELECT count (*) as count FROM " + "\"" + tableName + "\"")) { //NON-NLS{ - - numRows = resultSet.getInt("count"); + try { + numRows = viewReader.getRowCount(tableName); numEntriesField.setText(numRows + " entries"); currPage = 1; @@ -444,120 +402,113 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { nextPageButton.setEnabled(false); selectedTableView.setupTable(Collections.emptyList()); } - - } catch (SQLException ex) { - logger.log(Level.SEVERE, String.format("Failed to load table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS + } catch (SQLiteTableReaderException ex) { + logger.log(Level.WARNING, String.format("Failed to load table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_selectTable_errorText(tableName)); } } + private String prevTableName; @NbBundle.Messages({"# {0} - tableName", "SQLiteViewer.readTable.errorText=Error getting rows for table: {0}"}) private void readTable(String tableName, int startRow, int numRowsToRead) { - - try ( - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery( - "SELECT * FROM " + "\"" + tableName + "\"" - + " LIMIT " + Integer.toString(numRowsToRead) - + " OFFSET " + Integer.toString(startRow - 1))) { - - List> rows = resultSetToArrayList(resultSet); - if (Objects.nonNull(rows)) { - selectedTableView.setupTable(rows); - } else { - selectedTableView.setupTable(Collections.emptyList()); + try { + if(!tableName.equals(prevTableName)) { + prevTableName = tableName; + header = new ArrayList<>(); + rowIndex = 0; } - } catch (SQLException ex) { - logger.log(Level.SEVERE, String.format("Failed to read table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS + viewReader.read(tableName, numRowsToRead, startRow - 1); + selectedTableView.setupTable(chunk); + chunk = new ArrayList<>(); + } catch (SQLiteTableReaderException ex) { + logger.log(Level.WARNING, String.format("Failed to read table %s from DB file '%s' " //NON-NLS + + "(objId=%d) starting at row [%d] and limit [%d]", //NON-NLS + tableName, sqliteDbFile.getName(), sqliteDbFile.getId(), startRow - 1, numRowsToRead), ex.getMessage()); MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_readTable_errorText(tableName)); } } - @NbBundle.Messages("SQLiteViewer.BlobNotShown.message=BLOB Data not shown") - private List> resultSetToArrayList(ResultSet resultSet) throws SQLException { - ResultSetMetaData metaData = resultSet.getMetaData(); - int columns = metaData.getColumnCount(); - ArrayList> rowlist = new ArrayList<>(); - while (resultSet.next()) { - Map row = new LinkedHashMap<>(columns); - for (int i = 1; i <= columns; ++i) { - if (resultSet.getObject(i) == null) { - row.put(metaData.getColumnName(i), ""); - } else { - if (metaData.getColumnTypeName(i).compareToIgnoreCase("blob") == 0) { - row.put(metaData.getColumnName(i), Bundle.SQLiteViewer_BlobNotShown_message()); - } else { - row.put(metaData.getColumnName(i), resultSet.getObject(i)); - } - } - } - rowlist.add(row); - } + List header; + private int rowIndex; + private void initReader() { + viewReader = new SQLiteTableReader.Builder(sqliteDbFile) + .onColumnNames((columnName) -> { + header.add(columnName); + }) + .forAll((Object o) -> { + rowIndex++; + String objectStr = (o instanceof byte[]) ? "BLOB Data not shown" : Objects.toString(o, ""); - return rowlist; + rowMap.put(header.get(rowIndex - 1), objectStr); + //If this result is at the end of a row, then add it to the + //chunk! + if (rowIndex == header.size()) { + chunk.add(rowMap); + rowMap = new LinkedHashMap<>(); + } + rowIndex %= header.size(); + }).build(); } + + private int csvRowIndex; + private int columnCount; + private boolean afterHeader; @NbBundle.Messages({"SQLiteViewer.exportTableToCsv.write.errText=Failed to export table content to csv file.", - "SQLiteViewer.exportTableToCsv.FileName=File name: ", - "SQLiteViewer.exportTableToCsv.TableName=Table name: " + "SQLiteViewer.exportTableToCsv.FileName=File name: ", + "SQLiteViewer.exportTableToCsv.TableName=Table name: " }) private void exportTableToCsv(File file) { + csvRowIndex = 0; + columnCount = 0; + afterHeader = true; + File csvFile = new File(file.toString() + ".csv"); String tableName = (String) this.tablesDropdownList.getSelectedItem(); - try ( - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery("SELECT * FROM " + "\"" + tableName + "\"")) { - List> currentTableRows = resultSetToArrayList(resultSet); - - if (Objects.isNull(currentTableRows) || currentTableRows.isEmpty()) { - logger.log(Level.INFO, String.format("The table %s is empty. (objId=%d)", tableName, sqliteDbFile.getId())); //NON-NLS - } else { - File csvFile; - String fileName = file.getName(); - if (FilenameUtils.getExtension(fileName).equalsIgnoreCase("csv")) { - csvFile = file; - } else { - csvFile = new File(file.toString() + ".csv"); - } - - try (FileOutputStream out = new FileOutputStream(csvFile, false)) { - - out.write((Bundle.SQLiteViewer_exportTableToCsv_FileName() + csvFile.getName() + "\n").getBytes()); - out.write((Bundle.SQLiteViewer_exportTableToCsv_TableName() + tableName + "\n").getBytes()); - // Set up the column names - Map row = currentTableRows.get(0); - StringBuffer header = new StringBuffer(); - for (Map.Entry col : row.entrySet()) { - String colName = col.getKey(); - if (header.length() > 0) { - header.append(',').append(colName); - } else { - header.append(colName); - } - } - out.write(header.append('\n').toString().getBytes()); - - for (Map maps : currentTableRows) { - StringBuffer valueLine = new StringBuffer(); - maps.values().forEach((value) -> { - if (valueLine.length() > 0) { - valueLine.append(',').append(value.toString()); - } else { - valueLine.append(value.toString()); + try (FileOutputStream out = new FileOutputStream(csvFile, false)) { + try (SQLiteTableReader sqliteStream = new SQLiteTableReader.Builder(sqliteDbFile) + .onColumnNames((columnName) -> { + columnCount++; + try { + if(columnCount == 1) { + columnName = "\"" + columnName + "\""; + } else { + columnName = ",\"" + columnName + "\""; } - }); - out.write(valueLine.append('\n').toString().getBytes()); - } - } + out.write(columnName.getBytes()); + } catch (IOException ex) { + + } + }).forAll((Object o) -> { + csvRowIndex++; + String objectStr = (o instanceof byte[]) ? "BLOB Data not shown" : Objects.toString(o, ""); + objectStr = "\"" + objectStr + "\""; + + if (csvRowIndex > 1) { + objectStr = "," + objectStr; + } if(csvRowIndex == columnCount) { + objectStr += "\n"; + } + + if(afterHeader) { + objectStr = "\n" + objectStr; + afterHeader = false; + } + + try { + out.write(objectStr.getBytes()); + } catch (IOException ex) { + + } + csvRowIndex = csvRowIndex % columnCount; + }).build()) { + sqliteStream.read(tableName); } - } catch (SQLException ex) { - logger.log(Level.SEVERE, String.format("Failed to read table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS - MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_readTable_errorText(tableName)); - } catch (IOException ex) { - logger.log(Level.SEVERE, String.format("Failed to export table %s to file '%s'", tableName, file.getName()), ex); //NON-NLS + } catch (IOException | SQLiteTableReaderException ex) { + logger.log(Level.WARNING, String.format("Failed to export table [%s]" + + " to CSV in sqlite file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), + sqliteDbFile.getId()), ex.getMessage()); //NON-NLS MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_exportTableToCsv_write_errText()); } } - - } From ac4565f42fbfbfd9756758012e0ddc8c9c28dfb7 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 8 Nov 2018 11:27:42 -0500 Subject: [PATCH 02/32] Refactored some code to make it more readable and added comments --- .../autopsy/contentviewers/SQLiteViewer.java | 230 ++++++++++++------ 1 file changed, 160 insertions(+), 70 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index 541b057d9e..6de21f9ec0 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -32,6 +32,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.function.Consumer; import java.util.logging.Level; import javax.swing.JComboBox; import javax.swing.JFileChooser; @@ -62,12 +63,14 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { private SQLiteTableReader viewReader; - private Map rowMap = new LinkedHashMap<>(); - private List> chunk = new ArrayList<>(); + private Map row = new LinkedHashMap<>(); + private List> pageOfTableRows = new ArrayList<>(); + private List currentTableHeader = new ArrayList<>(); + private String prevTableName; private int numRows; // num of rows in the selected table private int currPage = 0; // curr page of rows being displayed - + /** * Constructs a file content viewer for SQLite database files. */ @@ -340,9 +343,11 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { tablesDropdownList.setEnabled(true); tablesDropdownList.removeAllItems(); numEntriesField.setText(""); + viewReader.close(); - rowMap = new LinkedHashMap<>(); - chunk = new ArrayList<>(); + row = new LinkedHashMap<>(); + pageOfTableRows = new ArrayList<>(); + currentTableHeader = new ArrayList<>(); viewReader = null; sqliteDbFile = null; } @@ -408,19 +413,20 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { } } - private String prevTableName; @NbBundle.Messages({"# {0} - tableName", "SQLiteViewer.readTable.errorText=Error getting rows for table: {0}"}) private void readTable(String tableName, int startRow, int numRowsToRead) { try { - if(!tableName.equals(prevTableName)) { + //If the table name has changed, then clear our table header. SQLiteTableReader + //will also detect the table name has changed and begin reading it as if it + //were a brand new table. + if (!tableName.equals(prevTableName)) { prevTableName = tableName; - header = new ArrayList<>(); - rowIndex = 0; + currentTableHeader = new ArrayList<>(); } viewReader.read(tableName, numRowsToRead, startRow - 1); - selectedTableView.setupTable(chunk); - chunk = new ArrayList<>(); + selectedTableView.setupTable(pageOfTableRows); + pageOfTableRows = new ArrayList<>(); } catch (SQLiteTableReaderException ex) { logger.log(Level.WARNING, String.format("Failed to read table %s from DB file '%s' " //NON-NLS + "(objId=%d) starting at row [%d] and limit [%d]", //NON-NLS @@ -429,86 +435,170 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { } } - List header; - private int rowIndex; + /** + * Creates a new SQLiteTableReader. This class will iterate through the + * table row by row and pass each value to the correct function based on its + * data type. For our use, we want to define an action when encountering + * column names and an action for all other data types. + */ private void initReader() { viewReader = new SQLiteTableReader.Builder(sqliteDbFile) .onColumnNames((columnName) -> { - header.add(columnName); + currentTableHeader.add(columnName); }) - .forAll((Object o) -> { - rowIndex++; - String objectStr = (o instanceof byte[]) ? "BLOB Data not shown" : Objects.toString(o, ""); - - rowMap.put(header.get(rowIndex - 1), objectStr); - //If this result is at the end of a row, then add it to the - //chunk! - if (rowIndex == header.size()) { - chunk.add(rowMap); - rowMap = new LinkedHashMap<>(); - } - rowIndex %= header.size(); - }).build(); + .forAll(getForAllStrategy()).build(); } - private int csvRowIndex; - private int columnCount; - private boolean afterHeader; - + /** + * For every database value we encounter on our read of the table do the + * following: 1) Get the string representation of the value 2) Collect the + * values until we have a full database row. 3) If we have the full row, + * write it to the UI. + * + * rowIndex is purely for indicating if we have read the full row. + * + * @return Consumer that will perform the actions above. When the + * SQLiteTableReader is reading, values will be passed to this + * consumer. + */ + private Consumer getForAllStrategy() { + return new Consumer() { + private int rowIndex = 0; + + @Override + public void accept(Object t) { + rowIndex++; + String objectStr = (t instanceof byte[]) ? "BLOB Data not shown" + : Objects.toString(t, ""); + + row.put(currentTableHeader.get(rowIndex - 1), objectStr); + + if (rowIndex == currentTableHeader.size()) { + pageOfTableRows.add(row); + row = new LinkedHashMap<>(); + } + rowIndex %= currentTableHeader.size(); + } + + }; + } + + private int totalColumnCount; + @NbBundle.Messages({"SQLiteViewer.exportTableToCsv.write.errText=Failed to export table content to csv file.", "SQLiteViewer.exportTableToCsv.FileName=File name: ", "SQLiteViewer.exportTableToCsv.TableName=Table name: " }) private void exportTableToCsv(File file) { - csvRowIndex = 0; - columnCount = 0; - afterHeader = true; File csvFile = new File(file.toString() + ".csv"); String tableName = (String) this.tablesDropdownList.getSelectedItem(); try (FileOutputStream out = new FileOutputStream(csvFile, false)) { try (SQLiteTableReader sqliteStream = new SQLiteTableReader.Builder(sqliteDbFile) - .onColumnNames((columnName) -> { - columnCount++; - try { - if(columnCount == 1) { - columnName = "\"" + columnName + "\""; - } else { - columnName = ",\"" + columnName + "\""; - } - out.write(columnName.getBytes()); - } catch (IOException ex) { - - } - }).forAll((Object o) -> { - csvRowIndex++; - String objectStr = (o instanceof byte[]) ? "BLOB Data not shown" : Objects.toString(o, ""); - objectStr = "\"" + objectStr + "\""; - - if (csvRowIndex > 1) { - objectStr = "," + objectStr; - } if(csvRowIndex == columnCount) { - objectStr += "\n"; - } - - if(afterHeader) { - objectStr = "\n" + objectStr; - afterHeader = false; - } - - try { - out.write(objectStr.getBytes()); - } catch (IOException ex) { - - } - csvRowIndex = csvRowIndex % columnCount; - }).build()) { + .onColumnNames(getColumnNameCSVStrategy(out)) + .forAll(getForAllCSVStrategy(out)).build()) { + totalColumnCount = sqliteStream.getColumnCount(tableName); sqliteStream.read(tableName); } - } catch (IOException | SQLiteTableReaderException ex) { + } catch (IOException | SQLiteTableReaderException | RuntimeException ex) { logger.log(Level.WARNING, String.format("Failed to export table [%s]" + " to CSV in sqlite file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex.getMessage()); //NON-NLS MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_exportTableToCsv_write_errText()); } } + + /** + * For every column name we encounter on our read of the table do the + * following: 1) Format the name so that it is comma seperated 2) Write the + * value to the output stream. + * + * columnIndex is purely for keeping track of where the column name is in + * the table so the value can be correctly formatted. + * + * @param out Output stream that this database table is being written to. + * + * @return Consumer that will perform the actions above. When the + * SQLiteTableReader is reading, values will be passed to this + * consumer. + */ + private Consumer getColumnNameCSVStrategy(FileOutputStream out) { + return new Consumer() { + private int columnIndex = 0; + + @Override + public void accept(String columnName) { + columnIndex++; + + if (columnIndex == 1) { + columnName = "\"" + columnName + "\""; + } else { + columnName = ",\"" + columnName + "\""; + } + + if (columnIndex == totalColumnCount) { + columnName += "\n"; + } + + try { + out.write(columnName.getBytes()); + } catch (IOException ex) { + /* + * If we can no longer write to the output stream, toss a + * runtime exception to get out of iteration. We explicitly + * catch this in exportTableToCsv() above. + */ + throw new RuntimeException(ex); + } + } + }; + } + + /** + * For every database value we encounter on our read of the table do the + * following: 1) Get the string representation of the value 2) Format it so + * that it adheres to the CSV format. 3) Write it to the output file. + * + * rowIndex is purely for keeping track of positioning of the database value + * in the row, so that it can be properly formatted. + * + * @param out Output file + * + * @return Consumer that will perform the actions above. When the + * SQLiteTableReader is reading, values will be passed to this + * consumer. + */ + private Consumer getForAllCSVStrategy(FileOutputStream out) { + return new Consumer() { + private int rowIndex = 0; + + @Override + public void accept(Object tableValue) { + rowIndex++; + //Substitute string representation of blob with placeholder text. + //Automatically wrap the value in quotes in case it contains commas. + String objectStr = (tableValue instanceof byte[]) + ? "BLOB Data not shown" : Objects.toString(tableValue, ""); + objectStr = "\"" + objectStr + "\""; + + if (rowIndex > 1) { + objectStr = "," + objectStr; + } + if (rowIndex == totalColumnCount) { + objectStr += "\n"; + } + + try { + out.write(objectStr.getBytes()); + } catch (IOException ex) { + /* + * If we can no longer write to the output stream, toss a + * runtime exception to get out of iteration. We explicitly + * catch this in exportTableToCsv() above. + */ + throw new RuntimeException(ex); + } + rowIndex = rowIndex % totalColumnCount; + } + }; + } } From 03e851a341dd6762e5b533890e51f99ea21d41da Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 8 Nov 2018 11:31:58 -0500 Subject: [PATCH 03/32] Deleted SqliteUtil and fixed a log message --- .../autopsy/contentviewers/SQLiteViewer.java | 7 +- .../autopsy/contentviewers/SqliteUtil.java | 130 ------------------ 2 files changed, 5 insertions(+), 132 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/contentviewers/SqliteUtil.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index 6de21f9ec0..e96a538580 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -408,7 +408,9 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { selectedTableView.setupTable(Collections.emptyList()); } } catch (SQLiteTableReaderException ex) { - logger.log(Level.WARNING, String.format("Failed to load table %s from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex); //NON-NLS + logger.log(Level.WARNING, String.format("Failed to load table %s " //NON-NLS + + "from DB file '%s' (objId=%d)", tableName, sqliteDbFile.getName(), //NON-NLS + sqliteDbFile.getId()), ex.getMessage()); MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_selectTable_errorText(tableName)); } } @@ -430,7 +432,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { } catch (SQLiteTableReaderException ex) { logger.log(Level.WARNING, String.format("Failed to read table %s from DB file '%s' " //NON-NLS + "(objId=%d) starting at row [%d] and limit [%d]", //NON-NLS - tableName, sqliteDbFile.getName(), sqliteDbFile.getId(), startRow - 1, numRowsToRead), ex.getMessage()); + tableName, sqliteDbFile.getName(), sqliteDbFile.getId(), + startRow - 1, numRowsToRead), ex.getMessage()); MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_readTable_errorText(tableName)); } } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SqliteUtil.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SqliteUtil.java deleted file mode 100755 index 4fc220cf0d..0000000000 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SqliteUtil.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018-2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.contentviewers; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.casemodule.services.FileManager; -import org.sleuthkit.autopsy.casemodule.services.Services; -import org.sleuthkit.autopsy.datamodel.ContentUtils; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Sqlite utility class. Find and copy metafiles, write sqlite abstract files to - * temp directory, and generate unique temp directory paths. - */ -final class SqliteUtil { - - private SqliteUtil() { - - } - - /** - * Overloaded implementation of - * {@link #findAndCopySQLiteMetaFile(AbstractFile, String) findAndCopySQLiteMetaFile} - * , automatically tries to copy -wal and -shm files without needing to know - * their existence. - * - * @param sqliteFile file which has -wal and -shm meta files - * - * @throws NoCurrentCaseException Case has been closed. - * @throws TskCoreException fileManager cannot find AbstractFile - * files. - * @throws IOException Issue during writing to file. - */ - public static void findAndCopySQLiteMetaFile(AbstractFile sqliteFile) - throws NoCurrentCaseException, TskCoreException, IOException { - - findAndCopySQLiteMetaFile(sqliteFile, sqliteFile.getName() + "-wal"); - findAndCopySQLiteMetaFile(sqliteFile, sqliteFile.getName() + "-shm"); - } - - /** - * Searches for a meta file associated with the give SQLite database. If - * found, it copies this file into the temp directory of the current case. - * - * @param sqliteFile file being processed - * @param metaFileName name of meta file to look for - * - * @throws NoCurrentCaseException Case has been closed. - * @throws TskCoreException fileManager cannot find AbstractFile - * files. - * @throws IOException Issue during writing to file. - */ - public static void findAndCopySQLiteMetaFile(AbstractFile sqliteFile, - String metaFileName) throws NoCurrentCaseException, TskCoreException, IOException { - - Case openCase = Case.getCurrentCaseThrows(); - SleuthkitCase sleuthkitCase = openCase.getSleuthkitCase(); - Services services = new Services(sleuthkitCase); - FileManager fileManager = services.getFileManager(); - - List metaFiles = fileManager.findFiles( - sqliteFile.getDataSource(), metaFileName, - sqliteFile.getParent().getName()); - - if (metaFiles != null) { - for (AbstractFile metaFile : metaFiles) { - writeAbstractFileToLocalDisk(metaFile); - } - } - } - - /** - * Copies the file contents into a unique path in the current case temp - * directory. - * - * @param file AbstractFile from the data source - * - * @return The path of the file on disk - * - * @throws IOException Exception writing file contents - * @throws NoCurrentCaseException Current case closed during file copying - */ - public static String writeAbstractFileToLocalDisk(AbstractFile file) - throws IOException, NoCurrentCaseException { - - String localDiskPath = getUniqueTempDirectoryPath(file); - File localDatabaseFile = new File(localDiskPath); - if (!localDatabaseFile.exists()) { - ContentUtils.writeToFile(file, localDatabaseFile); - } - return localDiskPath; - } - - /** - * Generates a unique local disk path that resides in the temp directory of - * the current case. - * - * @param file The database abstract file - * - * @return Unique local disk path living in the temp directory of the case - * - * @throws org.sleuthkit.autopsy.casemodule.NoCurrentCaseException - */ - public static String getUniqueTempDirectoryPath(AbstractFile file) throws NoCurrentCaseException { - return Case.getCurrentCaseThrows().getTempDirectory() - + File.separator + file.getId() + file.getName(); - } -} From b4cf1a0470bdd8c3fc84e56d8d63af294844366e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 8 Nov 2018 11:36:07 -0500 Subject: [PATCH 04/32] Added a few more comments --- .../org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index e96a538580..e41fbd1eef 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -432,7 +432,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { } catch (SQLiteTableReaderException ex) { logger.log(Level.WARNING, String.format("Failed to read table %s from DB file '%s' " //NON-NLS + "(objId=%d) starting at row [%d] and limit [%d]", //NON-NLS - tableName, sqliteDbFile.getName(), sqliteDbFile.getId(), + tableName, sqliteDbFile.getName(), sqliteDbFile.getId(), startRow - 1, numRowsToRead), ex.getMessage()); MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_readTable_errorText(tableName)); } @@ -476,6 +476,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { row.put(currentTableHeader.get(rowIndex - 1), objectStr); + //If we have built up a full database row, then add it to our page + //of rows to be displayed in the UI. if (rowIndex == currentTableHeader.size()) { pageOfTableRows.add(row); row = new LinkedHashMap<>(); @@ -532,12 +534,12 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { public void accept(String columnName) { columnIndex++; + //Format the value to adhere to the format of a CSV file if (columnIndex == 1) { columnName = "\"" + columnName + "\""; } else { columnName = ",\"" + columnName + "\""; } - if (columnIndex == totalColumnCount) { columnName += "\n"; } From 5a2de8a02cbf6fbfdc35c402af6fa74add069d2d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 8 Nov 2018 12:27:51 -0500 Subject: [PATCH 05/32] Bug fix on empty table display --- Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index 3706b92b92..28a719a855 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -406,6 +406,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { exportCsvButton.setEnabled(false); nextPageButton.setEnabled(false); + currentTableHeader = new ArrayList<>(); viewReader.read(tableName); Map columnRow = new LinkedHashMap<>(); for(int i = 0; i< currentTableHeader.size(); i++){ From 711ed7a3882ea68e2398413e70c67963c21c775d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 8 Nov 2018 14:29:39 -0500 Subject: [PATCH 06/32] Close now throws exception, so had to wrap it here --- .../org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index 28a719a855..bce1eb9c7e 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -344,7 +344,11 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { tablesDropdownList.removeAllItems(); numEntriesField.setText(""); - viewReader.close(); + try { + viewReader.close(); + } catch (SQLiteTableReaderException ex) { + //Could not successfully close the reader, nothing we can do to recover. + } row = new LinkedHashMap<>(); pageOfTableRows = new ArrayList<>(); currentTableHeader = new ArrayList<>(); From f0998c7a02cd1fd5b571ef4c92e14994dd633e91 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 8 Nov 2018 14:45:57 -0500 Subject: [PATCH 07/32] Fixed a bug with clicking the same table name --- Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java index bce1eb9c7e..f2db7c2532 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java @@ -435,8 +435,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer { //were a brand new table. if (!tableName.equals(prevTableName)) { prevTableName = tableName; - currentTableHeader = new ArrayList<>(); } + currentTableHeader = new ArrayList<>(); viewReader.read(tableName, numRowsToRead, startRow - 1); selectedTableView.setupTable(pageOfTableRows); pageOfTableRows = new ArrayList<>(); From b01596afc9cf834b6acf8b5c352d237c60494881 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 8 Nov 2018 16:42:04 -0500 Subject: [PATCH 08/32] 4361 add datasource_id column --- .../datamodel/AbstractSqlEamDb.java | 14 +++++++++++--- .../datamodel/PostgresEamDbSettings.java | 1 + .../datamodel/SqliteEamDbSettings.java | 1 + 3 files changed, 13 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 c350e2f441..08e9089276 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -3217,7 +3217,7 @@ abstract class AbstractSqlEamDb implements EamDb { if (dbSchemaVersion.compareTo(new CaseDbSchemaVersionNumber(1, 2)) < 0) { EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); - final String addObjectIdColumnTemplate = "ALTER TABLE %s ADD COLUMN object_id INTEGER;"; //NON-NLS + final String addIntegerColumnTemplate = "ALTER TABLE %s ADD COLUMN %s INTEGER;"; //NON-NLS final String addSsidTableTemplate; final String addCaseIdIndexTemplate; final String addDataSourceIdIndexTemplate; @@ -3249,11 +3249,19 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded."); } String instance_type_dbname; + final String dataSourcesTableName = "data_sources"; + final String dataSourceIdColumnName = "data_source_id"; + if (!doesColumnExist(conn, dataSourcesTableName, dataSourceIdColumnName)) { + statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceIdColumnName)); //NON-NLS + } + //WJS-TODO add index on datasource id column + //add object_id column to existing _instances table + final String objectIdColumnName = "object_id"; for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) { instance_type_dbname = EamDbUtil.correlationTypeToInstanceTableName(type); - if (!doesColumnExist(conn, instance_type_dbname, "object_id")) { - statement.execute(String.format(addObjectIdColumnTemplate, instance_type_dbname)); //NON-NLS + if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) { + statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName)); //NON-NLS } statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname)); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java index a3e3ba196a..bdc00be35b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java @@ -344,6 +344,7 @@ public final class PostgresEamDbSettings { createDataSourcesTable.append("case_id integer NOT NULL,"); createDataSourcesTable.append("device_id text NOT NULL,"); createDataSourcesTable.append("name text NOT NULL,"); + createDataSourcesTable.append("datasource_id integer,"); createDataSourcesTable.append("foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"); createDataSourcesTable.append("CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name)"); createDataSourcesTable.append(")"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java index 2ead0cd4f3..b806dba3b6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java @@ -287,6 +287,7 @@ public final class SqliteEamDbSettings { createDataSourcesTable.append("case_id integer NOT NULL,"); createDataSourcesTable.append("device_id text NOT NULL,"); createDataSourcesTable.append("name text NOT NULL,"); + createDataSourcesTable.append("datasource_id integer,"); createDataSourcesTable.append("foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"); createDataSourcesTable.append("CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name)"); createDataSourcesTable.append(")"); From ed249c4e284f872519d85f94a9ba30a69189d75b Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 9 Nov 2018 14:36:27 -0500 Subject: [PATCH 09/32] 4361 populate datasource_id column in central repository --- .../datamodel/AbstractSqlEamDb.java | 22 ++++++++++--------- .../datamodel/CorrelationDataSource.java | 20 +++++++++++++---- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 08e9089276..2fe6933969 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -593,7 +593,7 @@ abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; - String sql = "INSERT INTO data_sources(device_id, case_id, name) VALUES (?, ?, ?) " + String sql = "INSERT INTO data_sources(device_id, case_id, name, datasource_id) VALUES (?, ?, ?, ?) " + getConflictClause(); ResultSet resultSet = null; try { @@ -602,6 +602,7 @@ abstract class AbstractSqlEamDb implements EamDb { preparedStatement.setString(1, eamDataSource.getDeviceID()); preparedStatement.setInt(2, eamDataSource.getCaseID()); preparedStatement.setString(3, eamDataSource.getName()); + preparedStatement.setLong(4, eamDataSource.getCaseDataSourceID()); preparedStatement.executeUpdate(); resultSet = preparedStatement.getGeneratedKeys(); @@ -609,7 +610,7 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException(String.format("Failed to INSERT data source %s in central repo", eamDataSource.getName())); } int dataSourceId = resultSet.getInt(1); //last_insert_rowid() - CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName()); + CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getCaseDataSourceID()); dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(dataSource.getCaseID(), dataSource.getDeviceID()), dataSource); dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource); } catch (SQLException ex) { @@ -904,7 +905,7 @@ abstract class AbstractSqlEamDb implements EamDb { + ".value," + tableName + ".object_id," - + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM " + + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -969,7 +970,7 @@ abstract class AbstractSqlEamDb implements EamDb { + ".value," + tableName + ".object_id," - + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM " + + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -1237,7 +1238,7 @@ abstract class AbstractSqlEamDb implements EamDb { + tableName + " (case_id, data_source_id, value, file_path, known_status, comment, object_id) " + "VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), " - + "(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) " + + "(SELECT id FROM data_sources WHERE datasource_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) " + getConflictClause(); bulkPs = conn.prepareStatement(sql); @@ -1271,7 +1272,7 @@ abstract class AbstractSqlEamDb implements EamDb { if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) { bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID()); - bulkPs.setString(2, eamArtifact.getCorrelationDataSource().getDeviceID()); + bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getCaseDataSourceID()); bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID()); bulkPs.setString(4, eamArtifact.getCorrelationValue()); bulkPs.setString(5, eamArtifact.getFilePath()); @@ -1708,7 +1709,7 @@ abstract class AbstractSqlEamDb implements EamDb { + ".value, " + tableName + ".object_id," - + "cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id FROM " + + "cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -1765,7 +1766,7 @@ abstract class AbstractSqlEamDb implements EamDb { String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); String sql - = "SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, id, value, object_id FROM " + = "SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, id, value, object_id, data_sources.datasource_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -3047,7 +3048,8 @@ abstract class AbstractSqlEamDb implements EamDb { resultSet.getInt("case_id"), resultSet.getInt("id"), resultSet.getString("device_id"), - resultSet.getString("name") + resultSet.getString("name"), + resultSet.getLong("datasource_id") ); return eamDataSource; @@ -3088,7 +3090,7 @@ abstract class AbstractSqlEamDb implements EamDb { resultSet.getString("value"), resultSet.getInt("id"), new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), - new CorrelationDataSource(resultSet.getInt("case_id"), resultSet.getInt("data_source_id"), resultSet.getString("device_id"), resultSet.getString("name")), + new CorrelationDataSource(resultSet.getInt("case_id"), resultSet.getInt("data_source_id"), resultSet.getString("device_id"), resultSet.getString("name"), resultSet.getLong("datasource_id")), resultSet.getString("file_path"), resultSet.getString("comment"), TskData.FileKnown.valueOf(resultSet.getByte("known_status")), diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java index 84dce834a1..68ef26ff7d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java @@ -36,6 +36,7 @@ public class CorrelationDataSource implements Serializable { private final int caseID; //the value in the id column of the case table in the central repo private final int dataSourceID; //< Id in the central repo + private final Long caseDataSourceID; //< Id for data source in the caseDB private final String deviceID; //< Unique to its associated case (not necessarily globally unique) private final String name; @@ -44,8 +45,8 @@ public class CorrelationDataSource implements Serializable { * @param deviceId User specified case-specific ID * @param name Display name of data source */ - public CorrelationDataSource(CorrelationCase correlationCase, String deviceId, String name) { - this(correlationCase.getID(), -1, deviceId, name); + public CorrelationDataSource(CorrelationCase correlationCase, String deviceId, String name, long caseDataSourceId) { + this(correlationCase.getID(), -1, deviceId, name, caseDataSourceId); } /** @@ -58,11 +59,13 @@ public class CorrelationDataSource implements Serializable { CorrelationDataSource(int caseId, int dataSourceId, String deviceId, - String name) { + String name, + Long caseDataSourceId) { this.caseID = caseId; this.dataSourceID = dataSourceId; this.deviceID = deviceId; this.name = name; + this.caseDataSourceID = caseDataSourceId; } /** @@ -97,7 +100,7 @@ public class CorrelationDataSource implements Serializable { correlationDataSource = EamDb.getInstance().getDataSource(correlationCase, deviceId); } if (correlationDataSource == null) { - correlationDataSource = new CorrelationDataSource(correlationCase, deviceId, dataSource.getName()); + correlationDataSource = new CorrelationDataSource(correlationCase, deviceId, dataSource.getName(), dataSource.getId()); if (EamDbUtil.useCentralRepo()) { EamDb.getInstance().newDataSource(correlationDataSource); } @@ -143,6 +146,15 @@ public class CorrelationDataSource implements Serializable { public int getCaseID() { return caseID; } + + /** + * Get the id for the data source in the case db + * + * @return caseDataSourceID or NULL if not available + */ + Long getCaseDataSourceID(){ + return caseDataSourceID; + } /** * @return the name From 5c7fdf4b712db6144abcc1217fea23628f8a5285 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 12 Nov 2018 09:03:05 -0500 Subject: [PATCH 10/32] Did some codacy suggestions --- .../autopsy/coreutils/SQLiteTableReader.java | 163 ++++++++---------- .../coreutils/SQLiteTableReaderException.java | 12 +- 2 files changed, 78 insertions(+), 97 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java index 94306fa258..44a9696eae 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java @@ -41,30 +41,30 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Reads row by row through SQLite tables and performs user-defined actions on the row values. - * Table values are processed by data type. Users configure these actions for certain data types - * in the Builder. Example usage: + * Reads row by row through SQLite tables and performs user-defined actions on + * the row values. Table values are processed by data type. Users configure + * these actions for certain data types in the Builder. Example usage: + * + * SQLiteTableReader reader = new SQLiteTableReader.Builder(file) + * .onInteger((i) + * -> { System.out.println(i); }) + * .build(); * - * SQLiteTableReader reader = new SQLiteTableReader.Builder(file) - * .onInteger((i) -> { - * System.out.println(i); - * }).build(); - * reader.read(tableName); + * reader.read(tableName); + * + * or + * + * SQLiteTableReader reader = new SQLiteTableReader.Builder(file) + * .onInteger(new Consumer() { + * @Override public void accept(Integer i) { + * System.out.println(i); + * } + * }).build(); * - * or - * - * SQLiteTableReader reader = new SQLiteTableReader.Builder(file) - * .onInteger(new Consumer() { - * @Override - * public void accept(Integer i) { - * System.out.println(i); - * } - * }).build(); - * reader.reader(tableName); - * - * Invocation of read(String tableName) causes that table name to be processed row by row. - * When an Integer is encountered, its value will be passed to the Consumer that - * was defined above. + * reader.reader(tableName); + * + * Invocation of read(String tableName) reads row by row. When an Integer is + * encountered, its value will be passed to the Consumer that was defined above. */ public class SQLiteTableReader implements AutoCloseable { @@ -74,14 +74,18 @@ public class SQLiteTableReader implements AutoCloseable { public static class Builder { private final AbstractFile file; + private Consumer onColumnNameAction; - private Consumer onStringAction; private Consumer onLongAction; private Consumer onIntegerAction; private Consumer onFloatAction; private Consumer onBlobAction; private Consumer forAllAction; + + static Consumer doNothing() { + return NOOP -> {}; + } /** * Creates a Builder for this abstract file. @@ -90,6 +94,14 @@ public class SQLiteTableReader implements AutoCloseable { */ public Builder(AbstractFile file) { this.file = file; + + this.onColumnNameAction = Builder.doNothing(); + this.onStringAction = Builder.doNothing(); + this.onLongAction = Builder.doNothing(); + this.onIntegerAction = Builder.doNothing(); + this.onFloatAction = Builder.doNothing(); + this.onBlobAction = Builder.doNothing(); + this.forAllAction = Builder.doNothing(); } /** @@ -196,61 +208,32 @@ public class SQLiteTableReader implements AutoCloseable { } private final AbstractFile file; + private final Builder builder; + + private final String SELECT_ALL_QUERY = "SELECT * FROM \"%s\""; private Connection conn; private PreparedStatement statement; private ResultSet queryResults; + private ResultSetMetaData currentMetadata; - private final Consumer onColumnNameAction; - private final Consumer onStringAction; - private final Consumer onLongAction; - private final Consumer onIntegerAction; - private final Consumer onFloatAction; - private final Consumer onBlobAction; - private final Consumer forAllAction; - - //Iteration state variables + //Iteration state private int currRowColumnIndex; private int columnNameIndex; private int totalColumnCount; private boolean unfinishedRow; - private ResultSetMetaData currentMetadata; - private boolean liveResultSet; private String prevTableName; /** - * Assigns references to each action based on the Builder configuration. + * Holds reference to the builder instance so that we can use its actions + * during iteration. */ private SQLiteTableReader(Builder builder) { - - this.onColumnNameAction = nonNullValue(builder.onColumnNameAction); - this.onStringAction = nonNullValue(builder.onStringAction); - this.onIntegerAction = nonNullValue(builder.onIntegerAction); - this.onLongAction = nonNullValue(builder.onLongAction); - this.onFloatAction = nonNullValue(builder.onFloatAction); - this.onBlobAction = nonNullValue(builder.onBlobAction); - this.forAllAction = nonNullValue(builder.forAllAction); - + this.builder = builder; this.file = builder.file; } - /** - * Ensures the action is null safe. If action is left null, then during - * iteration null checks would be necessary. To mitigate against that, no-op - * lambdas are substituted for null values. - * - * @param Generic type of consumer - * @param action Consumer for generic type, supplied by Builder. - * - * @return If action is null, then a no-op lambda, if not then the action - * itself. - */ - private Consumer nonNullValue(Consumer action) { - return (Objects.nonNull(action)) ? action : NO_OP -> { - }; - } - /** * Fetches all table names from the database. * @@ -306,8 +289,7 @@ public class SQLiteTableReader implements AutoCloseable { public int getColumnCount(String tableName) throws SQLiteTableReaderException { ensureOpen(); try (ResultSet columnCount = conn.createStatement() - .executeQuery("SELECT * FROM " - + "\"" + tableName + "\"")) { + .executeQuery(String.format(SELECT_ALL_QUERY, tableName))) { return columnCount.getMetaData().getColumnCount(); } catch (SQLException ex) { throw new SQLiteTableReaderException(ex); @@ -325,23 +307,24 @@ public class SQLiteTableReader implements AutoCloseable { * @throws SQLiteTableReaderException */ public void read(String tableName) throws SQLiteTableReaderException { - readHelper("SELECT * FROM \"" + tableName + "\"", () -> false); + readHelper(String.format(SELECT_ALL_QUERY, tableName), () -> false); } /** * Reads column names and values from the table. Only actions that were - * configured in the Builder will be invoked during iteration. Iteration will stop - * when the table read has completed or an exception was encountered. + * configured in the Builder will be invoked during iteration. Iteration + * will stop when the table read has completed or an exception was + * encountered. * * @param tableName Source table to perform a read - * @param limit Number of rows to read from the table - * @param offset Starting row to read from in the table + * @param limit Number of rows to read from the table + * @param offset Starting row to read from in the table * * @throws SQLiteTableReaderException * */ public void read(String tableName, int limit, int offset) throws SQLiteTableReaderException { - readHelper("SELECT * FROM \"" + tableName + "\" LIMIT " + limit + readHelper(String.format(SELECT_ALL_QUERY, tableName)+ " LIMIT " + limit + " OFFSET " + offset, () -> false); } @@ -356,18 +339,16 @@ public class SQLiteTableReader implements AutoCloseable { * */ public void read(String tableName, BooleanSupplier condition) throws SQLiteTableReaderException { - if (Objects.nonNull(prevTableName) && prevTableName.equals(tableName)) { - readHelper("SELECT * FROM \"" + tableName + "\"", condition); - } else { + if (Objects.isNull(prevTableName) || !prevTableName.equals(tableName)) { prevTableName = tableName; - closeTableResources(); - readHelper("SELECT * FROM \"" + tableName + "\"", condition); + closeTableResources(); } + readHelper(String.format(SELECT_ALL_QUERY, tableName), condition); } /** - * Performs the result set iteration and is responsible for maintaining state - * of the read over multiple invocations. + * Performs the result set iteration and is responsible for maintaining + * state of the read over multiple invocations. * * @throws SQLiteTableReaderException */ @@ -379,35 +360,35 @@ public class SQLiteTableReader implements AutoCloseable { } //Process column names before reading the database table values - while(columnNameIndex < totalColumnCount) { + while (columnNameIndex < totalColumnCount) { if (condition.getAsBoolean()) { - return; + return; } - this.onColumnNameAction.accept(currentMetadata + builder.onColumnNameAction.accept(currentMetadata .getColumnName(++columnNameIndex)); } while (unfinishedRow || queryResults.next()) { - while(currRowColumnIndex < totalColumnCount) { + while (currRowColumnIndex < totalColumnCount) { if (condition.getAsBoolean()) { unfinishedRow = true; return; } - + Object item = queryResults.getObject(++currRowColumnIndex); if (item instanceof String) { - this.onStringAction.accept((String) item); + builder.onStringAction.accept((String) item); } else if (item instanceof Integer) { - this.onIntegerAction.accept((Integer) item); + builder.onIntegerAction.accept((Integer) item); } else if (item instanceof Double) { - this.onFloatAction.accept((Double) item); + builder.onFloatAction.accept((Double) item); } else if (item instanceof Long) { - this.onLongAction.accept((Long) item); + builder.onLongAction.accept((Long) item); } else if (item instanceof byte[]) { - this.onBlobAction.accept((byte[]) item); + builder.onBlobAction.accept((byte[]) item); } - this.forAllAction.accept(item); + builder.forAllAction.accept(item); } unfinishedRow = false; //Wrap column index back around if we've reached the end of the row @@ -480,18 +461,18 @@ public class SQLiteTableReader implements AutoCloseable { * directory. * * @param file AbstractFile from the data source - * @param id The input files id value + * @param id The input files id value * * @return The path of the file on disk * * @throws IOException Exception writing file contents * @throws NoCurrentCaseException Current case closed during file copying */ - private String copyFileToTempDirectory(AbstractFile file, long id) + private String copyFileToTempDirectory(AbstractFile file, long fileId) throws IOException, NoCurrentCaseException { String localDiskPath = Case.getCurrentCaseThrows().getTempDirectory() - + File.separator + id + file.getName(); + + File.separator + fileId + file.getName(); File localDatabaseFile = new File(localDiskPath); if (!localDatabaseFile.exists()) { ContentUtils.writeToFile(file, localDatabaseFile); @@ -568,12 +549,12 @@ public class SQLiteTableReader implements AutoCloseable { * @throws Throwable */ @Override - public void finalize() throws Throwable { - super.finalize(); + protected void finalize() throws Throwable { try { close(); } catch (SQLiteTableReaderException ex) { //Do nothing, we tried out best to close the connection. } + super.finalize(); } } diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReaderException.java b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReaderException.java index 70ef801673..63f907cc36 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReaderException.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReaderException.java @@ -27,18 +27,18 @@ public class SQLiteTableReaderException extends Exception { * Accepts both a message and a parent exception. * * @param msg Message detailing the cause - * @param ex Parent exception + * @param parentEx Parent exception */ - public SQLiteTableReaderException(String msg, Throwable ex) { - super(msg, ex); + public SQLiteTableReaderException(String msg, Throwable parentEx) { + super(msg, parentEx); } /** * Accepts only a parent exception. * - * @param ex Parent exception + * @param parentEx Parent exception */ - public SQLiteTableReaderException(Throwable ex) { - super(ex); + public SQLiteTableReaderException(Throwable parentEx) { + super(parentEx); } } From 7a410ade158c6f9d75544feb03a0b6767f3ffa84 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 12 Nov 2018 11:46:45 -0500 Subject: [PATCH 11/32] 4361 fix name of column in upgrade code --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 33f820eb9a..36600d2499 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -3251,7 +3251,7 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded."); } final String dataSourcesTableName = "data_sources"; - final String dataSourceIdColumnName = "data_source_id"; + final String dataSourceIdColumnName = "datasource_id"; if (!doesColumnExist(conn, dataSourcesTableName, dataSourceIdColumnName)) { statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceIdColumnName)); //NON-NLS } From e20466bc2832876b4a77c1ce0339499fb8af5245 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 14 Nov 2018 09:54:22 -0500 Subject: [PATCH 12/32] Added correlation property search. Cleanup still needed. --- Core/src/org/sleuthkit/autopsy/core/layer.xml | 5 + .../datamodel/DisplayableItemNodeVisitor.java | 16 + .../autopsy/md5search/Bundle.properties | 6 + ...CorrelationAttributeInstanceChildNode.java | 123 ++++++++ ...tionAttributeInstanceChildNodeFactory.java | 68 +++++ .../CorrelationAttributeInstanceRootNode.java | 162 ++++++++++ .../CorrelationAttributeSearchResults.java | 25 ++ .../DlgCorrelationAttributeInstanceNode.java | 143 +++++++++ .../autopsy/md5search/DlgFilterChildren.java | 39 +++ .../autopsy/md5search/DlgFilterNode.java | 79 +++++ .../autopsy/md5search/DlgSearchChildren.java | 34 +++ .../autopsy/md5search/DlgSearchNode.java | 29 ++ .../autopsy/md5search/Md5SearchAction.java | 60 ++++ .../autopsy/md5search/Md5SearchDialog.form | 145 +++++++++ .../autopsy/md5search/Md5SearchDialog.java | 282 ++++++++++++++++++ 15 files changed, 1216 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form create mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 8bdde0f317..546ec757ec 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -78,6 +78,7 @@ + @@ -201,6 +202,10 @@ + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 002f87acba..dbd06ac8dc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -29,6 +29,8 @@ import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNod import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.datamodel.accounts.Accounts; +import org.sleuthkit.autopsy.md5search.CorrelationAttributeInstanceChildNode; +import org.sleuthkit.autopsy.md5search.DlgCorrelationAttributeInstanceNode; /** * Visitor pattern that goes over all nodes in the directory tree. This includes @@ -125,6 +127,10 @@ public interface DisplayableItemNodeVisitor { T visit(CentralRepoCommonAttributeInstanceNode crfin); T visit(InstanceCountNode icn); + + T visit(CorrelationAttributeInstanceChildNode caicn); + + T visit(DlgCorrelationAttributeInstanceNode cain); //DLG: /* * Tags @@ -214,6 +220,16 @@ public interface DisplayableItemNodeVisitor { return defaultVisit(icn); } + @Override + public T visit(CorrelationAttributeInstanceChildNode caicn){ + return defaultVisit(caicn); + } + + @Override + public T visit(DlgCorrelationAttributeInstanceNode cain) { + return defaultVisit(cain); + } + @Override public T visit(CentralRepoCommonAttributeInstanceNode crfin){ return defaultVisit(crfin); diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties b/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties new file mode 100755 index 0000000000..59bdbf31bf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties @@ -0,0 +1,6 @@ + +Md5SearchDialog.jButton1.text=Search +Md5SearchDialog.jTextField1.text= +Md5SearchDialog.jLabel1.text=Correlation Property Value: +Md5SearchDialog.jLabel2.text=Correlation Property Type: +Md5SearchDialog.jTextArea1.text=Type a value into the Correlation Property Value field. When the input type is detected, the Correlation Property Type field will become available and default to the detected input type. diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java new file mode 100755 index 0000000000..49c525bd7a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java @@ -0,0 +1,123 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import javax.swing.Action; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * //DLG: + */ +public final class CorrelationAttributeInstanceChildNode extends DisplayableItemNode { + private String caseName; + private String dataSourceName; + //DLG: final ? knownStatus + private String fullPath; + //DLG: final String comment + //DLG: final String deviceId + private String name; + private String parent; + + public CorrelationAttributeInstanceChildNode(Children children) { + super(children); + } + + //CorrelationAttributeInstanceChildNode(Children children) { + // init(null); + //} + + private void init(Map map) { + caseName = (String)map.get("caseName"); + dataSourceName = (String)map.get("dataSourceName"); + fullPath = (String)map.get("fullPath"); + name = (String)map.get("name"); + parent = (String)map.get("parent"); + } + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + actionsList.addAll(Arrays.asList(super.getActions(true))); + + return actionsList.toArray(new Action[actionsList.size()]); + } + + /*@Override + public T accept(DisplayableItemNodeVisitor visitor) { + return visitor.visit(this); + }*/ + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-occur in the treetable with objects + // of this type and they will need to provide the same key + return CorrelationAttributeInstanceChildNode.class.getName(); + } + + @NbBundle.Messages({ + "CorrelationAttributeInstanceChildNode.columnName.case=Case", + "CorrelationAttributeInstanceChildNode.columnName.dataSource=Data Source", + "CorrelationAttributeInstanceChildNode.columnName.known=Known", + "CorrelationAttributeInstanceChildNode.columnName.path=Path", + "CorrelationAttributeInstanceChildNode.columnName.comment=Comment", + "CorrelationAttributeInstanceChildNode.columnName.device=Device" + }) + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_case(), + Bundle.CorrelationAttributeInstanceNode_columnName_case(), "", name)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), "", parent)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_known(), + Bundle.CorrelationAttributeInstanceNode_columnName_known(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_path(), + Bundle.CorrelationAttributeInstanceNode_columnName_path(), "", dataSourceName)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_device(), + Bundle.CorrelationAttributeInstanceNode_columnName_device(), "", caseName)); + + return sheet; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java new file mode 100755 index 0000000000..b30a11e06f --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java @@ -0,0 +1,68 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.datamodel.KeyValue; +import org.sleuthkit.autopsy.datamodel.KeyValueNode; + +/** + * //DLG: + */ +final class CorrelationAttributeInstanceChildNodeFactory extends ChildFactory { + private final Collection correlationInstances; + + CorrelationAttributeInstanceChildNodeFactory(Collection correlationInstances) { + this.correlationInstances = correlationInstances; + } + + @Override + protected boolean createKeys(List list) { + for (CorrelationAttributeInstance instance : correlationInstances) { + Map properties = new HashMap<>(); //DLG: + + final String caseName = instance.getCorrelationCase().getDisplayName(); + final String dataSourceName = instance.getCorrelationDataSource().getName(); + //DLG: final ? knownStatus + final String fullPath = instance.getFilePath(); + //DLG: final String comment + //DLG: final String deviceId + + final File file = new File(fullPath); + final String name = file.getName(); + final String parent = file.getParent(); + + properties.put("caseName", caseName); + properties.put("dataSourceName", dataSourceName); + properties.put("knownStatus", ""); //DLG: + properties.put("fullPath", fullPath); + properties.put("comment", ""); //DLG: + properties.put("deviceId", ""); //DLG: + properties.put("name", name); + properties.put("parent", parent); + + list.add(new KeyValue(String.valueOf(instance.getID()), properties, instance.getID())); + } + return true; + } + + @Override + protected Node createNodeForKey(KeyValue key) { + Map map = key.getMap(); + Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.fixed(correlationInstances.toArray())); + //DLG: Node resultNode = new CorrelationAttributeInstanceChildNode(kvNode); + return null; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java new file mode 100755 index 0000000000..43b67b57a9 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java @@ -0,0 +1,162 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.md5search; + +import org.sleuthkit.autopsy.commonfilesearch.*; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.Action; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * Used by the Common Files search feature to encapsulate instances of a given + * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are not in the current case, but from the + * Central Repo. Contrast with SleuthkitCase which should be used + * when the FileInstance was found in the case presently open in Autopsy. + */ +final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { + + public CorrelationAttributeInstanceRootNode(Children children) { + super(children); + } + + //private final CorrelationAttributeInstance crFile; + + //CorrelationAttributeInstanceRootNode(CorrelationAttributeSearchResults data) { + //super(Children.create(new FileInstanceNodeFactory(data), true)); + //} + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + actionsList.addAll(Arrays.asList(super.getActions(true))); + + return actionsList.toArray(new Action[actionsList.size()]); + } + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + return null; + //return visitor.visit(this); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-occur in the treetable with objects + // of this type and they will need to provide the same key + return CaseDBCommonAttributeInstanceNode.class.getName(); + } + + @NbBundle.Messages({ + "CorrelationAttributeInstanceNode.columnName.case=Case", + "CorrelationAttributeInstanceNode.columnName.dataSource=Data Source", + "CorrelationAttributeInstanceNode.columnName.known=Known", + "CorrelationAttributeInstanceNode.columnName.path=Path", + "CorrelationAttributeInstanceNode.columnName.comment=Comment", + "CorrelationAttributeInstanceNode.columnName.device=Device" + }) + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + /*Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); + + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); + final String dataSourceName = centralRepoFile.getCorrelationDataSource().getName(); + //DLG: final ? knownStatus + final String fullPath = centralRepoFile.getFilePath(); + //DLG: final String comment + //DLG: final String deviceId + + final File file = new File(fullPath); + final String name = file.getName(); + final String parent = file.getParent(); + + + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_case(), + Bundle.CorrelationAttributeInstanceNode_columnName_case(), "", name)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), "", parent)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_known(), + Bundle.CorrelationAttributeInstanceNode_columnName_known(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_path(), + Bundle.CorrelationAttributeInstanceNode_columnName_path(), "", dataSourceName)); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), "", "")); + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_device(), + Bundle.CorrelationAttributeInstanceNode_columnName_device(), "", caseName));*/ + + return sheet; + } + + /** + * Child generator for SleuthkitCaseFileInstanceNode of + * CommonAttributeValueNode. + */ + static class FileInstanceNodeFactory extends ChildFactory { + + private final CommonAttributeValue descendants; + + FileInstanceNodeFactory(CommonAttributeValue descendants) { + this.descendants = descendants; + } + + @Override + protected boolean createKeys(List list) { + return true; + } + + /*@Override + protected Node[] createNodesForKey(AbstractCommonAttributeInstance searchResult) { + return null; + //return searchResult.generateNodes(); + }*/ + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java new file mode 100755 index 0000000000..5c1e0ee004 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java @@ -0,0 +1,25 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.ArrayList; +import java.util.List; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; + +/** + * //DLG: + */ +public class CorrelationAttributeSearchResults { + List correlationInstances = new ArrayList<>(); + + CorrelationAttributeSearchResults(List correlationInstances) { + this.correlationInstances = correlationInstances; + } + + List getCorrelationAttributeInstances() { + return correlationInstances; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java new file mode 100755 index 0000000000..1e6a51850c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java @@ -0,0 +1,143 @@ +/* + * + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.md5search; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.Action; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; +import org.sleuthkit.autopsy.datamodel.NodeProperty; + +/** + * Used by the Common Files search feature to encapsulate instances of a given + * MD5s matched in the search. These nodes will be children of Md5Nodes. + * + * Use this type for files which are not in the current case, but from the + * Central Repo. Contrast with SleuthkitCase which should be used + * when the FileInstance was found in the case presently open in Autopsy. + */ +public class DlgCorrelationAttributeInstanceNode extends DisplayableItemNode { + + private final CorrelationAttributeInstance crFile; + + DlgCorrelationAttributeInstanceNode(CorrelationAttributeInstance content) { + super(Children.LEAF, Lookups.fixed(content)); + this.crFile = content; + this.setDisplayName(new File(this.crFile.getFilePath()).getName()); + } + + public CorrelationAttributeInstance getCorrelationAttributeInstance(){ + return this.crFile; + } + + @Override + public Action[] getActions(boolean context){ + List actionsList = new ArrayList<>(); + + actionsList.addAll(Arrays.asList(super.getActions(true))); + + return actionsList.toArray(new Action[actionsList.size()]); + } + + @Override + public T accept(DisplayableItemNodeVisitor visitor) { + return visitor.visit(this); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + public String getItemType() { + //objects of type FileNode will co-occur in the treetable with objects + // of this type and they will need to provide the same key + return DlgCorrelationAttributeInstanceNode.class.getName(); + } + + @NbBundle.Messages({ + "DlgCorrelationAttributeInstanceNode.columnName.name=Name", + "DlgCorrelationAttributeInstanceNode.columnName.case=Case", + "DlgCorrelationAttributeInstanceNode.columnName.dataSource=Data Source", + "DlgCorrelationAttributeInstanceNode.columnName.known=Known", + "DlgCorrelationAttributeInstanceNode.columnName.path=Path", + "DlgCorrelationAttributeInstanceNode.columnName.comment=Comment", + "DlgCorrelationAttributeInstanceNode.columnName.device=Device" + }) + @Override + protected Sheet createSheet(){ + Sheet sheet = new Sheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + + if(sheetSet == null){ + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + + final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); + + final String path = centralRepoFile.getFilePath(); + final File file = new File(path); + final String name = file.getName(); + //DLG: final String parent = file.getParent(); + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); + final CorrelationDataSource dataSource = centralRepoFile.getCorrelationDataSource(); + final String dataSourceName = dataSource.getName(); + final String known = centralRepoFile.getKnownStatus().getName(); + final String comment = centralRepoFile.getComment(); + final String device = dataSource.getDeviceID(); + + final String NO_DESCR = ""; + + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_name(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_name(), NO_DESCR, name)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_case(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_case(), NO_DESCR, caseName)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_dataSource(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_dataSource(), NO_DESCR, dataSourceName)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_known(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_known(), NO_DESCR, known)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_path(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_path(), NO_DESCR, path)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_comment(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_comment(), NO_DESCR, comment)); + sheetSet.put(new NodeProperty<>( + Bundle.DlgCorrelationAttributeInstanceNode_columnName_device(), + Bundle.DlgCorrelationAttributeInstanceNode_columnName_device(), NO_DESCR, device)); + + return sheet; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java new file mode 100755 index 0000000000..6ca7c7540c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import org.openide.nodes.Children; +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; + +/** + * //DLG: + */ +class DlgFilterChildren extends FilterNode.Children { + + public static Children createInstance(Node wrappedNode, boolean createChildren) { + + if (createChildren) { + return new DlgFilterChildren(wrappedNode); + } else { + return Children.LEAF; + } + } + + DlgFilterChildren(Node wrappedNode) { + super(wrappedNode); + } + + @Override + protected Node copyNode(Node nodeToCopy) { + return new DlgFilterNode(nodeToCopy, false); + } + + @Override + protected Node[] createNodes(Node key) { + return new Node[]{this.copyNode(key)}; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java new file mode 100755 index 0000000000..c746637544 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java @@ -0,0 +1,79 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; +import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; + +/** + * //DLG: + */ +public class DlgFilterNode extends FilterNode { + + private final boolean createChildren; + private final boolean forceUseWrappedDisplayName; + private String columnOrderKey = "NONE"; + + public DlgFilterNode(Node node, boolean createChildren) { + super(node, DlgFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + this.forceUseWrappedDisplayName = false; + this.createChildren = createChildren; + } + + public DlgFilterNode(Node node, boolean createChildren, String columnOrderKey) { + super(node, DlgFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + this.forceUseWrappedDisplayName = false; + this.createChildren = createChildren; + this.columnOrderKey = columnOrderKey; + } + + /*public DlgFilterNode(Node node, int childLayerDepth) { + super(node, TableFilterChildrenWithDescendants.createInstance(node, childLayerDepth), Lookups.proxy(node)); + this.createChildren = true; + this.forceUseWrappedDisplayName = true; + }*/ + + @Override + public String getDisplayName() { + if (this.forceUseWrappedDisplayName) { + return super.getDisplayName(); + } else if (createChildren) { + return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text"); + } else { + return super.getDisplayName(); + } + } + + public void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { + /* + * Currently, child selection is only supported for nodes selected in + * the tree view and decorated with a DataResultFilterNode. + */ + if (getOriginal() instanceof DataResultFilterNode) { + ((DataResultFilterNode) getOriginal()).setChildNodeSelectionInfo(selectedChildNodeInfo); + } + } + + public NodeSelectionInfo getChildNodeSelectionInfo() { + /* + * Currently, child selection is only supported for nodes selected in + * the tree view and decorated with a DataResultFilterNode. + */ + if (getOriginal() instanceof DataResultFilterNode) { + return ((DataResultFilterNode) getOriginal()).getChildNodeSelectionInfo(); + } else { + return null; + } + } + + public String getColumnOrderKey() { + return columnOrderKey; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java new file mode 100755 index 0000000000..3f2c2ad403 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.List; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; +import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; + +/** + * //DLG: + */ +class DlgSearchChildren extends Children.Keys { + + DlgSearchChildren(boolean lazy, List fileList) { + super(lazy); + this.setKeys(fileList); + } + + @Override + protected Node[] createNodes(CorrelationAttributeInstance t) { + //DLG: + Node[] node = new Node[1]; + //DLG: + node[0] = new DlgCorrelationAttributeInstanceNode(t); + return node; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java new file mode 100755 index 0000000000..6d1a75d39b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.List; +import org.openide.nodes.AbstractNode; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; + +/** + * //DLG: + */ +class DlgSearchNode extends AbstractNode { + + private DlgSearchChildren children; + + DlgSearchNode(List keys) { + super(new DlgSearchChildren(true, keys)); + this.children = (DlgSearchChildren) this.getChildren(); + } + + @Override + public String getName() { + //DLG: + return /*NbBundle.getMessage(this.getClass(), */"SearchNode.getName.text"/*)*/; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java new file mode 100755 index 0000000000..a231e389fb --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java @@ -0,0 +1,60 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.md5search; + +import java.awt.event.ActionEvent; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.actions.CallableSystemAction; +import org.sleuthkit.autopsy.casemodule.Case; + +/** + * //DLG: + */ +public class Md5SearchAction extends CallableSystemAction { + + @Override + public boolean isEnabled() { + return super.isEnabled() && Case.isCaseOpen(); + } + + @Override + public void actionPerformed(ActionEvent event) { + performAction(); + } + + @Override + public void performAction() { + Md5SearchDialog dialog = new Md5SearchDialog(); + dialog.display(); + } + + @NbBundle.Messages({ + "Md5SearchAction.getName.text=Correlation Attribute Search"}) + @Override + public String getName() { + return Bundle.Md5SearchAction_getName_text(); + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form new file mode 100755 index 0000000000..2ecd2f4475 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form @@ -0,0 +1,145 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java new file mode 100755 index 0000000000..3d6413e82a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java @@ -0,0 +1,282 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.md5search; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JFrame; +import javax.swing.SwingWorker; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.openide.explorer.ExplorerManager; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributesSearchResultsViewerTable; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; +import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; +import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; + +/** + * + * @author dgrove + */ +public class Md5SearchDialog extends javax.swing.JDialog { + private static final String FILES_CORRELATION_TYPE = "Files"; + private final List correlationTypes; + private final Pattern md5Pattern; + + /** + * Creates new form Md5SearchDialog + */ + @NbBundle.Messages({"Md5SearchDialog.title=Correlation Property Search"}) + public Md5SearchDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.Md5SearchDialog_title(), true); + this.correlationTypes = new ArrayList<>(); + this.md5Pattern = Pattern.compile("^[a-fA-F0-9]{32}$"); // NON-NLS + initComponents(); + customizeComponents(); + } + + private void search() { + new SwingWorker, Void>() { + + @Override + protected List doInBackground() { + List correlationTypes; + List correlationInstances = new ArrayList<>(); + + try { + correlationTypes = EamDb.getInstance().getDefinedCorrelationTypes(); + for (CorrelationAttributeInstance.Type type : correlationTypes) { + if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) { + correlationInstances = EamDb.getInstance().getArtifactInstancesByTypeValue(type, jTextField1.getText()); + break; + } + } + } catch (Exception ex) { + //DLG: + } + + return correlationInstances; + } + + @Override + protected void done() { + try { + super.done(); + List correlationInstances = this.get(); + //DLG: Node rootNode = new CorrelationAttributeInstanceRootNode(searchResults); + //DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(rootNode, ExplorerManager.find(Md5SearchDialog.this)); + //TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); + DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable(); + Collection viewers = new ArrayList<>(1); + viewers.add(table); + + DlgSearchNode searchNode = new DlgSearchNode(correlationInstances); + DlgFilterNode tableFilterNode = new DlgFilterNode(searchNode, true, searchNode.getName()); + + //Node rootNode; + //Children childNodes = Children.create(new CorrelationAttributeInstanceChildNodeFactory(correlationInstances), true); + //rootNode = new AbstractNode(childNodes); + DataResultTopComponent results = DataResultTopComponent.createInstance( + "Files", "Correlation Property Search", tableFilterNode, HIDE_ON_CLOSE, viewers); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); //DLG: + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); //DLG: + } + } + }.execute(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jTextField1 = new javax.swing.JTextField(); + jButton1 = new javax.swing.JButton(); + correlationTypeComboBox = new javax.swing.JComboBox<>(); + jLabel2 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextArea1 = new javax.swing.JTextArea(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setResizable(false); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jLabel1.text")); // NOI18N + + jTextField1.setText(org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jTextField1.text")); // NOI18N + jTextField1.addInputMethodListener(new java.awt.event.InputMethodListener() { + public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { + } + public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) { + jTextField1InputMethodTextChanged(evt); + } + }); + jTextField1.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + public void propertyChange(java.beans.PropertyChangeEvent evt) { + jTextField1PropertyChange(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jLabel2.text")); // NOI18N + + jTextArea1.setEditable(false); + jTextArea1.setColumns(20); + jTextArea1.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N + jTextArea1.setLineWrap(true); + jTextArea1.setRows(5); + jTextArea1.setText(org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jTextArea1.text")); // NOI18N + jTextArea1.setWrapStyleWord(true); + jTextArea1.setBorder(null); + jTextArea1.setOpaque(false); + jScrollPane1.setViewportView(jTextArea1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(11, 11, 11) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButton1, javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTextField1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButton1) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void jTextField1PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTextField1PropertyChange + //DLG: + }//GEN-LAST:event_jTextField1PropertyChange + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + search(); + }//GEN-LAST:event_jButton1ActionPerformed + + private void jTextField1InputMethodTextChanged(java.awt.event.InputMethodEvent evt) {//GEN-FIRST:event_jTextField1InputMethodTextChanged + //DLG: + }//GEN-LAST:event_jTextField1InputMethodTextChanged + + private void customizeComponents() { + jButton1.setEnabled(false); + correlationTypeComboBox.setEnabled(false); + + /* + * Add correlation types to the combo-box. + */ + try { + EamDb dbManager = EamDb.getInstance(); + correlationTypes.clear(); + correlationTypes.addAll(dbManager.getDefinedCorrelationTypes()); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + } + + for (CorrelationAttributeInstance.Type type : correlationTypes) { + correlationTypeComboBox.addItem(type.getDisplayName()); + } + + /* + * Create listener for text input. + */ + jTextField1.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + validateInput(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + validateInput(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + validateInput(); + } + + private void validateInput() { + Matcher matcher = md5Pattern.matcher(jTextField1.getText().trim()); + if (matcher.find()) { + jButton1.setEnabled(true); + correlationTypeComboBox.setEnabled(true); + correlationTypeComboBox.setSelectedItem(FILES_CORRELATION_TYPE); + } else { + jButton1.setEnabled(false); + correlationTypeComboBox.setEnabled(false); + } + } + }); + } + + public void display() { + this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + setVisible(true); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox correlationTypeComboBox; + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables +} From 6a5d7459214602e55f3e6121485e0f3ed2fc9d56 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 14 Nov 2018 16:03:38 -0500 Subject: [PATCH 13/32] 4361 make queries use case db datasource id --- .../datamodel/AbstractSqlEamDb.java | 79 ++++++++----------- .../datamodel/CorrelationDataSource.java | 55 +++++++------ .../centralrepository/datamodel/EamDb.java | 6 +- .../datamodel/SqliteEamDb.java | 12 +-- .../eventlisteners/CaseEventListener.java | 7 +- .../ingestmodule/IngestModule.java | 4 +- 6 files changed, 77 insertions(+), 86 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 36600d2499..ba0066c412 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -555,12 +555,13 @@ abstract class AbstractSqlEamDb implements EamDb { * * @param caseId - the id of the CorrelationCase in the Central * Repository - * @param dataSourceDeviceId - the device Id of the data source + * @param dataSourceDeviceId - the object id if of the data source in the + * case db * * @return a String to be used as a key for the dataSourceCacheByDeviceId */ - private static String getDataSourceByDeviceIdCacheKey(int caseId, String dataSourceDeviceId) { - return "Case" + caseId + "DeviceId" + dataSourceDeviceId; //NON-NLS + private static String getDataSourceByCaseDataSourceIdCacheKey(int caseId, Long caseDbDataSourceId) { + return "Case" + caseId + "DataSourceId" + caseDbDataSourceId; //NON-NLS } /** @@ -582,12 +583,12 @@ abstract class AbstractSqlEamDb implements EamDb { * @param eamDataSource the data source to add */ @Override - public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException { + public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource) throws EamDbException { if (eamDataSource.getCaseID() == -1) { throw new EamDbException("Case ID is -1"); } else if (eamDataSource.getID() != -1) { // This data source is already in the central repo - return; + return eamDataSource; } Connection conn = connect(); @@ -611,8 +612,9 @@ abstract class AbstractSqlEamDb implements EamDb { } int dataSourceId = resultSet.getInt(1); //last_insert_rowid() CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getCaseDataSourceID()); - dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(dataSource.getCaseID(), dataSource.getDeviceID()), dataSource); + dataSourceCacheByDeviceId.put(getDataSourceByCaseDataSourceIdCacheKey(dataSource.getCaseID(), dataSource.getCaseDataSourceID()), dataSource); dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource); + return dataSource; } catch (SQLException ex) { throw new EamDbException("Error inserting new data source.", ex); // NON-NLS } finally { @@ -634,13 +636,13 @@ abstract class AbstractSqlEamDb implements EamDb { * @throws EamDbException */ @Override - public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { + public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException { if (correlationCase == null) { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCacheByDeviceId.get(getDataSourceByDeviceIdCacheKey(correlationCase.getID(), dataSourceDeviceId), () -> getDataSourceFromCr(correlationCase, dataSourceDeviceId)); + return dataSourceCacheByDeviceId.get(getDataSourceByCaseDataSourceIdCacheKey(correlationCase.getID(), caseDbDataSourceId), () -> getDataSourceFromCr(correlationCase, caseDbDataSourceId)); } catch (CacheLoader.InvalidCacheLoadException ignored) { //lambda valueloader returned a null value and cache can not store null values this is normal if the dataSource does not exist in the central repo yet return null; @@ -661,18 +663,18 @@ abstract class AbstractSqlEamDb implements EamDb { * * @throws EamDbException */ - private CorrelationDataSource getDataSourceFromCr(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { + private CorrelationDataSource getDataSourceFromCr(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException { Connection conn = connect(); CorrelationDataSource eamDataSourceResult = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; - String sql = "SELECT * FROM data_sources WHERE device_id=? AND case_id=?"; // NON-NLS + String sql = "SELECT * FROM data_sources WHERE datasource_id=? AND case_id=?"; // NON-NLS try { preparedStatement = conn.prepareStatement(sql); - preparedStatement.setString(1, dataSourceDeviceId); + preparedStatement.setLong(1, caseDbDataSourceId); preparedStatement.setInt(2, correlationCase.getID()); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { @@ -743,7 +745,7 @@ abstract class AbstractSqlEamDb implements EamDb { eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); } if (eamDataSourceResult != null) { - dataSourceCacheByDeviceId.put(getDataSourceByDeviceIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDeviceID()), eamDataSourceResult); + dataSourceCacheByDeviceId.put(getDataSourceByCaseDataSourceIdCacheKey(correlationCase.getID(), eamDataSourceResult.getCaseDataSourceID()), eamDataSourceResult); } } catch (SQLException ex) { throw new EamDbException("Error getting data source.", ex); // NON-NLS @@ -810,28 +812,25 @@ abstract class AbstractSqlEamDb implements EamDb { = "INSERT INTO " + tableName + "(case_id, data_source_id, value, file_path, known_status, comment, object_id) " - + "VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), " - + "(SELECT id FROM data_sources WHERE device_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) " + getConflictClause(); try { preparedStatement = conn.prepareStatement(sql); if (!eamArtifact.getCorrelationValue().isEmpty()) { - - preparedStatement.setString(1, eamArtifact.getCorrelationCase().getCaseUUID()); - preparedStatement.setString(2, eamArtifact.getCorrelationDataSource().getDeviceID()); - preparedStatement.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID()); - preparedStatement.setString(4, eamArtifact.getCorrelationValue()); - preparedStatement.setString(5, eamArtifact.getFilePath().toLowerCase()); - preparedStatement.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue()); + preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID()); + preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID()); + preparedStatement.setString(3, eamArtifact.getCorrelationValue()); + preparedStatement.setString(4, eamArtifact.getFilePath().toLowerCase()); + preparedStatement.setByte(5, eamArtifact.getKnownStatus().getFileKnownValue()); if ("".equals(eamArtifact.getComment())) { - preparedStatement.setNull(7, Types.INTEGER); + preparedStatement.setNull(6, Types.INTEGER); } else { - preparedStatement.setString(7, eamArtifact.getComment()); + preparedStatement.setString(6, eamArtifact.getComment()); } - preparedStatement.setLong(8, eamArtifact.getFileObjectId()); + preparedStatement.setLong(7, eamArtifact.getFileObjectId()); preparedStatement.executeUpdate(); } @@ -1140,7 +1139,7 @@ abstract class AbstractSqlEamDb implements EamDb { * dataSource */ @Override - public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException { + public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource) throws EamDbException { Connection conn = connect(); Long instanceCount = 0L; @@ -1153,21 +1152,14 @@ abstract class AbstractSqlEamDb implements EamDb { for (CorrelationAttributeInstance.Type type : artifactTypes) { String table_name = EamDbUtil.correlationTypeToInstanceTableName(type); - sql += "+ (SELECT count(*) FROM " + table_name - + " WHERE data_source_id=(SELECT data_sources.id FROM cases INNER JOIN data_sources ON cases.id = data_sources.case_id WHERE case_uid=? and device_id=?))"; + + " WHERE data_source_id=" + correlationDataSource.getID() + ")"; } - try { preparedStatement = conn.prepareStatement(sql); - for (int i = 0; i < artifactTypes.size(); ++i) { - preparedStatement.setString(2 * i + 1, caseUUID); - preparedStatement.setString(2 * i + 2, dataSourceID); - } - resultSet = preparedStatement.executeQuery(); resultSet.next(); instanceCount = resultSet.getLong(1); @@ -1417,25 +1409,23 @@ abstract class AbstractSqlEamDb implements EamDb { if (eamArtifact.getCorrelationDataSource() == null) { throw new EamDbException("Correlation data source is null"); } - Connection conn = connect(); PreparedStatement preparedQuery = null; String tableName = EamDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); - String sqlUpdate = "UPDATE " + tableName + " SET comment=? " - + "WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) " - + "AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) " + + "WHERE case_id=? " + + "AND data_source_id=? " + "AND value=? " + "AND file_path=?"; try { preparedQuery = conn.prepareStatement(sqlUpdate); preparedQuery.setString(1, eamArtifact.getComment()); - preparedQuery.setString(2, eamArtifact.getCorrelationCase().getCaseUUID()); - preparedQuery.setString(3, eamArtifact.getCorrelationDataSource().getDeviceID()); + preparedQuery.setInt(2, eamArtifact.getCorrelationCase().getID()); + preparedQuery.setInt(3, eamArtifact.getCorrelationDataSource().getID()); preparedQuery.setString(4, eamArtifact.getCorrelationValue()); preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase()); preparedQuery.executeUpdate(); @@ -1617,8 +1607,8 @@ abstract class AbstractSqlEamDb implements EamDb { String sqlQuery = "SELECT id FROM " + tableName - + " WHERE case_id=(SELECT id FROM cases WHERE case_uid=?) " - + "AND data_source_id=(SELECT id FROM data_sources WHERE device_id=?) " + + " WHERE case_id=? " + + "AND data_source_id=? " + "AND value=? " + "AND file_path=?"; @@ -1630,8 +1620,8 @@ abstract class AbstractSqlEamDb implements EamDb { try { preparedQuery = conn.prepareStatement(sqlQuery); - preparedQuery.setString(1, eamArtifact.getCorrelationCase().getCaseUUID()); - preparedQuery.setString(2, eamArtifact.getCorrelationDataSource().getDeviceID()); + preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID()); + preparedQuery.setInt(2, eamArtifact.getCorrelationDataSource().getID()); preparedQuery.setString(3, eamArtifact.getCorrelationValue()); preparedQuery.setString(4, eamArtifact.getFilePath()); resultSet = preparedQuery.executeQuery(); @@ -1661,8 +1651,7 @@ abstract class AbstractSqlEamDb implements EamDb { if (null == correlationCaseWithId) { correlationCaseWithId = newCase(eamArtifact.getCorrelationCase()); } - - if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDeviceID())) { + if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getCaseDataSourceID())) { newDataSource(eamArtifact.getCorrelationDataSource()); } eamArtifact.setKnownStatus(knownStatus); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java index 68ef26ff7d..444fe9e259 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java @@ -41,20 +41,22 @@ public class CorrelationDataSource implements Serializable { private final String name; /** - * @param correlationCase CorrelationCase object data source is associated with. Must have been created by EamDB and have a valid ID. - * @param deviceId User specified case-specific ID - * @param name Display name of data source + * @param correlationCase CorrelationCase object data source is associated + * with. Must have been created by EamDB and have a + * valid ID. + * @param deviceId User specified case-specific ID + * @param name Display name of data source */ public CorrelationDataSource(CorrelationCase correlationCase, String deviceId, String name, long caseDataSourceId) { this(correlationCase.getID(), -1, deviceId, name, caseDataSourceId); - } - + } + /** - * - * @param caseId Row ID for Case in DB + * + * @param caseId Row ID for Case in DB * @param dataSourceId Row ID for this data source in DB (or -1) - * @param deviceId User specified ID for device (unique per case) - * @param name User specified name + * @param deviceId User specified ID for device (unique per case) + * @param name User specified name */ CorrelationDataSource(int caseId, int dataSourceId, @@ -69,8 +71,8 @@ public class CorrelationDataSource implements Serializable { } /** - * Create a CorrelationDataSource object from a TSK Content object. - * This will add it to the central repository. + * Create a CorrelationDataSource object from a TSK Content object. This + * will add it to the central repository. * * @param correlationCase the current CorrelationCase used for ensuring * uniqueness of DataSource @@ -88,21 +90,24 @@ public class CorrelationDataSource implements Serializable { } catch (NoCurrentCaseException ex) { throw new EamDbException("Autopsy case is closed"); } - String deviceId; - try { - deviceId = curCase.getSleuthkitCase().getDataSource(dataSource.getId()).getDeviceId(); - } catch (TskDataException | TskCoreException ex) { - throw new EamDbException("Error getting data source info: " + ex.getMessage()); - } - + CorrelationDataSource correlationDataSource = null; - if (EamDbUtil.useCentralRepo()) { - correlationDataSource = EamDb.getInstance().getDataSource(correlationCase, deviceId); + boolean useCR = EamDbUtil.useCentralRepo(); + if (useCR) { + correlationDataSource = EamDb.getInstance().getDataSource(correlationCase, dataSource.getId()); } + if (correlationDataSource == null) { + String deviceId; + try { + deviceId = curCase.getSleuthkitCase().getDataSource(dataSource.getId()).getDeviceId(); + } catch (TskDataException | TskCoreException ex) { + throw new EamDbException("Error getting data source info: " + ex.getMessage()); + } correlationDataSource = new CorrelationDataSource(correlationCase, deviceId, dataSource.getName(), dataSource.getId()); - if (EamDbUtil.useCentralRepo()) { - EamDb.getInstance().newDataSource(correlationDataSource); + if (useCR) { + //add the correlation data source to the central repository and fill in the Central repository data source id in the object + correlationDataSource = EamDb.getInstance().newDataSource(correlationDataSource); } } return correlationDataSource; @@ -146,13 +151,13 @@ public class CorrelationDataSource implements Serializable { public int getCaseID() { return caseID; } - + /** * Get the id for the data source in the case db - * + * * @return caseDataSourceID or NULL if not available */ - Long getCaseDataSourceID(){ + public Long getCaseDataSourceID() { return caseDataSourceID; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 95584d0ebe..358fe93b0d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -195,7 +195,7 @@ public interface EamDb { * * @param eamDataSource the data source to add */ - void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException; + CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource) throws EamDbException; /** * Retrieves Data Source details based on data source device ID @@ -206,7 +206,7 @@ public interface EamDb { * * @return The data source */ - CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException; + CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException; /** * Retrieves Data Source details based on data source ID @@ -309,7 +309,7 @@ public interface EamDb { * @return Number of artifact instances having caseDisplayName and * dataSource */ - Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException; + Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource) throws EamDbException; /** * Adds an eamArtifact to an internal list to be later added to DB. Artifact diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 6468801a57..d702bde5b1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -362,10 +362,10 @@ final class SqliteEamDb extends AbstractSqlEamDb { * @param eamDataSource the data source to add */ @Override - public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException { + public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource) throws EamDbException { try { acquireExclusiveLock(); - super.newDataSource(eamDataSource); + return super.newDataSource(eamDataSource); } finally { releaseExclusiveLock(); } @@ -381,10 +381,10 @@ final class SqliteEamDb extends AbstractSqlEamDb { * @return The data source */ @Override - public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { + public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException { try { acquireSharedLock(); - return super.getDataSource(correlationCase, dataSourceDeviceId); + return super.getDataSource(correlationCase, caseDbDataSourceId); } finally { releaseSharedLock(); } @@ -556,10 +556,10 @@ final class SqliteEamDb extends AbstractSqlEamDb { * dataSource */ @Override - public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException { + public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource) throws EamDbException { try { acquireSharedLock(); - return super.getCountArtifactInstancesByCaseDataSource(caseUUID, dataSourceID); + return super.getCountArtifactInstancesByCaseDataSource(correlationDataSource); } finally { releaseSharedLock(); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 2643c7aac5..ffff8c7b8b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -443,19 +443,16 @@ final class CaseEventListener implements PropertyChangeListener { Content newDataSource = dataSourceAddedEvent.getDataSource(); try { - String deviceId = openCase.getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId(); CorrelationCase correlationCase = dbManager.getCase(openCase); if (null == correlationCase) { correlationCase = dbManager.newCase(openCase); } - if (null == dbManager.getDataSource(correlationCase, deviceId)) { + if (null == dbManager.getDataSource(correlationCase, newDataSource.getId())) { CorrelationDataSource.fromTSKDataSource(correlationCase, newDataSource); } } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error adding new data source to the central repository", ex); //NON-NLS - } catch (TskCoreException | TskDataException ex) { - LOGGER.log(Level.SEVERE, "Error getting data source from DATA_SOURCE_ADDED event content.", ex); //NON-NLS - } + } } // DATA_SOURCE_ADDED } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 62a10aebb2..f77f90b38f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -192,7 +192,7 @@ final class IngestModule implements FileIngestModule { logger.log(Level.SEVERE, "Error doing bulk insert of artifacts.", ex); // NON-NLS } try { - Long count = dbManager.getCountArtifactInstancesByCaseDataSource(eamCase.getCaseUUID(), eamDataSource.getDeviceID()); + Long count = dbManager.getCountArtifactInstancesByCaseDataSource(eamDataSource); logger.log(Level.INFO, "{0} artifacts in db for case: {1} ds:{2}", new Object[]{count, eamCase.getDisplayName(), eamDataSource.getName()}); // NON-NLS } catch (EamDbException ex) { logger.log(Level.SEVERE, "Error counting artifacts.", ex); // NON-NLS @@ -303,7 +303,7 @@ final class IngestModule implements FileIngestModule { == 1) { // ensure we have this data source in the EAM DB try { - if (null == centralRepoDb.getDataSource(eamCase, eamDataSource.getDeviceID())) { + if (null == centralRepoDb.getDataSource(eamCase, eamDataSource.getCaseDataSourceID())) { centralRepoDb.newDataSource(eamDataSource); } } catch (EamDbException ex) { From 1da24f1aec0544e161e5651010b111afd1e08549 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 15 Nov 2018 00:49:53 -0500 Subject: [PATCH 14/32] Cleanup. --- Core/src/org/sleuthkit/autopsy/core/layer.xml | 5 - .../Bundle.properties | 7 + .../CorrelationAttributeInstanceNode.java} | 110 +++--- .../CorrelationPropertyFilterChildren.java | 84 ++++ .../CorrelationPropertyFilterNode.java | 134 +++++++ .../CorrelationPropertySearchAction.java} | 22 +- .../CorrelationPropertySearchChildren.java | 49 +++ .../CorrelationPropertySearchDialog.form | 135 +++++++ .../CorrelationPropertySearchDialog.java | 359 ++++++++++++++++++ .../CorrelationPropertySearchNode.java | 50 +++ .../datamodel/DisplayableItemNodeVisitor.java | 14 +- .../autopsy/md5search/Bundle.properties | 6 - ...CorrelationAttributeInstanceChildNode.java | 123 ------ ...tionAttributeInstanceChildNodeFactory.java | 68 ---- .../CorrelationAttributeSearchResults.java | 25 -- .../DlgCorrelationAttributeInstanceNode.java | 143 ------- .../autopsy/md5search/DlgFilterChildren.java | 39 -- .../autopsy/md5search/DlgFilterNode.java | 79 ---- .../autopsy/md5search/DlgSearchChildren.java | 34 -- .../autopsy/md5search/DlgSearchNode.java | 29 -- .../autopsy/md5search/Md5SearchDialog.form | 145 ------- .../autopsy/md5search/Md5SearchDialog.java | 282 -------------- .../autopsy/report/ReportWizardAction.java | 4 +- .../AutoIngestDashboardOpenAction.java | 4 +- 24 files changed, 884 insertions(+), 1066 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties rename Core/src/org/sleuthkit/autopsy/{md5search/CorrelationAttributeInstanceRootNode.java => correlationpropertysearch/CorrelationAttributeInstanceNode.java} (59%) create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java rename Core/src/org/sleuthkit/autopsy/{md5search/Md5SearchAction.java => correlationpropertysearch/CorrelationPropertySearchAction.java} (55%) create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java create mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form delete mode 100755 Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 546ec757ec..8bdde0f317 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -78,7 +78,6 @@ - @@ -202,10 +201,6 @@ - - - - diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties new file mode 100755 index 0000000000..e3ceab0960 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties @@ -0,0 +1,7 @@ +CorrelationPropertySearchDialog.errorLabel.text= +CorrelationPropertySearchDialog.correlationValueTextField.text= +CorrelationPropertySearchDialog.correlationTypeLabel.text=Correlation Property Type: +CorrelationPropertySearchDialog.correlationValueLabel.text=Correlation Property Value: +CorrelationPropertySearchDialog.searchButton.text=Search +CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleName=Search +CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleDescription= diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java similarity index 59% rename from Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java rename to Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java index 43b67b57a9..c277154033 100755 --- a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceRootNode.java +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java @@ -1,5 +1,4 @@ /* - * * Autopsy Forensic Browser * * Copyright 2018 Basis Technology Corp. @@ -17,43 +16,45 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.md5search; +package org.sleuthkit.autopsy.correlationpropertysearch; -import org.sleuthkit.autopsy.commonfilesearch.*; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.Action; -import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; -import org.openide.nodes.Node; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; /** - * Used by the Common Files search feature to encapsulate instances of a given - * MD5s matched in the search. These nodes will be children of Md5Nodes. - * - * Use this type for files which are not in the current case, but from the - * Central Repo. Contrast with SleuthkitCase which should be used - * when the FileInstance was found in the case presently open in Autopsy. + * Used by the Correlation Property Search feature to encapsulate instances of a + * given search match. */ -final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { +public class CorrelationAttributeInstanceNode extends DisplayableItemNode { - public CorrelationAttributeInstanceRootNode(Children children) { - super(children); - } - - //private final CorrelationAttributeInstance crFile; + private final CorrelationAttributeInstance instance; - //CorrelationAttributeInstanceRootNode(CorrelationAttributeSearchResults data) { - //super(Children.create(new FileInstanceNodeFactory(data), true)); - //} + CorrelationAttributeInstanceNode(CorrelationAttributeInstance content) { + super(Children.LEAF, Lookups.fixed(content)); + this.instance = content; + this.setDisplayName(new File(this.instance.getFilePath()).getName()); + } + + /** + * Get the CorrelationAttributeInstance attached to the node. + * + * @return The CorrelationAttributeInstance object. + */ + public CorrelationAttributeInstance getCorrelationAttributeInstance(){ + return this.instance; + } @Override public Action[] getActions(boolean context){ @@ -66,8 +67,7 @@ final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { @Override public T accept(DisplayableItemNodeVisitor visitor) { - return null; - //return visitor.visit(this); + return visitor.visit(this); } @Override @@ -77,12 +77,11 @@ final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { @Override public String getItemType() { - //objects of type FileNode will co-occur in the treetable with objects - // of this type and they will need to provide the same key - return CaseDBCommonAttributeInstanceNode.class.getName(); + return CorrelationAttributeInstanceNode.class.getName(); } @NbBundle.Messages({ + "CorrelationAttributeInstanceNode.columnName.name=Name", "CorrelationAttributeInstanceNode.columnName.case=Case", "CorrelationAttributeInstanceNode.columnName.dataSource=Data Source", "CorrelationAttributeInstanceNode.columnName.known=Known", @@ -93,7 +92,7 @@ final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { @Override protected Sheet createSheet(){ Sheet sheet = new Sheet(); - /*Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); if(sheetSet == null){ sheetSet = Sheet.createPropertiesSet(); @@ -102,61 +101,40 @@ final class CorrelationAttributeInstanceRootNode extends DisplayableItemNode { final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); - final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); - final String dataSourceName = centralRepoFile.getCorrelationDataSource().getName(); - //DLG: final ? knownStatus - final String fullPath = centralRepoFile.getFilePath(); - //DLG: final String comment - //DLG: final String deviceId - - final File file = new File(fullPath); + final String path = centralRepoFile.getFilePath(); + final File file = new File(path); final String name = file.getName(); - final String parent = file.getParent(); - + final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); + final CorrelationDataSource dataSource = centralRepoFile.getCorrelationDataSource(); + final String dataSourceName = dataSource.getName(); + final String known = centralRepoFile.getKnownStatus().getName(); + final String comment = centralRepoFile.getComment(); + final String device = dataSource.getDeviceID(); + final String NO_DESCR = ""; + + sheetSet.put(new NodeProperty<>( + Bundle.CorrelationAttributeInstanceNode_columnName_name(), + Bundle.CorrelationAttributeInstanceNode_columnName_name(), NO_DESCR, name)); sheetSet.put(new NodeProperty<>( Bundle.CorrelationAttributeInstanceNode_columnName_case(), - Bundle.CorrelationAttributeInstanceNode_columnName_case(), "", name)); + Bundle.CorrelationAttributeInstanceNode_columnName_case(), NO_DESCR, caseName)); sheetSet.put(new NodeProperty<>( Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), - Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), "", parent)); + Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), NO_DESCR, dataSourceName)); sheetSet.put(new NodeProperty<>( Bundle.CorrelationAttributeInstanceNode_columnName_known(), - Bundle.CorrelationAttributeInstanceNode_columnName_known(), "", "")); + Bundle.CorrelationAttributeInstanceNode_columnName_known(), NO_DESCR, known)); sheetSet.put(new NodeProperty<>( Bundle.CorrelationAttributeInstanceNode_columnName_path(), - Bundle.CorrelationAttributeInstanceNode_columnName_path(), "", dataSourceName)); + Bundle.CorrelationAttributeInstanceNode_columnName_path(), NO_DESCR, path)); sheetSet.put(new NodeProperty<>( Bundle.CorrelationAttributeInstanceNode_columnName_comment(), - Bundle.CorrelationAttributeInstanceNode_columnName_comment(), "", "")); + Bundle.CorrelationAttributeInstanceNode_columnName_comment(), NO_DESCR, comment)); sheetSet.put(new NodeProperty<>( Bundle.CorrelationAttributeInstanceNode_columnName_device(), - Bundle.CorrelationAttributeInstanceNode_columnName_device(), "", caseName));*/ + Bundle.CorrelationAttributeInstanceNode_columnName_device(), NO_DESCR, device)); return sheet; } - - /** - * Child generator for SleuthkitCaseFileInstanceNode of - * CommonAttributeValueNode. - */ - static class FileInstanceNodeFactory extends ChildFactory { - - private final CommonAttributeValue descendants; - - FileInstanceNodeFactory(CommonAttributeValue descendants) { - this.descendants = descendants; - } - - @Override - protected boolean createKeys(List list) { - return true; - } - - /*@Override - protected Node[] createNodesForKey(AbstractCommonAttributeInstance searchResult) { - return null; - //return searchResult.generateNodes(); - }*/ - } } diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java new file mode 100755 index 0000000000..4c3c443944 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java @@ -0,0 +1,84 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.correlationpropertysearch; + +import org.openide.nodes.Children; +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; + +/** + * A Children implementation for a + * CorrelationPropertyFilterNode. + */ +class CorrelationPropertyFilterChildren extends FilterNode.Children { + + /** + * Create a new Children instance. + * + * @param wrappedNode The node to be wrapped. + * @param createChildren If false, return LEAF. Otherwise, return a new + * CorrelationPropertyFilterChildren instance. + * + * @return A Children instance. + */ + public static Children createInstance(Node wrappedNode, boolean createChildren) { + + if (createChildren) { + return new CorrelationPropertyFilterChildren(wrappedNode); + } else { + return Children.LEAF; + } + } + + /** + * Constructs a children (child factory) implementation for a + * CorrelationPropertyFilterNode. + * + * @param wrappedNode The node wrapped by CorrelationPropertyFilterNode. + */ + CorrelationPropertyFilterChildren(Node wrappedNode) { + super(wrappedNode); + } + + /** + * Copies a CorrelationPropertyFilterNode, with the children (child factory) + * flag set to false. + * + * @param nodeToCopy The CorrelationPropertyFilterNode to copy. + * + * @return A copy of a CorrelationPropertyFilterNode. + */ + @Override + protected Node copyNode(Node nodeToCopy) { + return new CorrelationPropertyFilterNode(nodeToCopy, false); + } + + /** + * Creates the child nodes represented by this children (child factory) + * object. + * + * @param key The key, i.e., the node, for which to create the child nodes. + * + * @return A single-element node array. + */ + @Override + protected Node[] createNodes(Node key) { + return new Node[]{this.copyNode(key)}; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java new file mode 100755 index 0000000000..fa5c1ecaa1 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java @@ -0,0 +1,134 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.correlationpropertysearch; + +import org.openide.nodes.FilterNode; +import org.openide.nodes.Node; +import org.openide.util.NbBundle; +import org.openide.util.lookup.Lookups; +import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; +import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; + +/** + * FilterNode containing properties and actions for Correlation Property Search. + */ +public class CorrelationPropertyFilterNode extends FilterNode { + + private final boolean createChildren; + private final boolean forceUseWrappedDisplayName; + private String columnOrderKey = "NONE"; + + /** + * Constructs a filter node that creates at most one layer of child nodes + * for the node it wraps. It is designed to be used in the results view to + * ensure the individual viewers display only the first layer of child + * nodes. + * + * @param node The node to wrap in the filter node. + * @param createChildren True if a Children object should be created for the + * wrapped node. + */ + public CorrelationPropertyFilterNode(Node node, boolean createChildren) { + super(node, CorrelationPropertyFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + this.forceUseWrappedDisplayName = false; + this.createChildren = createChildren; + } + + /** + * Constructs a filter node that creates at most one layer of child nodes + * for the node it wraps. It is designed to be used in the results view to + * ensure the individual viewers display only the first layer of child + * nodes. + * + * @param node The node to wrap in the filter node. + * @param createChildren True if a Children object should be created for the + * wrapped node. + * @param columnOrderKey A key that represents the type of the original + * wrapped node and what is being displayed under that node. + */ + public CorrelationPropertyFilterNode(Node node, boolean createChildren, String columnOrderKey) { + super(node, CorrelationPropertyFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + this.forceUseWrappedDisplayName = false; + this.createChildren = createChildren; + this.columnOrderKey = columnOrderKey; + } + + /** + * Gets the display name for the wrapped node, for use in the first column + * of an Autopsy table view. + * + * @return The display name. + */ + @Override + public String getDisplayName() { + if (this.forceUseWrappedDisplayName) { + return super.getDisplayName(); + } else if (createChildren) { + return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text"); + } else { + return super.getDisplayName(); + } + } + + /** + * Adds information about which child node of this node, if any, should be + * selected. Can be null. + * + * @param selectedChildNodeInfo The child node selection information. + */ + public void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { + /* + * Currently, child selection is only supported for nodes selected in + * the tree view and decorated with a DataResultFilterNode. + */ + if (getOriginal() instanceof DataResultFilterNode) { + ((DataResultFilterNode) getOriginal()).setChildNodeSelectionInfo(selectedChildNodeInfo); + } + } + + /** + * Gets information about which child node of this node, if any, should be + * selected. + * + * @return The child node selection information, or null if no child should + * be selected. + */ + public NodeSelectionInfo getChildNodeSelectionInfo() { + /* + * Currently, child selection is only supported for nodes selected in + * the tree view and decorated with a DataResultFilterNode. + */ + if (getOriginal() instanceof DataResultFilterNode) { + return ((DataResultFilterNode) getOriginal()).getChildNodeSelectionInfo(); + } else { + return null; + } + } + + /** + * @return the column order key, which allows custom column ordering to be + * written into a properties file and be reloaded for future use in a table + * with the same root node or for different cases. This is done by + * DataResultViewerTable. The key should represent what kinds of items the + * table is showing. + */ + public String getColumnOrderKey() { + return columnOrderKey; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchAction.java similarity index 55% rename from Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java rename to Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchAction.java index a231e389fb..74facdff65 100755 --- a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchAction.java @@ -16,22 +16,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.md5search; +package org.sleuthkit.autopsy.correlationpropertysearch; import java.awt.event.ActionEvent; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionRegistration; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; /** - * //DLG: + * Action for accessing the Correlation Property Search dialog. */ -public class Md5SearchAction extends CallableSystemAction { +@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.correlationpropertysearch.CorrelationPropertySearchAction") +@ActionRegistration(displayName = "#CTL_CorrelationPropertySearchAction=Correlation Property Search", lazy = false) +@ActionReference(path = "Menu/Tools", position = 104) +@NbBundle.Messages({"CTL_CorrelationPropertySearchAction=Correlation Property Search"}) +public class CorrelationPropertySearchAction extends CallableSystemAction { @Override public boolean isEnabled() { - return super.isEnabled() && Case.isCaseOpen(); + return EamDb.isEnabled() && Case.isCaseOpen(); } @Override @@ -41,15 +49,15 @@ public class Md5SearchAction extends CallableSystemAction { @Override public void performAction() { - Md5SearchDialog dialog = new Md5SearchDialog(); + CorrelationPropertySearchDialog dialog = new CorrelationPropertySearchDialog(); dialog.display(); } @NbBundle.Messages({ - "Md5SearchAction.getName.text=Correlation Attribute Search"}) + "CorrelationPropertySearchAction.getName.text=Correlation Property Search"}) @Override public String getName() { - return Bundle.Md5SearchAction_getName_text(); + return Bundle.CorrelationPropertySearchAction_getName_text(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java new file mode 100755 index 0000000000..9e1d20f2ef --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java @@ -0,0 +1,49 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.correlationpropertysearch; + +import java.util.List; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; + +/** + * Creates CorrelationAttributeInstanceNodes from a collection of + * CorrelationAttributeInstances. + */ +class CorrelationPropertySearchChildren extends Children.Keys { + + /** + * Create an instance of CorrelationPropertySearchChildren. + * + * @param lazy Lazy load? + * @param fileList List of CorrelationAttributeInstances. + */ + CorrelationPropertySearchChildren(boolean lazy, List instances) { + super(lazy); + this.setKeys(instances); + } + + @Override + protected Node[] createNodes(CorrelationAttributeInstance t) { + Node[] node = new Node[1]; + node[0] = new CorrelationAttributeInstanceNode(t); + return node; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form new file mode 100755 index 0000000000..347008824c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form @@ -0,0 +1,135 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java new file mode 100755 index 0000000000..f22acbfea5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java @@ -0,0 +1,359 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.correlationpropertysearch; + +import java.awt.Color; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JFrame; +import javax.swing.SwingWorker; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; +import org.openide.windows.TopComponent; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributesSearchResultsViewerTable; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; +import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; +import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; +import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.corecomponents.TextPrompt; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.EmptyNode; + +@Messages({ + "CorrelationPropertySearchDialog.title.text=Correlation Property Search", + "CorrelationPropertySearchDialog.results.text=Correlation Properties", + "CorrelationPropertySearchDialog.emptyNode.text=No results found.", + "CorrelationPropertySearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash." +}) +/** + * The Correlation Property Search dialog allows users to search for specific + * types of correlation properties in the Central Repository. + */ +public class CorrelationPropertySearchDialog extends javax.swing.JDialog { + private static final Logger logger = Logger.getLogger(CorrelationPropertySearchDialog.class.getName()); + + private static final String FILES_CORRELATION_TYPE = "Files"; + + private final List correlationTypes; + private TextPrompt correlationValueTextFieldPrompt; + + /** + * Creates a new instance of the Correlation Property Search dialog. + */ + public CorrelationPropertySearchDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.CorrelationPropertySearchDialog_title_text(), true); + this.correlationTypes = new ArrayList<>(); + initComponents(); + customizeComponents(); + } + + /** + * Perform the correlation property search. + */ + private void search() { + new SwingWorker, Void>() { + + @Override + protected List doInBackground() { + List correlationTypes; + List correlationInstances = new ArrayList<>(); + + try { + correlationTypes = EamDb.getInstance().getDefinedCorrelationTypes(); + for (CorrelationAttributeInstance.Type type : correlationTypes) { + if (type.getDisplayName().equals((String) correlationTypeComboBox.getSelectedItem())) { + correlationInstances = EamDb.getInstance().getArtifactInstancesByTypeValue(type, correlationValueTextField.getText()); + break; + } + } + } catch (EamDbException ex) { + logger.log(Level.SEVERE, "Unable to connect to the Central Repository database.", ex); + } catch (CorrelationAttributeNormalizationException ex) { + logger.log(Level.SEVERE, "Unable to retrieve data from the Central Repository.", ex); + } + + return correlationInstances; + } + + @Override + protected void done() { + try { + super.done(); + List correlationInstances = this.get(); + DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable(); + Collection viewers = new ArrayList<>(1); + viewers.add(table); + + CorrelationPropertySearchNode searchNode = new CorrelationPropertySearchNode(correlationInstances); + CorrelationPropertyFilterNode tableFilterNode = new CorrelationPropertyFilterNode(searchNode, true, searchNode.getName()); + + String resultsText = String.format("%s (%s; \"%s\")", + Bundle.CorrelationPropertySearchDialog_results_text(), + (String) correlationTypeComboBox.getSelectedItem(), + correlationValueTextField.getText()); + final TopComponent searchResultWin; + if (correlationInstances.isEmpty()) { + Node emptyNode = new TableFilterNode( + new EmptyNode(Bundle.CorrelationPropertySearchDialog_emptyNode_text()), true); + searchResultWin = DataResultTopComponent.createInstance( + resultsText, Bundle.CorrelationPropertySearchDialog_title_text(), emptyNode, 0); + } else { + searchResultWin = DataResultTopComponent.createInstance( + resultsText, Bundle.CorrelationPropertySearchDialog_title_text(), tableFilterNode, HIDE_ON_CLOSE, viewers); + } + searchResultWin.requestActive(); // make it the active top component + } catch (ExecutionException | InterruptedException ex) { + logger.log(Level.SEVERE, "Unable to get CorrelationAttributeInstances.", ex); + } + } + }.execute(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + correlationValueLabel = new javax.swing.JLabel(); + correlationValueTextField = new javax.swing.JTextField(); + searchButton = new javax.swing.JButton(); + correlationTypeComboBox = new javax.swing.JComboBox<>(); + correlationTypeLabel = new javax.swing.JLabel(); + errorLabel = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setResizable(false); + + org.openide.awt.Mnemonics.setLocalizedText(correlationValueLabel, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.correlationValueLabel.text")); // NOI18N + + correlationValueTextField.setText(org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.correlationValueTextField.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.searchButton.text")); // NOI18N + searchButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + searchButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(correlationTypeLabel, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.correlationTypeLabel.text")); // NOI18N + + errorLabel.setForeground(new java.awt.Color(255, 0, 0)); + org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.errorLabel.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(18, 18, 18) + .addComponent(searchButton)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(correlationValueLabel) + .addComponent(correlationTypeLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(correlationTypeComboBox, 0, 289, Short.MAX_VALUE) + .addComponent(correlationValueTextField)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(correlationTypeLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(correlationValueLabel) + .addComponent(correlationValueTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(searchButton) + .addComponent(errorLabel)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + searchButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleName")); // NOI18N + searchButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleDescription")); // NOI18N + + pack(); + }// //GEN-END:initComponents + + private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed + if (validateInputs()) { + /* + * Just in case, we'll lock down the type and value components to + * avoid the possibly of a race condition. + */ + correlationTypeComboBox.setEnabled(false); + correlationValueTextField.setEnabled(false); + + search(); + dispose(); + } else { + searchButton.setEnabled(false); + errorLabel.setText(Bundle.CorrelationPropertySearchDialog_validation_invalidHash()); + correlationValueTextField.grabFocus(); + } + }//GEN-LAST:event_searchButtonActionPerformed + + /** + * Further customize the components beyond the standard initialization. + */ + private void customizeComponents() { + searchButton.setEnabled(false); + + /* + * Add correlation types to the combo-box. + */ + try { + EamDb dbManager = EamDb.getInstance(); + correlationTypes.clear(); + correlationTypes.addAll(dbManager.getDefinedCorrelationTypes()); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + } + + for (CorrelationAttributeInstance.Type type : correlationTypes) { + // We only support the "Files" type for now. + if (type.getDisplayName().equals(FILES_CORRELATION_TYPE)) { + correlationTypeComboBox.addItem(type.getDisplayName()); + } + } + correlationTypeComboBox.setSelectedIndex(0); + + correlationTypeComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + updateSearchButton(); + } + }); + + /* + * Create listener for text input. + */ + correlationValueTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + updateSearchButton(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + updateSearchButton(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updateSearchButton(); + } + }); + + updateCorrelationValueTextFieldPrompt(); + } + + @Messages({ + "CorrelationPropertySearchDialog.correlationValueTextField.filesExample=Example: \"f0e1d2c3b4a5968778695a4b3c2d1e0f\"" + }) + /** + * Update the text prompt of the name text field based on the input type + * selection. + */ + private void updateCorrelationValueTextFieldPrompt() { + /** + * Add text prompt to the text field. + */ + String text = Bundle.CorrelationPropertySearchDialog_correlationValueTextField_filesExample(); + correlationValueTextFieldPrompt = new TextPrompt(text, correlationValueTextField); + + /** + * Sets the foreground color and transparency of the text prompt. + */ + correlationValueTextFieldPrompt.setForeground(Color.LIGHT_GRAY); + correlationValueTextFieldPrompt.changeAlpha(0.9f); // Mostly opaque + + validate(); + repaint(); + } + + /** + * Enable or disable the Search button depending on whether or not text has + * been provided for the correlation property value. + */ + private void updateSearchButton() { + searchButton.setEnabled(correlationValueTextField.getText().isEmpty() == false); + } + + /** + * Validate the value input. + * + * @return True if the input is valid for the selected type; otherwise false. + */ + private boolean validateInputs() { + Pattern md5Pattern = Pattern.compile("^[a-fA-F0-9]{32}$"); // NON-NLS + Matcher matcher = md5Pattern.matcher(correlationValueTextField.getText().trim()); + if (matcher.find()) { + return true; + } + return false; + } + + /** + * Display the Correlation Property Search dialog. + */ + public void display() { + this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + setVisible(true); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox correlationTypeComboBox; + private javax.swing.JLabel correlationTypeLabel; + private javax.swing.JLabel correlationValueLabel; + private javax.swing.JTextField correlationValueTextField; + private javax.swing.JLabel errorLabel; + private javax.swing.JButton searchButton; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java new file mode 100755 index 0000000000..17b1d979c4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java @@ -0,0 +1,50 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.correlationpropertysearch; + +import java.util.List; +import org.openide.nodes.AbstractNode; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; + +/** + * Parent node to CorrelationPropertySearchChildren. + */ +class CorrelationPropertySearchNode extends AbstractNode { + + private CorrelationPropertySearchChildren children; + + /** + * Create an instance of CorrelationPropertySearchNode. + * + * @param keys The list of CorrelationAttributeInstances. + */ + CorrelationPropertySearchNode(List keys) { + super(new CorrelationPropertySearchChildren(true, keys)); + this.children = (CorrelationPropertySearchChildren) this.getChildren(); + } + + @Messages({ + "CorrelationPropertySearchNode.getName.text=Correlation Property Search" + }) + @Override + public String getName() { + return Bundle.CorrelationPropertySearchNode_getName_text(); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index dbd06ac8dc..d9d2ffea84 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -29,8 +29,7 @@ import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNod import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.datamodel.accounts.Accounts; -import org.sleuthkit.autopsy.md5search.CorrelationAttributeInstanceChildNode; -import org.sleuthkit.autopsy.md5search.DlgCorrelationAttributeInstanceNode; +import org.sleuthkit.autopsy.correlationpropertysearch.CorrelationAttributeInstanceNode; /** * Visitor pattern that goes over all nodes in the directory tree. This includes @@ -128,9 +127,7 @@ public interface DisplayableItemNodeVisitor { T visit(InstanceCountNode icn); - T visit(CorrelationAttributeInstanceChildNode caicn); - - T visit(DlgCorrelationAttributeInstanceNode cain); //DLG: + T visit(CorrelationAttributeInstanceNode cain); /* * Tags @@ -221,12 +218,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(CorrelationAttributeInstanceChildNode caicn){ - return defaultVisit(caicn); - } - - @Override - public T visit(DlgCorrelationAttributeInstanceNode cain) { + public T visit(CorrelationAttributeInstanceNode cain) { return defaultVisit(cain); } diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties b/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties deleted file mode 100755 index 59bdbf31bf..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/Bundle.properties +++ /dev/null @@ -1,6 +0,0 @@ - -Md5SearchDialog.jButton1.text=Search -Md5SearchDialog.jTextField1.text= -Md5SearchDialog.jLabel1.text=Correlation Property Value: -Md5SearchDialog.jLabel2.text=Correlation Property Type: -Md5SearchDialog.jTextArea1.text=Type a value into the Correlation Property Value field. When the input type is detected, the Correlation Property Type field will become available and default to the detected input type. diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java deleted file mode 100755 index 49c525bd7a..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNode.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import javax.swing.Action; -import org.openide.nodes.Children; -import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; -import org.sleuthkit.autopsy.datamodel.NodeProperty; - -/** - * //DLG: - */ -public final class CorrelationAttributeInstanceChildNode extends DisplayableItemNode { - private String caseName; - private String dataSourceName; - //DLG: final ? knownStatus - private String fullPath; - //DLG: final String comment - //DLG: final String deviceId - private String name; - private String parent; - - public CorrelationAttributeInstanceChildNode(Children children) { - super(children); - } - - //CorrelationAttributeInstanceChildNode(Children children) { - // init(null); - //} - - private void init(Map map) { - caseName = (String)map.get("caseName"); - dataSourceName = (String)map.get("dataSourceName"); - fullPath = (String)map.get("fullPath"); - name = (String)map.get("name"); - parent = (String)map.get("parent"); - } - - @Override - public Action[] getActions(boolean context){ - List actionsList = new ArrayList<>(); - - actionsList.addAll(Arrays.asList(super.getActions(true))); - - return actionsList.toArray(new Action[actionsList.size()]); - } - - /*@Override - public T accept(DisplayableItemNodeVisitor visitor) { - return visitor.visit(this); - }*/ - - @Override - public T accept(DisplayableItemNodeVisitor visitor) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isLeafTypeNode() { - return true; - } - - @Override - public String getItemType() { - //objects of type FileNode will co-occur in the treetable with objects - // of this type and they will need to provide the same key - return CorrelationAttributeInstanceChildNode.class.getName(); - } - - @NbBundle.Messages({ - "CorrelationAttributeInstanceChildNode.columnName.case=Case", - "CorrelationAttributeInstanceChildNode.columnName.dataSource=Data Source", - "CorrelationAttributeInstanceChildNode.columnName.known=Known", - "CorrelationAttributeInstanceChildNode.columnName.path=Path", - "CorrelationAttributeInstanceChildNode.columnName.comment=Comment", - "CorrelationAttributeInstanceChildNode.columnName.device=Device" - }) - @Override - protected Sheet createSheet(){ - Sheet sheet = new Sheet(); - Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); - - if(sheetSet == null){ - sheetSet = Sheet.createPropertiesSet(); - sheet.put(sheetSet); - } - - - sheetSet.put(new NodeProperty<>( - Bundle.CorrelationAttributeInstanceNode_columnName_case(), - Bundle.CorrelationAttributeInstanceNode_columnName_case(), "", name)); - sheetSet.put(new NodeProperty<>( - Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), - Bundle.CorrelationAttributeInstanceNode_columnName_dataSource(), "", parent)); - sheetSet.put(new NodeProperty<>( - Bundle.CorrelationAttributeInstanceNode_columnName_known(), - Bundle.CorrelationAttributeInstanceNode_columnName_known(), "", "")); - sheetSet.put(new NodeProperty<>( - Bundle.CorrelationAttributeInstanceNode_columnName_path(), - Bundle.CorrelationAttributeInstanceNode_columnName_path(), "", dataSourceName)); - sheetSet.put(new NodeProperty<>( - Bundle.CorrelationAttributeInstanceNode_columnName_comment(), - Bundle.CorrelationAttributeInstanceNode_columnName_comment(), "", "")); - sheetSet.put(new NodeProperty<>( - Bundle.CorrelationAttributeInstanceNode_columnName_device(), - Bundle.CorrelationAttributeInstanceNode_columnName_device(), "", caseName)); - - return sheet; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java deleted file mode 100755 index b30a11e06f..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeInstanceChildNodeFactory.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import java.io.File; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.openide.nodes.ChildFactory; -import org.openide.nodes.Children; -import org.openide.nodes.Node; -import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.datamodel.KeyValue; -import org.sleuthkit.autopsy.datamodel.KeyValueNode; - -/** - * //DLG: - */ -final class CorrelationAttributeInstanceChildNodeFactory extends ChildFactory { - private final Collection correlationInstances; - - CorrelationAttributeInstanceChildNodeFactory(Collection correlationInstances) { - this.correlationInstances = correlationInstances; - } - - @Override - protected boolean createKeys(List list) { - for (CorrelationAttributeInstance instance : correlationInstances) { - Map properties = new HashMap<>(); //DLG: - - final String caseName = instance.getCorrelationCase().getDisplayName(); - final String dataSourceName = instance.getCorrelationDataSource().getName(); - //DLG: final ? knownStatus - final String fullPath = instance.getFilePath(); - //DLG: final String comment - //DLG: final String deviceId - - final File file = new File(fullPath); - final String name = file.getName(); - final String parent = file.getParent(); - - properties.put("caseName", caseName); - properties.put("dataSourceName", dataSourceName); - properties.put("knownStatus", ""); //DLG: - properties.put("fullPath", fullPath); - properties.put("comment", ""); //DLG: - properties.put("deviceId", ""); //DLG: - properties.put("name", name); - properties.put("parent", parent); - - list.add(new KeyValue(String.valueOf(instance.getID()), properties, instance.getID())); - } - return true; - } - - @Override - protected Node createNodeForKey(KeyValue key) { - Map map = key.getMap(); - Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.fixed(correlationInstances.toArray())); - //DLG: Node resultNode = new CorrelationAttributeInstanceChildNode(kvNode); - return null; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java deleted file mode 100755 index 5c1e0ee004..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/CorrelationAttributeSearchResults.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import java.util.ArrayList; -import java.util.List; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; - -/** - * //DLG: - */ -public class CorrelationAttributeSearchResults { - List correlationInstances = new ArrayList<>(); - - CorrelationAttributeSearchResults(List correlationInstances) { - this.correlationInstances = correlationInstances; - } - - List getCorrelationAttributeInstances() { - return correlationInstances; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java deleted file mode 100755 index 1e6a51850c..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/DlgCorrelationAttributeInstanceNode.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.md5search; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import javax.swing.Action; -import org.openide.nodes.Children; -import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; -import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; -import org.sleuthkit.autopsy.datamodel.NodeProperty; - -/** - * Used by the Common Files search feature to encapsulate instances of a given - * MD5s matched in the search. These nodes will be children of Md5Nodes. - * - * Use this type for files which are not in the current case, but from the - * Central Repo. Contrast with SleuthkitCase which should be used - * when the FileInstance was found in the case presently open in Autopsy. - */ -public class DlgCorrelationAttributeInstanceNode extends DisplayableItemNode { - - private final CorrelationAttributeInstance crFile; - - DlgCorrelationAttributeInstanceNode(CorrelationAttributeInstance content) { - super(Children.LEAF, Lookups.fixed(content)); - this.crFile = content; - this.setDisplayName(new File(this.crFile.getFilePath()).getName()); - } - - public CorrelationAttributeInstance getCorrelationAttributeInstance(){ - return this.crFile; - } - - @Override - public Action[] getActions(boolean context){ - List actionsList = new ArrayList<>(); - - actionsList.addAll(Arrays.asList(super.getActions(true))); - - return actionsList.toArray(new Action[actionsList.size()]); - } - - @Override - public T accept(DisplayableItemNodeVisitor visitor) { - return visitor.visit(this); - } - - @Override - public boolean isLeafTypeNode() { - return true; - } - - @Override - public String getItemType() { - //objects of type FileNode will co-occur in the treetable with objects - // of this type and they will need to provide the same key - return DlgCorrelationAttributeInstanceNode.class.getName(); - } - - @NbBundle.Messages({ - "DlgCorrelationAttributeInstanceNode.columnName.name=Name", - "DlgCorrelationAttributeInstanceNode.columnName.case=Case", - "DlgCorrelationAttributeInstanceNode.columnName.dataSource=Data Source", - "DlgCorrelationAttributeInstanceNode.columnName.known=Known", - "DlgCorrelationAttributeInstanceNode.columnName.path=Path", - "DlgCorrelationAttributeInstanceNode.columnName.comment=Comment", - "DlgCorrelationAttributeInstanceNode.columnName.device=Device" - }) - @Override - protected Sheet createSheet(){ - Sheet sheet = new Sheet(); - Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); - - if(sheetSet == null){ - sheetSet = Sheet.createPropertiesSet(); - sheet.put(sheetSet); - } - - final CorrelationAttributeInstance centralRepoFile = this.getCorrelationAttributeInstance(); - - final String path = centralRepoFile.getFilePath(); - final File file = new File(path); - final String name = file.getName(); - //DLG: final String parent = file.getParent(); - final String caseName = centralRepoFile.getCorrelationCase().getDisplayName(); - final CorrelationDataSource dataSource = centralRepoFile.getCorrelationDataSource(); - final String dataSourceName = dataSource.getName(); - final String known = centralRepoFile.getKnownStatus().getName(); - final String comment = centralRepoFile.getComment(); - final String device = dataSource.getDeviceID(); - - final String NO_DESCR = ""; - - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_name(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_name(), NO_DESCR, name)); - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_case(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_case(), NO_DESCR, caseName)); - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_dataSource(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_dataSource(), NO_DESCR, dataSourceName)); - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_known(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_known(), NO_DESCR, known)); - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_path(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_path(), NO_DESCR, path)); - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_comment(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_comment(), NO_DESCR, comment)); - sheetSet.put(new NodeProperty<>( - Bundle.DlgCorrelationAttributeInstanceNode_columnName_device(), - Bundle.DlgCorrelationAttributeInstanceNode_columnName_device(), NO_DESCR, device)); - - return sheet; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java deleted file mode 100755 index 6ca7c7540c..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterChildren.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import org.openide.nodes.Children; -import org.openide.nodes.FilterNode; -import org.openide.nodes.Node; - -/** - * //DLG: - */ -class DlgFilterChildren extends FilterNode.Children { - - public static Children createInstance(Node wrappedNode, boolean createChildren) { - - if (createChildren) { - return new DlgFilterChildren(wrappedNode); - } else { - return Children.LEAF; - } - } - - DlgFilterChildren(Node wrappedNode) { - super(wrappedNode); - } - - @Override - protected Node copyNode(Node nodeToCopy) { - return new DlgFilterNode(nodeToCopy, false); - } - - @Override - protected Node[] createNodes(Node key) { - return new Node[]{this.copyNode(key)}; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java deleted file mode 100755 index c746637544..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/DlgFilterNode.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import org.openide.nodes.FilterNode; -import org.openide.nodes.Node; -import org.openide.util.NbBundle; -import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; -import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; - -/** - * //DLG: - */ -public class DlgFilterNode extends FilterNode { - - private final boolean createChildren; - private final boolean forceUseWrappedDisplayName; - private String columnOrderKey = "NONE"; - - public DlgFilterNode(Node node, boolean createChildren) { - super(node, DlgFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); - this.forceUseWrappedDisplayName = false; - this.createChildren = createChildren; - } - - public DlgFilterNode(Node node, boolean createChildren, String columnOrderKey) { - super(node, DlgFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); - this.forceUseWrappedDisplayName = false; - this.createChildren = createChildren; - this.columnOrderKey = columnOrderKey; - } - - /*public DlgFilterNode(Node node, int childLayerDepth) { - super(node, TableFilterChildrenWithDescendants.createInstance(node, childLayerDepth), Lookups.proxy(node)); - this.createChildren = true; - this.forceUseWrappedDisplayName = true; - }*/ - - @Override - public String getDisplayName() { - if (this.forceUseWrappedDisplayName) { - return super.getDisplayName(); - } else if (createChildren) { - return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text"); - } else { - return super.getDisplayName(); - } - } - - public void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { - /* - * Currently, child selection is only supported for nodes selected in - * the tree view and decorated with a DataResultFilterNode. - */ - if (getOriginal() instanceof DataResultFilterNode) { - ((DataResultFilterNode) getOriginal()).setChildNodeSelectionInfo(selectedChildNodeInfo); - } - } - - public NodeSelectionInfo getChildNodeSelectionInfo() { - /* - * Currently, child selection is only supported for nodes selected in - * the tree view and decorated with a DataResultFilterNode. - */ - if (getOriginal() instanceof DataResultFilterNode) { - return ((DataResultFilterNode) getOriginal()).getChildNodeSelectionInfo(); - } else { - return null; - } - } - - public String getColumnOrderKey() { - return columnOrderKey; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java deleted file mode 100755 index 3f2c2ad403..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchChildren.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import java.util.List; -import org.openide.nodes.Children; -import org.openide.nodes.Node; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; -import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; -import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; - -/** - * //DLG: - */ -class DlgSearchChildren extends Children.Keys { - - DlgSearchChildren(boolean lazy, List fileList) { - super(lazy); - this.setKeys(fileList); - } - - @Override - protected Node[] createNodes(CorrelationAttributeInstance t) { - //DLG: - Node[] node = new Node[1]; - //DLG: - node[0] = new DlgCorrelationAttributeInstanceNode(t); - return node; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java b/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java deleted file mode 100755 index 6d1a75d39b..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/DlgSearchNode.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import java.util.List; -import org.openide.nodes.AbstractNode; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; - -/** - * //DLG: - */ -class DlgSearchNode extends AbstractNode { - - private DlgSearchChildren children; - - DlgSearchNode(List keys) { - super(new DlgSearchChildren(true, keys)); - this.children = (DlgSearchChildren) this.getChildren(); - } - - @Override - public String getName() { - //DLG: - return /*NbBundle.getMessage(this.getClass(), */"SearchNode.getName.text"/*)*/; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form deleted file mode 100755 index 2ecd2f4475..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.form +++ /dev/null @@ -1,145 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java b/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java deleted file mode 100755 index 3d6413e82a..0000000000 --- a/Core/src/org/sleuthkit/autopsy/md5search/Md5SearchDialog.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.sleuthkit.autopsy.md5search; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.swing.JFrame; -import javax.swing.SwingWorker; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import org.openide.explorer.ExplorerManager; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; -import org.openide.nodes.Node; -import org.openide.util.Exceptions; -import org.openide.util.NbBundle; -import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributesSearchResultsViewerTable; -import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; -import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; -import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; -import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; - -/** - * - * @author dgrove - */ -public class Md5SearchDialog extends javax.swing.JDialog { - private static final String FILES_CORRELATION_TYPE = "Files"; - private final List correlationTypes; - private final Pattern md5Pattern; - - /** - * Creates new form Md5SearchDialog - */ - @NbBundle.Messages({"Md5SearchDialog.title=Correlation Property Search"}) - public Md5SearchDialog() { - super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.Md5SearchDialog_title(), true); - this.correlationTypes = new ArrayList<>(); - this.md5Pattern = Pattern.compile("^[a-fA-F0-9]{32}$"); // NON-NLS - initComponents(); - customizeComponents(); - } - - private void search() { - new SwingWorker, Void>() { - - @Override - protected List doInBackground() { - List correlationTypes; - List correlationInstances = new ArrayList<>(); - - try { - correlationTypes = EamDb.getInstance().getDefinedCorrelationTypes(); - for (CorrelationAttributeInstance.Type type : correlationTypes) { - if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) { - correlationInstances = EamDb.getInstance().getArtifactInstancesByTypeValue(type, jTextField1.getText()); - break; - } - } - } catch (Exception ex) { - //DLG: - } - - return correlationInstances; - } - - @Override - protected void done() { - try { - super.done(); - List correlationInstances = this.get(); - //DLG: Node rootNode = new CorrelationAttributeInstanceRootNode(searchResults); - //DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(rootNode, ExplorerManager.find(Md5SearchDialog.this)); - //TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); - DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable(); - Collection viewers = new ArrayList<>(1); - viewers.add(table); - - DlgSearchNode searchNode = new DlgSearchNode(correlationInstances); - DlgFilterNode tableFilterNode = new DlgFilterNode(searchNode, true, searchNode.getName()); - - //Node rootNode; - //Children childNodes = Children.create(new CorrelationAttributeInstanceChildNodeFactory(correlationInstances), true); - //rootNode = new AbstractNode(childNodes); - DataResultTopComponent results = DataResultTopComponent.createInstance( - "Files", "Correlation Property Search", tableFilterNode, HIDE_ON_CLOSE, viewers); - } catch (InterruptedException ex) { - Exceptions.printStackTrace(ex); //DLG: - } catch (ExecutionException ex) { - Exceptions.printStackTrace(ex); //DLG: - } - } - }.execute(); - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - jLabel1 = new javax.swing.JLabel(); - jTextField1 = new javax.swing.JTextField(); - jButton1 = new javax.swing.JButton(); - correlationTypeComboBox = new javax.swing.JComboBox<>(); - jLabel2 = new javax.swing.JLabel(); - jScrollPane1 = new javax.swing.JScrollPane(); - jTextArea1 = new javax.swing.JTextArea(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - setResizable(false); - - org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jLabel1.text")); // NOI18N - - jTextField1.setText(org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jTextField1.text")); // NOI18N - jTextField1.addInputMethodListener(new java.awt.event.InputMethodListener() { - public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { - } - public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) { - jTextField1InputMethodTextChanged(evt); - } - }); - jTextField1.addPropertyChangeListener(new java.beans.PropertyChangeListener() { - public void propertyChange(java.beans.PropertyChangeEvent evt) { - jTextField1PropertyChange(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jButton1.text")); // NOI18N - jButton1.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - jButton1ActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jLabel2.text")); // NOI18N - - jTextArea1.setEditable(false); - jTextArea1.setColumns(20); - jTextArea1.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N - jTextArea1.setLineWrap(true); - jTextArea1.setRows(5); - jTextArea1.setText(org.openide.util.NbBundle.getMessage(Md5SearchDialog.class, "Md5SearchDialog.jTextArea1.text")); // NOI18N - jTextArea1.setWrapStyleWord(true); - jTextArea1.setBorder(null); - jTextArea1.setOpaque(false); - jScrollPane1.setViewportView(jTextArea1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(11, 11, 11) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jButton1, javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addComponent(jLabel1)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jTextField1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jButton1) - .addContainerGap()) - ); - - pack(); - }// //GEN-END:initComponents - - private void jTextField1PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTextField1PropertyChange - //DLG: - }//GEN-LAST:event_jTextField1PropertyChange - - private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - search(); - }//GEN-LAST:event_jButton1ActionPerformed - - private void jTextField1InputMethodTextChanged(java.awt.event.InputMethodEvent evt) {//GEN-FIRST:event_jTextField1InputMethodTextChanged - //DLG: - }//GEN-LAST:event_jTextField1InputMethodTextChanged - - private void customizeComponents() { - jButton1.setEnabled(false); - correlationTypeComboBox.setEnabled(false); - - /* - * Add correlation types to the combo-box. - */ - try { - EamDb dbManager = EamDb.getInstance(); - correlationTypes.clear(); - correlationTypes.addAll(dbManager.getDefinedCorrelationTypes()); - } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); - } - - for (CorrelationAttributeInstance.Type type : correlationTypes) { - correlationTypeComboBox.addItem(type.getDisplayName()); - } - - /* - * Create listener for text input. - */ - jTextField1.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void changedUpdate(DocumentEvent e) { - validateInput(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - validateInput(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - validateInput(); - } - - private void validateInput() { - Matcher matcher = md5Pattern.matcher(jTextField1.getText().trim()); - if (matcher.find()) { - jButton1.setEnabled(true); - correlationTypeComboBox.setEnabled(true); - correlationTypeComboBox.setSelectedItem(FILES_CORRELATION_TYPE); - } else { - jButton1.setEnabled(false); - correlationTypeComboBox.setEnabled(false); - } - } - }); - } - - public void display() { - this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - setVisible(true); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JComboBox correlationTypeComboBox; - private javax.swing.JButton jButton1; - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel jLabel2; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JTextArea jTextArea1; - private javax.swing.JTextField jTextField1; - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java b/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java index 618cba2a38..8ed4c46111 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportWizardAction.java @@ -50,8 +50,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact; @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportWizardAction") @ActionRegistration(displayName = "#CTL_ReportWizardAction", lazy = false) @ActionReferences(value = { - @ActionReference(path = "Menu/Tools", position = 103), - @ActionReference(path = "Toolbars/Case", position = 103)}) + @ActionReference(path = "Menu/Tools", position = 105), + @ActionReference(path = "Toolbars/Case", position = 105)}) public final class ReportWizardAction extends CallableSystemAction implements Presenter.Toolbar, ActionListener { private final JButton toolbarButton = new JButton(); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java index 45563a4f4b..56f13e172a 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2017 Basis Technology Corp. + * Copyright 2017-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.Logger; @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.experimental.autoingest.AutoIngestDashboardOpenAction") -@ActionReference(path = "Menu/Tools", position = 104) +@ActionReference(path = "Menu/Tools", position = 106) @ActionRegistration(displayName = "#CTL_AutoIngestDashboardOpenAction", lazy = false) @Messages({"CTL_AutoIngestDashboardOpenAction=Auto Ingest Dashboard"}) public final class AutoIngestDashboardOpenAction extends CallableSystemAction { From 4b804ed22660b07fd037fe4b112e2d86304ec719 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 15 Nov 2018 10:03:08 -0500 Subject: [PATCH 15/32] Updated access modifiers. --- .../CorrelationAttributeInstanceNode.java | 2 +- .../CorrelationPropertyFilterChildren.java | 4 ++-- .../CorrelationPropertyFilterNode.java | 12 ++++++------ .../CorrelationPropertySearchDialog.java | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java index c277154033..e0b1b378c0 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; * Used by the Correlation Property Search feature to encapsulate instances of a * given search match. */ -public class CorrelationAttributeInstanceNode extends DisplayableItemNode { +public final class CorrelationAttributeInstanceNode extends DisplayableItemNode { private final CorrelationAttributeInstance instance; diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java index 4c3c443944..04a6ebf605 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java @@ -26,7 +26,7 @@ import org.openide.nodes.Node; * A Children implementation for a * CorrelationPropertyFilterNode. */ -class CorrelationPropertyFilterChildren extends FilterNode.Children { +final class CorrelationPropertyFilterChildren extends FilterNode.Children { /** * Create a new Children instance. @@ -37,7 +37,7 @@ class CorrelationPropertyFilterChildren extends FilterNode.Children { * * @return A Children instance. */ - public static Children createInstance(Node wrappedNode, boolean createChildren) { + static Children createInstance(Node wrappedNode, boolean createChildren) { if (createChildren) { return new CorrelationPropertyFilterChildren(wrappedNode); diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java index fa5c1ecaa1..bca214edb9 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java @@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; /** * FilterNode containing properties and actions for Correlation Property Search. */ -public class CorrelationPropertyFilterNode extends FilterNode { +final class CorrelationPropertyFilterNode extends FilterNode { private final boolean createChildren; private final boolean forceUseWrappedDisplayName; @@ -44,7 +44,7 @@ public class CorrelationPropertyFilterNode extends FilterNode { * @param createChildren True if a Children object should be created for the * wrapped node. */ - public CorrelationPropertyFilterNode(Node node, boolean createChildren) { + CorrelationPropertyFilterNode(Node node, boolean createChildren) { super(node, CorrelationPropertyFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); this.forceUseWrappedDisplayName = false; this.createChildren = createChildren; @@ -62,7 +62,7 @@ public class CorrelationPropertyFilterNode extends FilterNode { * @param columnOrderKey A key that represents the type of the original * wrapped node and what is being displayed under that node. */ - public CorrelationPropertyFilterNode(Node node, boolean createChildren, String columnOrderKey) { + CorrelationPropertyFilterNode(Node node, boolean createChildren, String columnOrderKey) { super(node, CorrelationPropertyFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); this.forceUseWrappedDisplayName = false; this.createChildren = createChildren; @@ -92,7 +92,7 @@ public class CorrelationPropertyFilterNode extends FilterNode { * * @param selectedChildNodeInfo The child node selection information. */ - public void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { + void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { /* * Currently, child selection is only supported for nodes selected in * the tree view and decorated with a DataResultFilterNode. @@ -109,7 +109,7 @@ public class CorrelationPropertyFilterNode extends FilterNode { * @return The child node selection information, or null if no child should * be selected. */ - public NodeSelectionInfo getChildNodeSelectionInfo() { + NodeSelectionInfo getChildNodeSelectionInfo() { /* * Currently, child selection is only supported for nodes selected in * the tree view and decorated with a DataResultFilterNode. @@ -128,7 +128,7 @@ public class CorrelationPropertyFilterNode extends FilterNode { * DataResultViewerTable. The key should represent what kinds of items the * table is showing. */ - public String getColumnOrderKey() { + String getColumnOrderKey() { return columnOrderKey; } } diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java index f22acbfea5..6dc500d471 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java +++ b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java @@ -61,7 +61,7 @@ import org.sleuthkit.autopsy.datamodel.EmptyNode; * The Correlation Property Search dialog allows users to search for specific * types of correlation properties in the Central Repository. */ -public class CorrelationPropertySearchDialog extends javax.swing.JDialog { +final class CorrelationPropertySearchDialog extends javax.swing.JDialog { private static final Logger logger = Logger.getLogger(CorrelationPropertySearchDialog.class.getName()); private static final String FILES_CORRELATION_TYPE = "Files"; @@ -72,7 +72,7 @@ public class CorrelationPropertySearchDialog extends javax.swing.JDialog { /** * Creates a new instance of the Correlation Property Search dialog. */ - public CorrelationPropertySearchDialog() { + CorrelationPropertySearchDialog() { super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.CorrelationPropertySearchDialog_title_text(), true); this.correlationTypes = new ArrayList<>(); initComponents(); From 9ee54cf46e28764cace739433c6b8d880b4c0019 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Thu, 15 Nov 2018 11:58:22 -0500 Subject: [PATCH 16/32] Renamed feature; added description to dialog. --- .../Bundle.properties | 7 -- .../datamodel/DisplayableItemNodeVisitor.java | 2 +- .../othercasessearch/Bundle.properties | 9 +++ .../CorrelationAttributeInstanceNode.java | 7 +- .../OtherCasesFilterChildren.java} | 10 +-- .../OtherCasesFilterNode.java} | 14 ++-- .../OtherCasesSearchAction.java} | 19 ++--- .../OtherCasesSearchChildren.java} | 8 +- .../OtherCasesSearchDialog.form} | 31 +++++--- .../OtherCasesSearchDialog.java} | 74 +++++++++++-------- .../OtherCasesSearchNode.java} | 21 +++--- 11 files changed, 115 insertions(+), 87 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties create mode 100755 Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch => othercasessearch}/CorrelationAttributeInstanceNode.java (96%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertyFilterChildren.java => othercasessearch/OtherCasesFilterChildren.java} (87%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertyFilterNode.java => othercasessearch/OtherCasesFilterNode.java} (88%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertySearchAction.java => othercasessearch/OtherCasesSearchAction.java} (67%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertySearchChildren.java => othercasessearch/OtherCasesSearchChildren.java} (81%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertySearchDialog.form => othercasessearch/OtherCasesSearchDialog.form} (70%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertySearchDialog.java => othercasessearch/OtherCasesSearchDialog.java} (80%) rename Core/src/org/sleuthkit/autopsy/{correlationpropertysearch/CorrelationPropertySearchNode.java => othercasessearch/OtherCasesSearchNode.java} (61%) diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties deleted file mode 100755 index e3ceab0960..0000000000 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/Bundle.properties +++ /dev/null @@ -1,7 +0,0 @@ -CorrelationPropertySearchDialog.errorLabel.text= -CorrelationPropertySearchDialog.correlationValueTextField.text= -CorrelationPropertySearchDialog.correlationTypeLabel.text=Correlation Property Type: -CorrelationPropertySearchDialog.correlationValueLabel.text=Correlation Property Value: -CorrelationPropertySearchDialog.searchButton.text=Search -CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleName=Search -CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleDescription= diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index d9d2ffea84..df1358833f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -29,7 +29,7 @@ import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNod import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootNode; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.datamodel.accounts.Accounts; -import org.sleuthkit.autopsy.correlationpropertysearch.CorrelationAttributeInstanceNode; +import org.sleuthkit.autopsy.othercasessearch.CorrelationAttributeInstanceNode; /** * Visitor pattern that goes over all nodes in the directory tree. This includes diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties new file mode 100755 index 0000000000..ff51e4ca22 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties @@ -0,0 +1,9 @@ + +OtherCasesSearchDialog.searchButton.AccessibleContext.accessibleDescription= +OtherCasesSearchDialog.searchButton.AccessibleContext.accessibleName=Search +OtherCasesSearchDialog.searchButton.text=Search +OtherCasesSearchDialog.correlationValueTextField.text= +OtherCasesSearchDialog.correlationValueLabel.text=Correlation Property Value: +OtherCasesSearchDialog.descriptionLabel.text=Search data in the Central Repository from other cases. +OtherCasesSearchDialog.errorLabel.text= +OtherCasesSearchDialog.correlationTypeLabel.text=Correlation Property Type: diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/CorrelationAttributeInstanceNode.java similarity index 96% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/CorrelationAttributeInstanceNode.java index e0b1b378c0..f3248d293b 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/CorrelationAttributeInstanceNode.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import java.io.File; import java.util.ArrayList; @@ -29,13 +29,14 @@ import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; +import org.sleuthkit.autopsy.othercasessearch.Bundle; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; /** - * Used by the Correlation Property Search feature to encapsulate instances of a - * given search match. + * Used by the Other Cases Search feature to encapsulate instances of a given + * search match. */ public final class CorrelationAttributeInstanceNode extends DisplayableItemNode { diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java similarity index 87% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java index 04a6ebf605..72edf98cd9 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterChildren.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import org.openide.nodes.Children; import org.openide.nodes.FilterNode; @@ -26,7 +26,7 @@ import org.openide.nodes.Node; * A Children implementation for a * CorrelationPropertyFilterNode. */ -final class CorrelationPropertyFilterChildren extends FilterNode.Children { +final class OtherCasesFilterChildren extends FilterNode.Children { /** * Create a new Children instance. @@ -40,7 +40,7 @@ final class CorrelationPropertyFilterChildren extends FilterNode.Children { static Children createInstance(Node wrappedNode, boolean createChildren) { if (createChildren) { - return new CorrelationPropertyFilterChildren(wrappedNode); + return new OtherCasesFilterChildren(wrappedNode); } else { return Children.LEAF; } @@ -52,7 +52,7 @@ final class CorrelationPropertyFilterChildren extends FilterNode.Children { * * @param wrappedNode The node wrapped by CorrelationPropertyFilterNode. */ - CorrelationPropertyFilterChildren(Node wrappedNode) { + OtherCasesFilterChildren(Node wrappedNode) { super(wrappedNode); } @@ -66,7 +66,7 @@ final class CorrelationPropertyFilterChildren extends FilterNode.Children { */ @Override protected Node copyNode(Node nodeToCopy) { - return new CorrelationPropertyFilterNode(nodeToCopy, false); + return new OtherCasesFilterNode(nodeToCopy, false); } /** diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java similarity index 88% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java index bca214edb9..8cf27fd507 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertyFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import org.openide.nodes.FilterNode; import org.openide.nodes.Node; @@ -26,9 +26,9 @@ import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; /** - * FilterNode containing properties and actions for Correlation Property Search. + * FilterNode containing properties and actions for the other cases search. */ -final class CorrelationPropertyFilterNode extends FilterNode { +final class OtherCasesFilterNode extends FilterNode { private final boolean createChildren; private final boolean forceUseWrappedDisplayName; @@ -44,8 +44,8 @@ final class CorrelationPropertyFilterNode extends FilterNode { * @param createChildren True if a Children object should be created for the * wrapped node. */ - CorrelationPropertyFilterNode(Node node, boolean createChildren) { - super(node, CorrelationPropertyFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + OtherCasesFilterNode(Node node, boolean createChildren) { + super(node, OtherCasesFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); this.forceUseWrappedDisplayName = false; this.createChildren = createChildren; } @@ -62,8 +62,8 @@ final class CorrelationPropertyFilterNode extends FilterNode { * @param columnOrderKey A key that represents the type of the original * wrapped node and what is being displayed under that node. */ - CorrelationPropertyFilterNode(Node node, boolean createChildren, String columnOrderKey) { - super(node, CorrelationPropertyFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); + OtherCasesFilterNode(Node node, boolean createChildren, String columnOrderKey) { + super(node, OtherCasesFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); this.forceUseWrappedDisplayName = false; this.createChildren = createChildren; this.columnOrderKey = columnOrderKey; diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchAction.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchAction.java similarity index 67% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchAction.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchAction.java index 74facdff65..55dcda0a24 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchAction.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import java.awt.event.ActionEvent; import org.openide.awt.ActionID; @@ -27,15 +27,16 @@ import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; +import org.sleuthkit.autopsy.othercasessearch.Bundle; /** - * Action for accessing the Correlation Property Search dialog. + * Action for accessing the Search Other Cases dialog. */ -@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.correlationpropertysearch.CorrelationPropertySearchAction") -@ActionRegistration(displayName = "#CTL_CorrelationPropertySearchAction=Correlation Property Search", lazy = false) +@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.othercasessearch.OtherCasesSearchAction") +@ActionRegistration(displayName = "#CTL_OtherCasesSearchAction=Search Other Cases", lazy = false) @ActionReference(path = "Menu/Tools", position = 104) -@NbBundle.Messages({"CTL_CorrelationPropertySearchAction=Correlation Property Search"}) -public class CorrelationPropertySearchAction extends CallableSystemAction { +@NbBundle.Messages({"CTL_OtherCasesSearchAction=Search Other Cases"}) +public class OtherCasesSearchAction extends CallableSystemAction { @Override public boolean isEnabled() { @@ -49,15 +50,15 @@ public class CorrelationPropertySearchAction extends CallableSystemAction { @Override public void performAction() { - CorrelationPropertySearchDialog dialog = new CorrelationPropertySearchDialog(); + OtherCasesSearchDialog dialog = new OtherCasesSearchDialog(); dialog.display(); } @NbBundle.Messages({ - "CorrelationPropertySearchAction.getName.text=Correlation Property Search"}) + "OtherCasesSearchAction.getName.text=Search Other Cases"}) @Override public String getName() { - return Bundle.CorrelationPropertySearchAction_getName_text(); + return Bundle.OtherCasesSearchAction_getName_text(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchChildren.java similarity index 81% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchChildren.java index 9e1d20f2ef..eea55a6518 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchChildren.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchChildren.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import java.util.List; import org.openide.nodes.Children; @@ -27,15 +27,15 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns * Creates CorrelationAttributeInstanceNodes from a collection of * CorrelationAttributeInstances. */ -class CorrelationPropertySearchChildren extends Children.Keys { +class OtherCasesSearchChildren extends Children.Keys { /** - * Create an instance of CorrelationPropertySearchChildren. + * Create an instance of OtherCasesSearchChildren. * * @param lazy Lazy load? * @param fileList List of CorrelationAttributeInstances. */ - CorrelationPropertySearchChildren(boolean lazy, List instances) { + OtherCasesSearchChildren(boolean lazy, List instances) { super(lazy); this.setKeys(instances); } diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form similarity index 70% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form index 347008824c..cbe9506133 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.form +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form @@ -43,6 +43,10 @@ + + + + @@ -50,8 +54,10 @@ - + + + @@ -61,7 +67,7 @@ - + @@ -75,29 +81,29 @@ - + - + - + - + - + @@ -117,7 +123,7 @@ - + @@ -127,7 +133,14 @@ - + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java similarity index 80% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java index 6dc500d471..d691e078cb 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchDialog.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import java.awt.Color; import java.awt.event.ItemEvent; @@ -34,7 +34,6 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.openide.nodes.Node; import org.openide.util.Exceptions; -import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; @@ -49,20 +48,22 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.othercasessearch.Bundle; import org.sleuthkit.autopsy.datamodel.EmptyNode; @Messages({ - "CorrelationPropertySearchDialog.title.text=Correlation Property Search", - "CorrelationPropertySearchDialog.results.text=Correlation Properties", - "CorrelationPropertySearchDialog.emptyNode.text=No results found.", - "CorrelationPropertySearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash." + "OtherCasesSearchDialog.dialogTitle.text=Search Other Cases", + "OtherCasesSearchDialog.resultsTitle.text=Other Cases", + "OtherCasesSearchDialog.resultsDescription.text=Other Cases Search", + "OtherCasesSearchDialog.emptyNode.text=No results found.", + "OtherCasesSearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash." }) /** - * The Correlation Property Search dialog allows users to search for specific + * The Search Other Cases dialog allows users to search for specific * types of correlation properties in the Central Repository. */ -final class CorrelationPropertySearchDialog extends javax.swing.JDialog { - private static final Logger logger = Logger.getLogger(CorrelationPropertySearchDialog.class.getName()); +final class OtherCasesSearchDialog extends javax.swing.JDialog { + private static final Logger logger = Logger.getLogger(OtherCasesSearchDialog.class.getName()); private static final String FILES_CORRELATION_TYPE = "Files"; @@ -70,17 +71,17 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { private TextPrompt correlationValueTextFieldPrompt; /** - * Creates a new instance of the Correlation Property Search dialog. + * Creates a new instance of the Search Other Cases dialog. */ - CorrelationPropertySearchDialog() { - super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.CorrelationPropertySearchDialog_title_text(), true); + OtherCasesSearchDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.OtherCasesSearchDialog_dialogTitle_text(), true); this.correlationTypes = new ArrayList<>(); initComponents(); customizeComponents(); } /** - * Perform the correlation property search. + * Perform the other cases search. */ private void search() { new SwingWorker, Void>() { @@ -116,22 +117,22 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { Collection viewers = new ArrayList<>(1); viewers.add(table); - CorrelationPropertySearchNode searchNode = new CorrelationPropertySearchNode(correlationInstances); - CorrelationPropertyFilterNode tableFilterNode = new CorrelationPropertyFilterNode(searchNode, true, searchNode.getName()); + OtherCasesSearchNode searchNode = new OtherCasesSearchNode(correlationInstances); + OtherCasesFilterNode tableFilterNode = new OtherCasesFilterNode(searchNode, true, searchNode.getName()); String resultsText = String.format("%s (%s; \"%s\")", - Bundle.CorrelationPropertySearchDialog_results_text(), + Bundle.OtherCasesSearchDialog_resultsTitle_text(), (String) correlationTypeComboBox.getSelectedItem(), correlationValueTextField.getText()); final TopComponent searchResultWin; if (correlationInstances.isEmpty()) { Node emptyNode = new TableFilterNode( - new EmptyNode(Bundle.CorrelationPropertySearchDialog_emptyNode_text()), true); + new EmptyNode(Bundle.OtherCasesSearchDialog_emptyNode_text()), true); searchResultWin = DataResultTopComponent.createInstance( - resultsText, Bundle.CorrelationPropertySearchDialog_title_text(), emptyNode, 0); + resultsText, Bundle.OtherCasesSearchDialog_resultsDescription_text(), emptyNode, 0); } else { searchResultWin = DataResultTopComponent.createInstance( - resultsText, Bundle.CorrelationPropertySearchDialog_title_text(), tableFilterNode, HIDE_ON_CLOSE, viewers); + resultsText, Bundle.OtherCasesSearchDialog_resultsDescription_text(), tableFilterNode, HIDE_ON_CLOSE, viewers); } searchResultWin.requestActive(); // make it the active top component } catch (ExecutionException | InterruptedException ex) { @@ -156,25 +157,28 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { correlationTypeComboBox = new javax.swing.JComboBox<>(); correlationTypeLabel = new javax.swing.JLabel(); errorLabel = new javax.swing.JLabel(); + descriptionLabel = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setResizable(false); - org.openide.awt.Mnemonics.setLocalizedText(correlationValueLabel, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.correlationValueLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(correlationValueLabel, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.correlationValueLabel.text")); // NOI18N - correlationValueTextField.setText(org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.correlationValueTextField.text")); // NOI18N + correlationValueTextField.setText(org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.correlationValueTextField.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.searchButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.searchButton.text")); // NOI18N searchButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { searchButtonActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(correlationTypeLabel, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.correlationTypeLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(correlationTypeLabel, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.correlationTypeLabel.text")); // NOI18N errorLabel.setForeground(new java.awt.Color(255, 0, 0)); - org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.errorLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.errorLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.descriptionLabel.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); @@ -194,13 +198,18 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(correlationTypeComboBox, 0, 289, Short.MAX_VALUE) - .addComponent(correlationValueTextField)))) + .addComponent(correlationValueTextField))) + .addGroup(layout.createSequentialGroup() + .addComponent(descriptionLabel) + .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() + .addComponent(descriptionLabel) + .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(correlationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(correlationTypeLabel)) @@ -215,8 +224,8 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - searchButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleName")); // NOI18N - searchButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(CorrelationPropertySearchDialog.class, "CorrelationPropertySearchDialog.searchButton.AccessibleContext.accessibleDescription")); // NOI18N + searchButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.searchButton.AccessibleContext.accessibleName")); // NOI18N + searchButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.searchButton.AccessibleContext.accessibleDescription")); // NOI18N pack(); }// //GEN-END:initComponents @@ -234,7 +243,7 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { dispose(); } else { searchButton.setEnabled(false); - errorLabel.setText(Bundle.CorrelationPropertySearchDialog_validation_invalidHash()); + errorLabel.setText(Bundle.OtherCasesSearchDialog_validation_invalidHash()); correlationValueTextField.grabFocus(); } }//GEN-LAST:event_searchButtonActionPerformed @@ -295,7 +304,7 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { } @Messages({ - "CorrelationPropertySearchDialog.correlationValueTextField.filesExample=Example: \"f0e1d2c3b4a5968778695a4b3c2d1e0f\"" + "OtherCasesSearchDialog.correlationValueTextField.filesExample=Example: \"f0e1d2c3b4a5968778695a4b3c2d1e0f\"" }) /** * Update the text prompt of the name text field based on the input type @@ -305,7 +314,7 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { /** * Add text prompt to the text field. */ - String text = Bundle.CorrelationPropertySearchDialog_correlationValueTextField_filesExample(); + String text = Bundle.OtherCasesSearchDialog_correlationValueTextField_filesExample(); correlationValueTextFieldPrompt = new TextPrompt(text, correlationValueTextField); /** @@ -341,7 +350,7 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { } /** - * Display the Correlation Property Search dialog. + * Display the Search Other Cases dialog. */ public void display() { this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); @@ -353,6 +362,7 @@ final class CorrelationPropertySearchDialog extends javax.swing.JDialog { private javax.swing.JLabel correlationTypeLabel; private javax.swing.JLabel correlationValueLabel; private javax.swing.JTextField correlationValueTextField; + private javax.swing.JLabel descriptionLabel; private javax.swing.JLabel errorLabel; private javax.swing.JButton searchButton; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java similarity index 61% rename from Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java rename to Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java index 17b1d979c4..312744ffdc 100755 --- a/Core/src/org/sleuthkit/autopsy/correlationpropertysearch/CorrelationPropertySearchNode.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java @@ -16,35 +16,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.correlationpropertysearch; +package org.sleuthkit.autopsy.othercasessearch; import java.util.List; import org.openide.nodes.AbstractNode; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; +import org.sleuthkit.autopsy.othercasessearch.Bundle; /** - * Parent node to CorrelationPropertySearchChildren. + * Parent node to OtherCasesSearchChildren. */ -class CorrelationPropertySearchNode extends AbstractNode { +class OtherCasesSearchNode extends AbstractNode { - private CorrelationPropertySearchChildren children; + private OtherCasesSearchChildren children; /** - * Create an instance of CorrelationPropertySearchNode. + * Create an instance of OtherCasesSearchNode. * * @param keys The list of CorrelationAttributeInstances. */ - CorrelationPropertySearchNode(List keys) { - super(new CorrelationPropertySearchChildren(true, keys)); - this.children = (CorrelationPropertySearchChildren) this.getChildren(); + OtherCasesSearchNode(List keys) { + super(new OtherCasesSearchChildren(true, keys)); + this.children = (OtherCasesSearchChildren) this.getChildren(); } @Messages({ - "CorrelationPropertySearchNode.getName.text=Correlation Property Search" + "OtherCasesSearchNode.getName.text=Other Cases Search" }) @Override public String getName() { - return Bundle.CorrelationPropertySearchNode_getName_text(); + return Bundle.OtherCasesSearchNode_getName_text(); } } From 9f48caf897f533047f613f5ecf11279dffdacbe8 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 14:06:21 -0500 Subject: [PATCH 17/32] 4361 enable/disable settings based on CURRENT_CASE events --- .../optionspanel/GlobalSettingsPanel.java | 44 +++++------- .../corecomponents/ViewPreferencesPanel.form | 69 +++++++++---------- .../corecomponents/ViewPreferencesPanel.java | 8 ++- .../ImageGalleryOptionsPanel.form | 6 -- .../ImageGalleryOptionsPanel.java | 27 ++------ 5 files changed, 64 insertions(+), 90 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index a4d6ef5cc0..0600e6de6f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -23,11 +23,13 @@ import java.awt.EventQueue; import org.sleuthkit.autopsy.coreutils.Logger; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.EnumSet; 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.casemodule.Case; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.ingest.IngestManager; @@ -58,6 +60,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i initComponents(); customizeComponents(); addIngestJobEventsListener(); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + //disable when case is open, enable when case is closed + ingestStateUpdated(evt.getNewValue() != null); + }); } private void customizeComponents() { @@ -66,7 +72,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void addIngestJobEventsListener() { IngestManager.getInstance().addIngestJobEventListener(ingestJobEventListener); - ingestStateUpdated(); + ingestStateUpdated(Case.isCaseOpen()); } @Messages({"GlobalSettingsPanel.updateFailed.title=Update failed", @@ -429,7 +435,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i store(); updateDatabase(); load(); - this.ingestStateUpdated(); + this.ingestStateUpdated(Case.isCaseOpen()); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_cbUseCentralRepoActionPerformed @@ -447,7 +453,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i @Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."}) public void load() { tbOops.setText(""); - enableAllSubComponents(false); + enableButtonSubComponents(false); EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform(); cbUseCentralRepo.setSelected(EamDbUtil.useCentralRepo()); // NON-NLS switch (selectedPlatform) { @@ -456,20 +462,19 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i lbDbPlatformValue.setText(EamDbPlatformEnum.POSTGRESQL.toString()); lbDbNameValue.setText(dbSettingsPg.getDbName()); lbDbLocationValue.setText(dbSettingsPg.getHost()); - enableAllSubComponents(true); + enableButtonSubComponents(cbUseCentralRepo.isSelected()); break; case SQLITE: SqliteEamDbSettings dbSettingsSqlite = new SqliteEamDbSettings(); lbDbPlatformValue.setText(EamDbPlatformEnum.SQLITE.toString()); lbDbNameValue.setText(dbSettingsSqlite.getDbName()); lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory()); - enableAllSubComponents(true); + enableButtonSubComponents(cbUseCentralRepo.isSelected()); break; default: lbDbPlatformValue.setText(EamDbPlatformEnum.DISABLED.toString()); lbDbNameValue.setText(""); lbDbLocationValue.setText(""); - enableDatabaseConfigureButton(cbUseCentralRepo.isSelected()); tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); break; } @@ -521,7 +526,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i EventQueue.invokeLater(new Runnable() { @Override public void run() { - ingestStateUpdated(); + ingestStateUpdated(Case.isCaseOpen()); } }); } @@ -550,38 +555,25 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running."}) - private void ingestStateUpdated() { + private void ingestStateUpdated(boolean caseIsOpen) { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(() -> { - ingestStateUpdated(); + ingestStateUpdated(caseIsOpen); }); return; } + cbUseCentralRepo.setEnabled(!caseIsOpen); if (IngestManager.getInstance().isIngestRunning()) { tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning()); tbOops.setVisible(true); - cbUseCentralRepo.setEnabled(false); - enableAllSubComponents(false); - } else if (!cbUseCentralRepo.isEnabled()) { - cbUseCentralRepo.setEnabled(true); + enableButtonSubComponents(cbUseCentralRepo.isSelected()); + } else { load(); + enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } - } - /** - * Wrapper around each of the enableComponentXYZ methods to enable/disable - * them all at the same time. - * - * @param enable - * - * @return True - */ - private boolean enableAllSubComponents(Boolean enable) { - enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && enable); - enableButtonSubComponents(cbUseCentralRepo.isSelected() && enable); - return true; } /** diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index 711caf3b7b..b0b283350b 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -108,53 +108,48 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - - - - + + - + + + + + + + + - - - + + + + + + + + + + + + + + + + - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 872a7d6d6d..a468648425 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.corecomponents; +import java.beans.PropertyChangeEvent; +import java.util.EnumSet; import java.util.Objects; import java.util.TimeZone; import javax.swing.JPanel; @@ -46,7 +48,11 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { public ViewPreferencesPanel(boolean immediateUpdates) { initComponents(); this.immediateUpdates = immediateUpdates; - + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + //disable when case is closed, enable when case is open + currentCaseSettingsPanel.setEnabled(evt.getNewValue() != null); + groupByDataSourceCheckbox.setEnabled(evt.getNewValue() != null); + }); this.timeZoneList.setListData(TimeZoneUtils.createTimeZoneList().stream().toArray(String[]::new)); } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.form b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.form index 4c999006a3..9fbf3c99eb 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.form +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.form @@ -114,9 +114,6 @@ - - - @@ -146,9 +143,6 @@ - - - diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.java index df0dacd3fe..42f52e3a82 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanel.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.imagegallery; +import java.beans.PropertyChangeEvent; +import java.util.EnumSet; import java.util.logging.Level; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; @@ -30,8 +32,7 @@ import org.sleuthkit.datamodel.TskCoreException; * The Image/Video Gallery panel in the NetBeans provided Options Dialogs * accessed via Tools -> Options * - * Uses ImageGalleryPreferences and PerCaseProperties to persist - * settings + * Uses ImageGalleryPreferences and PerCaseProperties to persist settings */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class ImageGalleryOptionsPanel extends javax.swing.JPanel { @@ -46,6 +47,10 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel { //disable during ingest enabledForCaseBox.setEnabled(Case.isCaseOpen() && IngestManager.getInstance().isIngestRunning() == false); }); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + //disable when case is closed, enable when case is open + enabledForCaseBox.setEnabled(evt.getNewValue() != null && IngestManager.getInstance().isIngestRunning() == false); + }); enabledByDefaultBox.addActionListener(actionEvent -> controller.changed()); enabledForCaseBox.addActionListener(actionEvent -> controller.changed()); @@ -76,11 +81,6 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel { enabledByDefaultBox.setFont(enabledByDefaultBox.getFont().deriveFont(enabledByDefaultBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(enabledByDefaultBox, org.openide.util.NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.enabledByDefaultBox.text")); // NOI18N - enabledByDefaultBox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - enabledByDefaultBoxActionPerformed(evt); - } - }); infoIconLabel.setFont(infoIconLabel.getFont().deriveFont(infoIconLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); infoIconLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"))); // NOI18N @@ -88,11 +88,6 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel { enabledForCaseBox.setFont(enabledForCaseBox.getFont().deriveFont(enabledForCaseBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); org.openide.awt.Mnemonics.setLocalizedText(enabledForCaseBox, org.openide.util.NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.enabledForCaseBox.text")); // NOI18N enabledForCaseBox.setToolTipText(NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.enabledForCaseBox.toolTipText")); // NOI18N - enabledForCaseBox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - enabledForCaseBoxActionPerformed(evt); - } - }); unavailableDuringInjestLabel.setFont(unavailableDuringInjestLabel.getFont().deriveFont(unavailableDuringInjestLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); unavailableDuringInjestLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/warning16.png"))); // NOI18N @@ -174,14 +169,6 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents - private void enabledByDefaultBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enabledByDefaultBoxActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_enabledByDefaultBoxActionPerformed - - private void enabledForCaseBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enabledForCaseBoxActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_enabledForCaseBoxActionPerformed - void load() { enabledByDefaultBox.setSelected(ImageGalleryPreferences.isEnabledByDefault()); try { From aee7efd6d5592261d0b6467b65eef30acabaf65a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 15:24:33 -0500 Subject: [PATCH 18/32] 4361 AutopsyService to populate object id for data sources in cr --- .../datamodel/AbstractSqlEamDb.java | 18 ++++++ .../datamodel/CaseUpdateAutopsyService.java | 59 +++++++++++++++++++ .../centralrepository/datamodel/EamDb.java | 21 +++++-- .../datamodel/SqliteEamDb.java | 10 ++++ 4 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index ba0066c412..2e28dfccfa 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -133,6 +133,24 @@ abstract class AbstractSqlEamDb implements EamDb { } + @Override + public void addDataSourceObjectId(int rowId, long dataSourceObjectId) throws EamDbException{ + Connection conn = connect(); + PreparedStatement preparedStatement = null; + String sql = "UPDATE data_sources SET datasource_id=? WHERE id=?"; + try { + preparedStatement = conn.prepareStatement(sql); + preparedStatement.setLong(1, dataSourceObjectId); + preparedStatement.setInt(2, rowId); + preparedStatement.executeUpdate(); + } catch (SQLException ex) { + throw new EamDbException("Error updating data source object id for data_sources row " + rowId, ex); + } finally { + EamDbUtil.closeStatement(preparedStatement); + EamDbUtil.closeConnection(conn); + } + } + /** * Get the value for the given name from the name/value db_info table. * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java new file mode 100644 index 0000000000..c2f6575acf --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java @@ -0,0 +1,59 @@ +/* + * Central Repository + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.datamodel; + +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.appservices.AutopsyService +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; + + +@ServiceProvider(service = AutopsyService.class) +public class CaseUpdateAutopsyService implements AutopsyService{ + + @Override + public String getServiceName() { + return "UpdateCR"; + } + + @Override + public void openCaseResources(CaseContext context) throws AutopsyServiceException { + if (EamDb.isEnabled()){ + try { + EamDb centralRepository = EamDb.getInstance(); + CorrelationCase correlationCase = centralRepository.getCase(context.getCase()); + for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { + if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getCaseDataSourceID() == null){ + for (Content dataSource : context.getCase().getDataSources()){ + if (((DataSource)dataSource).getDeviceId().equals(correlationDataSource.getDeviceID())){ + centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); + break; + } + } + + } + } + } catch (EamDbException | TskCoreException ex) { + throw new AutopsyServiceException("Unabe to update datasources in central repository", ex); + } + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 358fe93b0d..92cf9aea4e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -110,6 +110,16 @@ public interface EamDb { */ public void newDbInfo(String name, String value) throws EamDbException; + /** + * Set the data source object id for a specific entry in the data_sources + * table + * + * @param rowId - the row id for the data_sources table entry + * @param dataSourceObjectId - the object id for the data source from the + * caseDb + */ + void addDataSourceObjectId(int rowId, long dataSourceObjectId) throws EamDbException; + /** * Get the value for the given name from the name/value db_info table. * @@ -345,9 +355,9 @@ public interface EamDb { /** * Find a correlation attribute in the Central Repository database given the * instance type, case, data source, value, and file path. - * - * Method exists to support instances added using Central Repository version 1,1 and - * older + * + * Method exists to support instances added using Central Repository version + * 1,1 and older * * @param type The type of instance. * @param correlationCase The case tied to the instance. @@ -356,7 +366,7 @@ public interface EamDb { * @param filePath The file path tied to the instance. * * @return The correlation attribute if it exists; otherwise null. - * + * * @throws EamDbException */ CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase, @@ -369,7 +379,8 @@ public interface EamDb { * @param type The type of instance. * @param correlationCase The case tied to the instance. * @param correlationDataSource The data source tied to the instance. - * @param objectID The object id of the file tied to the instance. + * @param objectID The object id of the file tied to the + * instance. * * @return The correlation attribute if it exists; otherwise null. * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index d702bde5b1..36484d2f2d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -274,6 +274,16 @@ final class SqliteEamDb extends AbstractSqlEamDb { } } + @Override + public void addDataSourceObjectId(int rowId, long dataSourceObjectId) throws EamDbException{ + try { + acquireExclusiveLock(); + super.addDataSourceObjectId(rowId, dataSourceObjectId); + } finally { + releaseExclusiveLock(); + } + } + /** * Creates new Case in the database * From 624a82991789a6d82b6283013439720b5a07a902 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 16:04:11 -0500 Subject: [PATCH 19/32] 4361 fix data source cr object id update code --- ...vice.java => DataSourceUpdateService.java} | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{CaseUpdateAutopsyService.java => DataSourceUpdateService.java} (66%) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java similarity index 66% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java index c2f6575acf..3d839be7a0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CaseUpdateAutopsyService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java @@ -18,42 +18,44 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; +import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.appservices.AutopsyService +import org.sleuthkit.autopsy.appservices.AutopsyService; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; - @ServiceProvider(service = AutopsyService.class) -public class CaseUpdateAutopsyService implements AutopsyService{ - +public class DataSourceUpdateService implements AutopsyService { + @Override + @NbBundle.Messages({"DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources"}) public String getServiceName() { - return "UpdateCR"; + return Bundle.DataSourceUpdateService_serviceName_text(); } @Override - public void openCaseResources(CaseContext context) throws AutopsyServiceException { - if (EamDb.isEnabled()){ + public void openCaseResources(CaseContext context) throws AutopsyServiceException { + if (EamDb.isEnabled()) { try { EamDb centralRepository = EamDb.getInstance(); CorrelationCase correlationCase = centralRepository.getCase(context.getCase()); for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { - if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getCaseDataSourceID() == null){ - for (Content dataSource : context.getCase().getDataSources()){ - if (((DataSource)dataSource).getDeviceId().equals(correlationDataSource.getDeviceID())){ - centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); - break; + //ResultSet.getLong has a value of 0 when the value is null + if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getCaseDataSourceID() == 0) { + for (Content dataSource : context.getCase().getDataSources()) { + if (((DataSource) dataSource).getDeviceId().equals(correlationDataSource.getDeviceID())) { + centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); + break; } } - + } } } catch (EamDbException | TskCoreException ex) { - throw new AutopsyServiceException("Unabe to update datasources in central repository", ex); + throw new AutopsyServiceException("Unabe to update datasources in central repository", ex); } } } - + } From 3e8373d5e276dc022eb360ba3da988359019fd04 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 16:24:03 -0500 Subject: [PATCH 20/32] 4361 add note regarding not being able to change CR with open case --- .../autopsy/centralrepository/optionspanel/Bundle.properties | 2 +- .../centralrepository/optionspanel/GlobalSettingsPanel.form | 4 ++-- .../centralrepository/optionspanel/GlobalSettingsPanel.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties index 2be40d5a64..645c1415c9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties @@ -61,7 +61,7 @@ EamDbSettingsDialog.lbFullDbPath.text= GlobalSettingsPanel.cbUseCentralRepo.text=Use a Central Repository GlobalSettingsPanel.organizationTextArea.text=Organization information can be tracked in the Central Repository. GlobalSettingsPanel.manageOrganizationButton.text=Manage Organizations -GlobalSettingsPanel.lbCentralRepository.text=A Central Repository allows you to correlate files and results between cases. +GlobalSettingsPanel.lbCentralRepository.text=A Central Repository allows you to correlate files and results between cases. Central Repository configuration can not be modified while a case is open. GlobalSettingsPanel.pnCorrelationProperties.border.title=Correlation Properties GlobalSettingsPanel.organizationPanel.border.title=Organizations GlobalSettingsPanel.casesPanel.border.title=Case Details diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 0a8c7dcc64..617f6e1fe5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -140,7 +140,7 @@ - + @@ -150,7 +150,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 0600e6de6f..67d1f33889 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -179,7 +179,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addComponent(bnDbConfigure) - .addContainerGap()) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup() .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -187,7 +187,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addComponent(lbDbLocationLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 936, Short.MAX_VALUE) .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))) ); From 8d8125abee45be9ff36abcd85e489ed0f61a0eab Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 17:21:36 -0500 Subject: [PATCH 21/32] 4361 refactor names adjust comments --- .../datamodel/AbstractSqlEamDb.java | 66 +++++++++---------- .../datamodel/CorrelationDataSource.java | 14 ++-- .../datamodel/DataSourceUpdateService.java | 7 +- .../datamodel/EamArtifactUtil.java | 1 - .../centralrepository/datamodel/EamDb.java | 2 + .../datamodel/PostgresEamDbSettings.java | 2 +- .../datamodel/SqliteEamDbSettings.java | 2 +- .../ingestmodule/IngestModule.java | 2 +- 8 files changed, 53 insertions(+), 43 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 2e28dfccfa..37823a37a9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -71,7 +71,7 @@ abstract class AbstractSqlEamDb implements EamDb { private static final Cache caseCacheById = CacheBuilder.newBuilder() .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); - private static final Cache dataSourceCacheByDeviceId = CacheBuilder.newBuilder() + private static final Cache dataSourceCacheByDsObjectId = CacheBuilder.newBuilder() .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); private static final Cache dataSourceCacheById = CacheBuilder.newBuilder() @@ -134,10 +134,10 @@ abstract class AbstractSqlEamDb implements EamDb { } @Override - public void addDataSourceObjectId(int rowId, long dataSourceObjectId) throws EamDbException{ + public void addDataSourceObjectId(int rowId, long dataSourceObjectId) throws EamDbException { Connection conn = connect(); PreparedStatement preparedStatement = null; - String sql = "UPDATE data_sources SET datasource_id=? WHERE id=?"; + String sql = "UPDATE data_sources SET datasource_obj_id=? WHERE id=?"; try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setLong(1, dataSourceObjectId); @@ -193,7 +193,7 @@ abstract class AbstractSqlEamDb implements EamDb { typeCache.invalidateAll(); caseCacheByUUID.invalidateAll(); caseCacheById.invalidateAll(); - dataSourceCacheByDeviceId.invalidateAll(); + dataSourceCacheByDsObjectId.invalidateAll(); dataSourceCacheById.invalidateAll(); } @@ -569,17 +569,17 @@ abstract class AbstractSqlEamDb implements EamDb { } /** - * Create a key to the DataSourceCacheByDeviceId + * Create a key to the dataSourceCacheByDsObjectId * * @param caseId - the id of the CorrelationCase in the Central * Repository - * @param dataSourceDeviceId - the object id if of the data source in the + * @param dataSourceObjectId - the object id if of the data source in the * case db * - * @return a String to be used as a key for the dataSourceCacheByDeviceId + * @return a String to be used as a key for the dataSourceCacheByDsObjectId */ - private static String getDataSourceByCaseDataSourceIdCacheKey(int caseId, Long caseDbDataSourceId) { - return "Case" + caseId + "DataSourceId" + caseDbDataSourceId; //NON-NLS + private static String getDataSourceByDSObjectIdCacheKey(int caseId, Long dataSourceObjectId) { + return "Case" + caseId + "DsObjectId" + dataSourceObjectId; //NON-NLS } /** @@ -612,7 +612,7 @@ abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; - String sql = "INSERT INTO data_sources(device_id, case_id, name, datasource_id) VALUES (?, ?, ?, ?) " + String sql = "INSERT INTO data_sources(device_id, case_id, name, datasource_obj_id) VALUES (?, ?, ?, ?) " + getConflictClause(); ResultSet resultSet = null; try { @@ -621,7 +621,7 @@ abstract class AbstractSqlEamDb implements EamDb { preparedStatement.setString(1, eamDataSource.getDeviceID()); preparedStatement.setInt(2, eamDataSource.getCaseID()); preparedStatement.setString(3, eamDataSource.getName()); - preparedStatement.setLong(4, eamDataSource.getCaseDataSourceID()); + preparedStatement.setLong(4, eamDataSource.getDataSourceObjectID()); preparedStatement.executeUpdate(); resultSet = preparedStatement.getGeneratedKeys(); @@ -629,8 +629,8 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException(String.format("Failed to INSERT data source %s in central repo", eamDataSource.getName())); } int dataSourceId = resultSet.getInt(1); //last_insert_rowid() - CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getCaseDataSourceID()); - dataSourceCacheByDeviceId.put(getDataSourceByCaseDataSourceIdCacheKey(dataSource.getCaseID(), dataSource.getCaseDataSourceID()), dataSource); + CorrelationDataSource dataSource = new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getDataSourceObjectID()); + dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(dataSource.getCaseID(), dataSource.getDataSourceObjectID()), dataSource); dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource); return dataSource; } catch (SQLException ex) { @@ -643,24 +643,24 @@ abstract class AbstractSqlEamDb implements EamDb { } /** - * Retrieves Data Source details based on data source device ID + * Retrieves Data Source details based on data source object ID * * @param correlationCase the current CorrelationCase used for ensuring * uniqueness of DataSource - * @param dataSourceDeviceId the data source device ID number + * @param dataSourceObjectId the data source device ID number * * @return The data source * * @throws EamDbException */ @Override - public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException { + public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long dataSourceObjectId) throws EamDbException { if (correlationCase == null) { throw new EamDbException("Correlation case is null"); } try { - return dataSourceCacheByDeviceId.get(getDataSourceByCaseDataSourceIdCacheKey(correlationCase.getID(), caseDbDataSourceId), () -> getDataSourceFromCr(correlationCase, caseDbDataSourceId)); + return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), dataSourceObjectId), () -> getDataSourceFromCr(correlationCase, dataSourceObjectId)); } catch (CacheLoader.InvalidCacheLoadException ignored) { //lambda valueloader returned a null value and cache can not store null values this is normal if the dataSource does not exist in the central repo yet return null; @@ -681,18 +681,18 @@ abstract class AbstractSqlEamDb implements EamDb { * * @throws EamDbException */ - private CorrelationDataSource getDataSourceFromCr(CorrelationCase correlationCase, Long caseDbDataSourceId) throws EamDbException { + private CorrelationDataSource getDataSourceFromCr(CorrelationCase correlationCase, Long dataSourceObjectId) throws EamDbException { Connection conn = connect(); CorrelationDataSource eamDataSourceResult = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; - String sql = "SELECT * FROM data_sources WHERE datasource_id=? AND case_id=?"; // NON-NLS + String sql = "SELECT * FROM data_sources WHERE datasource_obj_id=? AND case_id=?"; // NON-NLS try { preparedStatement = conn.prepareStatement(sql); - preparedStatement.setLong(1, caseDbDataSourceId); + preparedStatement.setLong(1, dataSourceObjectId); preparedStatement.setInt(2, correlationCase.getID()); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { @@ -763,7 +763,7 @@ abstract class AbstractSqlEamDb implements EamDb { eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); } if (eamDataSourceResult != null) { - dataSourceCacheByDeviceId.put(getDataSourceByCaseDataSourceIdCacheKey(correlationCase.getID(), eamDataSourceResult.getCaseDataSourceID()), eamDataSourceResult); + dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDataSourceObjectID()), eamDataSourceResult); } } catch (SQLException ex) { throw new EamDbException("Error getting data source.", ex); // NON-NLS @@ -922,7 +922,7 @@ abstract class AbstractSqlEamDb implements EamDb { + ".value," + tableName + ".object_id," - + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_id FROM " + + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_obj_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -987,7 +987,7 @@ abstract class AbstractSqlEamDb implements EamDb { + ".value," + tableName + ".object_id," - + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_id FROM " + + " cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_obj_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -1248,7 +1248,7 @@ abstract class AbstractSqlEamDb implements EamDb { + tableName + " (case_id, data_source_id, value, file_path, known_status, comment, object_id) " + "VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), " - + "(SELECT id FROM data_sources WHERE datasource_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) " + + "(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) " + getConflictClause(); bulkPs = conn.prepareStatement(sql); @@ -1282,7 +1282,7 @@ abstract class AbstractSqlEamDb implements EamDb { if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) { bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID()); - bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getCaseDataSourceID()); + bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getDataSourceObjectID()); bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID()); bulkPs.setString(4, eamArtifact.getCorrelationValue()); bulkPs.setString(5, eamArtifact.getFilePath()); @@ -1669,7 +1669,7 @@ abstract class AbstractSqlEamDb implements EamDb { if (null == correlationCaseWithId) { correlationCaseWithId = newCase(eamArtifact.getCorrelationCase()); } - if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getCaseDataSourceID())) { + if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDataSourceObjectID())) { newDataSource(eamArtifact.getCorrelationDataSource()); } eamArtifact.setKnownStatus(knownStatus); @@ -1716,7 +1716,7 @@ abstract class AbstractSqlEamDb implements EamDb { + ".value, " + tableName + ".object_id," - + "cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_id FROM " + + "cases.case_name, cases.case_uid, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, data_sources.datasource_obj_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -1773,7 +1773,7 @@ abstract class AbstractSqlEamDb implements EamDb { String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType); String sql - = "SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, id, value, object_id, data_sources.datasource_id FROM " + = "SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, id, value, object_id, data_sources.datasource_obj_id FROM " + tableName + " LEFT JOIN cases ON " + tableName @@ -3056,7 +3056,7 @@ abstract class AbstractSqlEamDb implements EamDb { resultSet.getInt("id"), resultSet.getString("device_id"), resultSet.getString("name"), - resultSet.getLong("datasource_id") + resultSet.getLong("datasource_obj_id") ); return eamDataSource; @@ -3097,7 +3097,7 @@ abstract class AbstractSqlEamDb implements EamDb { resultSet.getString("value"), resultSet.getInt("id"), new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")), - new CorrelationDataSource(resultSet.getInt("case_id"), resultSet.getInt("data_source_id"), resultSet.getString("device_id"), resultSet.getString("name"), resultSet.getLong("datasource_id")), + new CorrelationDataSource(resultSet.getInt("case_id"), resultSet.getInt("data_source_id"), resultSet.getString("device_id"), resultSet.getString("name"), resultSet.getLong("datasource_obj_id")), resultSet.getString("file_path"), resultSet.getString("comment"), TskData.FileKnown.valueOf(resultSet.getByte("known_status")), @@ -3258,9 +3258,9 @@ abstract class AbstractSqlEamDb implements EamDb { throw new EamDbException("Currently selected database platform \"" + selectedPlatform.name() + "\" can not be upgraded."); } final String dataSourcesTableName = "data_sources"; - final String dataSourceIdColumnName = "datasource_id"; - if (!doesColumnExist(conn, dataSourcesTableName, dataSourceIdColumnName)) { - statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceIdColumnName)); //NON-NLS + final String dataSourceObjectIdColumnName = "datasource_obj_id"; + if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) { + statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName)); //NON-NLS } //WJS-TODO add index on datasource id column diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java index 444fe9e259..f5684966e7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java @@ -36,11 +36,14 @@ public class CorrelationDataSource implements Serializable { private final int caseID; //the value in the id column of the case table in the central repo private final int dataSourceID; //< Id in the central repo - private final Long caseDataSourceID; //< Id for data source in the caseDB + private final Long dataSourceObjectID; //< Id for data source in the caseDB private final String deviceID; //< Unique to its associated case (not necessarily globally unique) private final String name; /** + * Create a CorrelationDataSource object, the object will not have the data + * source id for the row in the central repository. + * * @param correlationCase CorrelationCase object data source is associated * with. Must have been created by EamDB and have a * valid ID. @@ -52,6 +55,7 @@ public class CorrelationDataSource implements Serializable { } /** + * Create a CorrelationDataSource object. * * @param caseId Row ID for Case in DB * @param dataSourceId Row ID for this data source in DB (or -1) @@ -67,7 +71,7 @@ public class CorrelationDataSource implements Serializable { this.dataSourceID = dataSourceId; this.deviceID = deviceId; this.name = name; - this.caseDataSourceID = caseDataSourceId; + this.dataSourceObjectID = caseDataSourceId; } /** @@ -155,10 +159,10 @@ public class CorrelationDataSource implements Serializable { /** * Get the id for the data source in the case db * - * @return caseDataSourceID or NULL if not available + * @return dataSourceObjectID or NULL if not available */ - public Long getCaseDataSourceID() { - return caseDataSourceID; + public Long getDataSourceObjectID() { + return dataSourceObjectID; } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java index 3d839be7a0..c4acd7e4e4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java @@ -25,6 +25,11 @@ import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; +/** + * Class which updates the data sources in the central repository to include the + * object id which ties them to the current case. + * + */ @ServiceProvider(service = AutopsyService.class) public class DataSourceUpdateService implements AutopsyService { @@ -42,7 +47,7 @@ public class DataSourceUpdateService implements AutopsyService { CorrelationCase correlationCase = centralRepository.getCase(context.getCase()); for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { //ResultSet.getLong has a value of 0 when the value is null - if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getCaseDataSourceID() == 0) { + if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getDataSourceObjectID() == 0) { for (Content dataSource : context.getCase().getDataSources()) { if (((DataSource) dataSource).getDeviceId().equals(correlationDataSource.getDeviceID())) { centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index 7d098fc590..9e271a96a5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -328,7 +328,6 @@ public class EamArtifactUtil { if (null == correlationCase) { correlationCase = EamDb.getInstance().newCase(Case.getCurrentCaseThrows()); } - return new CorrelationAttributeInstance( filesType, af.getMd5Hash(), diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index 92cf9aea4e..08627c5f96 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -204,6 +204,8 @@ public interface EamDb { * Creates new Data Source in the database * * @param eamDataSource the data source to add + * + * @return - A CorrelationDataSource object with data source's central repository id */ CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource) throws EamDbException; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java index bdc00be35b..0cfb45f76e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java @@ -344,7 +344,7 @@ public final class PostgresEamDbSettings { createDataSourcesTable.append("case_id integer NOT NULL,"); createDataSourcesTable.append("device_id text NOT NULL,"); createDataSourcesTable.append("name text NOT NULL,"); - createDataSourcesTable.append("datasource_id integer,"); + createDataSourcesTable.append("datasource_obj_id integer,"); createDataSourcesTable.append("foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"); createDataSourcesTable.append("CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name)"); createDataSourcesTable.append(")"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java index b806dba3b6..72bbe6a3b6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java @@ -287,7 +287,7 @@ public final class SqliteEamDbSettings { createDataSourcesTable.append("case_id integer NOT NULL,"); createDataSourcesTable.append("device_id text NOT NULL,"); createDataSourcesTable.append("name text NOT NULL,"); - createDataSourcesTable.append("datasource_id integer,"); + createDataSourcesTable.append("datasource_obj_id integer,"); createDataSourcesTable.append("foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"); createDataSourcesTable.append("CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name)"); createDataSourcesTable.append(")"); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index f77f90b38f..0eecc533b0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -303,7 +303,7 @@ final class IngestModule implements FileIngestModule { == 1) { // ensure we have this data source in the EAM DB try { - if (null == centralRepoDb.getDataSource(eamCase, eamDataSource.getCaseDataSourceID())) { + if (null == centralRepoDb.getDataSource(eamCase, eamDataSource.getDataSourceObjectID())) { centralRepoDb.newDataSource(eamDataSource); } } catch (EamDbException ex) { From 276d15e01cd53a11aa64b019927ded3ec236e5a5 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 18:05:09 -0500 Subject: [PATCH 22/32] 4361 add indexes for datasource_obj_id to creation and upgrade code --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 4 +++- .../centralrepository/datamodel/PostgresEamDbSettings.java | 4 +++- .../centralrepository/datamodel/SqliteEamDbSettings.java | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 37823a37a9..7dc0d129f5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -3262,11 +3262,13 @@ abstract class AbstractSqlEamDb implements EamDb { if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) { statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName)); //NON-NLS } - //WJS-TODO add index on datasource id column + final String dataSourceObjectIdIndexTemplate = "CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)"; + statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName)); //update central repository to be able to store new correlation attributes final String wirelessNetworsDbTableName = "wireless_networks"; final String wirelessNetworksTableInstanceName = wirelessNetworsDbTableName + "_instances"; + //add the wireless_networks attribute to the correlation_types table preparedStatement = conn.prepareStatement(addAttributeSql); preparedStatement.setInt(1, CorrelationAttributeInstance.SSID_TYPE_ID); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java index 0cfb45f76e..dfad9a1760 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresEamDbSettings.java @@ -350,6 +350,7 @@ public final class PostgresEamDbSettings { createDataSourcesTable.append(")"); String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)"; + String dataSourceIdx2 = "CREATE INDEX IF NOT EXISTS data_sources_object_id ON data_sources (datasource_obj_id)"; StringBuilder createReferenceSetsTable = new StringBuilder(); createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets ("); @@ -426,7 +427,8 @@ public final class PostgresEamDbSettings { stmt.execute(createDataSourcesTable.toString()); stmt.execute(dataSourceIdx1); - + stmt.execute(dataSourceIdx2); + stmt.execute(createReferenceSetsTable.toString()); stmt.execute(referenceSetsIdx1); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java index 72bbe6a3b6..6544609e34 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDbSettings.java @@ -293,6 +293,7 @@ public final class SqliteEamDbSettings { createDataSourcesTable.append(")"); String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)"; + String dataSourceIdx2 = "CREATE INDEX IF NOT EXISTS data_sources_object_id ON data_sources (datasource_obj_id)"; StringBuilder createReferenceSetsTable = new StringBuilder(); createReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS reference_sets ("); @@ -375,6 +376,7 @@ public final class SqliteEamDbSettings { stmt.execute(createDataSourcesTable.toString()); stmt.execute(dataSourceIdx1); + stmt.execute(dataSourceIdx2); stmt.execute(createReferenceSetsTable.toString()); stmt.execute(referenceSetsIdx1); From bace99fd711709ec293303e318758a3d64d26207 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 15 Nov 2018 18:08:28 -0500 Subject: [PATCH 23/32] 4361 replace cryptic comment with more descriptive one regarding large query --- .../autopsy/centralrepository/datamodel/AbstractSqlEamDb.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 7dc0d129f5..9ea011d897 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -1165,7 +1165,7 @@ abstract class AbstractSqlEamDb implements EamDb { PreparedStatement preparedStatement = null; ResultSet resultSet = null; - // Figure out sql variables or subqueries + //Create query to get count of all instances in the database for the specified case specific data source String sql = "SELECT 0 "; for (CorrelationAttributeInstance.Type type : artifactTypes) { From 4a0be9ecf8b25b6f970a7d020d797f1cc851bbb0 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 16 Nov 2018 16:34:10 -0500 Subject: [PATCH 24/32] 4361 do not attempt to update CR data sources when case is not present --- .../datamodel/DataSourceUpdateService.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java index c4acd7e4e4..4e30a25ead 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java @@ -45,16 +45,19 @@ public class DataSourceUpdateService implements AutopsyService { try { EamDb centralRepository = EamDb.getInstance(); CorrelationCase correlationCase = centralRepository.getCase(context.getCase()); - for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { - //ResultSet.getLong has a value of 0 when the value is null - if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getDataSourceObjectID() == 0) { - for (Content dataSource : context.getCase().getDataSources()) { - if (((DataSource) dataSource).getDeviceId().equals(correlationDataSource.getDeviceID())) { - centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); - break; + //if the case isn't in the central repository yet there won't be data sources in it to update + if (correlationCase != null) { + for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { + //ResultSet.getLong has a value of 0 when the value is null + if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getDataSourceObjectID() == 0) { + for (Content dataSource : context.getCase().getDataSources()) { + if (((DataSource) dataSource).getDeviceId().equals(correlationDataSource.getDeviceID())) { + centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); + break; + } } - } + } } } } catch (EamDbException | TskCoreException ex) { From ec94b8ecde8e2c4996f424c4c1604a442a8e32b3 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 16 Nov 2018 16:34:59 -0500 Subject: [PATCH 25/32] 4361 remove empty line white space change --- .../centralrepository/datamodel/DataSourceUpdateService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java index 4e30a25ead..16cc5b58c7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java @@ -46,7 +46,7 @@ public class DataSourceUpdateService implements AutopsyService { EamDb centralRepository = EamDb.getInstance(); CorrelationCase correlationCase = centralRepository.getCase(context.getCase()); //if the case isn't in the central repository yet there won't be data sources in it to update - if (correlationCase != null) { + if (correlationCase != null) { for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { //ResultSet.getLong has a value of 0 when the value is null if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getDataSourceObjectID() == 0) { @@ -56,7 +56,6 @@ public class DataSourceUpdateService implements AutopsyService { break; } } - } } } From 4fabe289d180b7b08c95dd8c46f4e81656bda79a Mon Sep 17 00:00:00 2001 From: esaunders Date: Mon, 19 Nov 2018 17:58:31 -0500 Subject: [PATCH 26/32] Removed columns from results table. --- .../datamodel/AbstractAbstractFileNode.java | 24 ------------------- .../autopsy/datamodel/Bundle_ja.properties | 8 ------- 2 files changed, 32 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 5f8ea3d63f..61c9e59830 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -187,16 +187,8 @@ public abstract class AbstractAbstractFileNode extends A "AbstractAbstractFileNode.sizeColLbl=Size", "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)", "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)", - "AbstractAbstractFileNode.modeColLbl=Mode", - "AbstractAbstractFileNode.useridColLbl=UserID", - "AbstractAbstractFileNode.groupidColLbl=GroupID", - "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.", - "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.", - "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)", - "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)", "AbstractAbstractFileNode.knownColLbl=Known", "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash", - "AbstractAbstractFileNode.objectId=Object ID", "AbstractAbstractFileNode.mimeType=MIME Type", "AbstractAbstractFileNode.extensionColLbl=Extension"}) public enum AbstractFilePropertyType { @@ -210,16 +202,8 @@ public abstract class AbstractAbstractFileNode extends A SIZE(AbstractAbstractFileNode_sizeColLbl()), FLAGS_DIR(AbstractAbstractFileNode_flagsDirColLbl()), FLAGS_META(AbstractAbstractFileNode_flagsMetaColLbl()), - MODE(AbstractAbstractFileNode_modeColLbl()), - USER_ID(AbstractAbstractFileNode_useridColLbl()), - GROUP_ID(AbstractAbstractFileNode_groupidColLbl()), - META_ADDR(AbstractAbstractFileNode_metaAddrColLbl()), - ATTR_ADDR(AbstractAbstractFileNode_attrAddrColLbl()), - TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()), - TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()), KNOWN(AbstractAbstractFileNode_knownColLbl()), MD5HASH(AbstractAbstractFileNode_md5HashColLbl()), - ObjectID(AbstractAbstractFileNode_objectId()), MIMETYPE(AbstractAbstractFileNode_mimeType()), EXTENSION(AbstractAbstractFileNode_extensionColLbl()); @@ -252,16 +236,8 @@ public abstract class AbstractAbstractFileNode extends A map.put(SIZE.toString(), content.getSize()); map.put(FLAGS_DIR.toString(), content.getDirFlagAsString()); map.put(FLAGS_META.toString(), content.getMetaFlagsAsString()); - map.put(MODE.toString(), content.getModesAsString()); - map.put(USER_ID.toString(), content.getUid()); - map.put(GROUP_ID.toString(), content.getGid()); - map.put(META_ADDR.toString(), content.getMetaAddr()); - map.put(ATTR_ADDR.toString(), content.getAttrType().getValue() + "-" + content.getAttributeId()); - map.put(TYPE_DIR.toString(), content.getDirType().getLabel()); - map.put(TYPE_META.toString(), content.getMetaType().toString()); map.put(KNOWN.toString(), content.getKnown().getName()); map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash())); - map.put(ObjectID.toString(), content.getId()); map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType())); map.put(EXTENSION.toString(), content.getNameExtension()); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties index 2f91dfb27a..34a1274c32 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle_ja.properties @@ -6,9 +6,6 @@ AbstractAbstractFileNode.changeTimeColLbl=\u5909\u66f4\u65e5\u6642 AbstractAbstractFileNode.accessTimeColLbl=\u30a2\u30af\u30bb\u30b9\u65e5\u6642 AbstractAbstractFileNode.createdTimeColLbl=\u4f5c\u6210\u65e5\u6642 AbstractAbstractFileNode.sizeColLbl=\u30b5\u30a4\u30ba -AbstractAbstractFileNode.modeColLbl=\u30e2\u30fc\u30c9 -AbstractAbstractFileNode.useridColLbl=\u30e6\u30fc\u30b6ID -AbstractAbstractFileNode.groupidColLbl=\u30b0\u30eb\u30fc\u30d7ID AbstractAbstractFileNode.knownColLbl=\u65e2\u77e5 AbstractAbstractFileNode.md5HashColLbl=MD5\u30cf\u30c3\u30b7\u30e5 AbstractContentChildren.CreateTSKNodeVisitor.exception.noNodeMsg=\u6307\u5b9a\u3055\u308c\u305fSleuthkitItem\u306e\u30ce\u30fc\u30c9\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093 @@ -198,10 +195,6 @@ TagsNode.displayName.text=\u30bf\u30b0 TagsNode.createSheet.name.name=\u540d\u524d AbstractAbstractFileNode.flagsDirColLbl=\u30d5\u30e9\u30b0\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\uff09 AbstractAbstractFileNode.flagsMetaColLbl=\u30d5\u30e9\u30b0\uff08\u30e1\u30bf\u30c7\u30fc\u30bf\uff09 -AbstractAbstractFileNode.metaAddrColLbl=\u30e1\u30bf\u30c7\u30fc\u30bf\u30a2\u30c9\u30ec\u30b9 -AbstractAbstractFileNode.attrAddrColLbl=\u5c5e\u6027\u30a2\u30c9\u30ec\u30b9 -AbstractAbstractFileNode.typeDirColLbl=\u30bf\u30a4\u30d7\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\uff09 -AbstractAbstractFileNode.typeMetaColLbl=\u30bf\u30a4\u30d7\uff08\u30e1\u30bf\u30c7\u30fc\u30bf\uff09 ArtifactTypeNode.createSheet.childCnt.displayName=\u30c1\u30e3\u30a4\u30eb\u30c9\u6570 TagsNode.createSheet.name.displayName=\u540d\u524d ViewsNode.name.text=\u30d3\u30e5\u30fc @@ -238,7 +231,6 @@ KeywordHits.createSheet.numChildren.name=\u30c1\u30e3\u30a4\u30eb\u30c9\u6570 KeywordHits.createSheet.numChildren.displayName=\u30c1\u30e3\u30a4\u30eb\u30c9\u6570 KeywordHits.simpleLiteralSearch.text=\u30b7\u30f3\u30b0\u30eb\u30ea\u30c6\u30e9\u30eb\u691c\u7d22 KeywordHits.singleRegexSearch.text=\u30b7\u30f3\u30b0\u30eb\u6b63\u898f\u8868\u73fe\u691c\u7d22 -AbstractAbstractFileNode.objectId=\u30aa\u30d6\u30b8\u30a7\u30af\u30c8ID ArtifactStringContent.getStr.artifactId.text=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8ID OpenReportAction.actionDisplayName=\u30ec\u30dd\u30fc\u30c8\u3092\u958b\u304f OpenReportAction.actionPerformed.MessageBoxTitle=\u5931\u6557\u30ec\u30dd\u30fc\u30c8\u3092\u958b\u304f From 03af3136acfe5fd0148cd90eef7c63f9f901d191 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Tue, 20 Nov 2018 00:59:29 -0500 Subject: [PATCH 27/32] Fixed column sorting bug; added case count to dialog. --- .../othercasessearch/Bundle.properties | 3 +- .../OtherCasesFilterChildren.java | 3 +- .../OtherCasesFilterNode.java | 134 ------------------ .../OtherCasesSearchDialog.form | 25 +++- .../OtherCasesSearchDialog.java | 38 +++-- .../OtherCasesSearchNode.java | 4 - 6 files changed, 46 insertions(+), 161 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties index ff51e4ca22..17ea13ee0b 100755 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/Bundle.properties @@ -5,5 +5,6 @@ OtherCasesSearchDialog.searchButton.text=Search OtherCasesSearchDialog.correlationValueTextField.text= OtherCasesSearchDialog.correlationValueLabel.text=Correlation Property Value: OtherCasesSearchDialog.descriptionLabel.text=Search data in the Central Repository from other cases. -OtherCasesSearchDialog.errorLabel.text= +OtherCasesSearchDialog.errorLabel.text=\ OtherCasesSearchDialog.correlationTypeLabel.text=Correlation Property Type: +OtherCasesSearchDialog.casesLabel.text=\ diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java index 72edf98cd9..abe37bb15e 100755 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterChildren.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.othercasessearch; import org.openide.nodes.Children; import org.openide.nodes.FilterNode; import org.openide.nodes.Node; +import org.sleuthkit.autopsy.corecomponents.TableFilterNode; /** * A Children implementation for a @@ -66,7 +67,7 @@ final class OtherCasesFilterChildren extends FilterNode.Children { */ @Override protected Node copyNode(Node nodeToCopy) { - return new OtherCasesFilterNode(nodeToCopy, false); + return new TableFilterNode(nodeToCopy, false); } /** diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java deleted file mode 100755 index 8cf27fd507..0000000000 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesFilterNode.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.othercasessearch; - -import org.openide.nodes.FilterNode; -import org.openide.nodes.Node; -import org.openide.util.NbBundle; -import org.openide.util.lookup.Lookups; -import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; -import org.sleuthkit.autopsy.directorytree.DataResultFilterNode; - -/** - * FilterNode containing properties and actions for the other cases search. - */ -final class OtherCasesFilterNode extends FilterNode { - - private final boolean createChildren; - private final boolean forceUseWrappedDisplayName; - private String columnOrderKey = "NONE"; - - /** - * Constructs a filter node that creates at most one layer of child nodes - * for the node it wraps. It is designed to be used in the results view to - * ensure the individual viewers display only the first layer of child - * nodes. - * - * @param node The node to wrap in the filter node. - * @param createChildren True if a Children object should be created for the - * wrapped node. - */ - OtherCasesFilterNode(Node node, boolean createChildren) { - super(node, OtherCasesFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); - this.forceUseWrappedDisplayName = false; - this.createChildren = createChildren; - } - - /** - * Constructs a filter node that creates at most one layer of child nodes - * for the node it wraps. It is designed to be used in the results view to - * ensure the individual viewers display only the first layer of child - * nodes. - * - * @param node The node to wrap in the filter node. - * @param createChildren True if a Children object should be created for the - * wrapped node. - * @param columnOrderKey A key that represents the type of the original - * wrapped node and what is being displayed under that node. - */ - OtherCasesFilterNode(Node node, boolean createChildren, String columnOrderKey) { - super(node, OtherCasesFilterChildren.createInstance(node, createChildren), Lookups.proxy(node)); - this.forceUseWrappedDisplayName = false; - this.createChildren = createChildren; - this.columnOrderKey = columnOrderKey; - } - - /** - * Gets the display name for the wrapped node, for use in the first column - * of an Autopsy table view. - * - * @return The display name. - */ - @Override - public String getDisplayName() { - if (this.forceUseWrappedDisplayName) { - return super.getDisplayName(); - } else if (createChildren) { - return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text"); - } else { - return super.getDisplayName(); - } - } - - /** - * Adds information about which child node of this node, if any, should be - * selected. Can be null. - * - * @param selectedChildNodeInfo The child node selection information. - */ - void setChildNodeSelectionInfo(NodeSelectionInfo selectedChildNodeInfo) { - /* - * Currently, child selection is only supported for nodes selected in - * the tree view and decorated with a DataResultFilterNode. - */ - if (getOriginal() instanceof DataResultFilterNode) { - ((DataResultFilterNode) getOriginal()).setChildNodeSelectionInfo(selectedChildNodeInfo); - } - } - - /** - * Gets information about which child node of this node, if any, should be - * selected. - * - * @return The child node selection information, or null if no child should - * be selected. - */ - NodeSelectionInfo getChildNodeSelectionInfo() { - /* - * Currently, child selection is only supported for nodes selected in - * the tree view and decorated with a DataResultFilterNode. - */ - if (getOriginal() instanceof DataResultFilterNode) { - return ((DataResultFilterNode) getOriginal()).getChildNodeSelectionInfo(); - } else { - return null; - } - } - - /** - * @return the column order key, which allows custom column ordering to be - * written into a properties file and be reloaded for future use in a table - * with the same root node or for different cases. This is done by - * DataResultViewerTable. The key should represent what kinds of items the - * table is showing. - */ - String getColumnOrderKey() { - return columnOrderKey; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form index cbe9506133..00eb862b4a 100755 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.form @@ -28,10 +28,14 @@ - + + + + + @@ -41,12 +45,9 @@ + - - - - @@ -67,10 +68,12 @@ - + + + - + @@ -144,5 +147,13 @@ + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java index d691e078cb..86d037865e 100755 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java @@ -41,14 +41,12 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributesSearchResultsViewerTable; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.othercasessearch.Bundle; import org.sleuthkit.autopsy.datamodel.EmptyNode; @Messages({ @@ -56,7 +54,9 @@ import org.sleuthkit.autopsy.datamodel.EmptyNode; "OtherCasesSearchDialog.resultsTitle.text=Other Cases", "OtherCasesSearchDialog.resultsDescription.text=Other Cases Search", "OtherCasesSearchDialog.emptyNode.text=No results found.", - "OtherCasesSearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash." + "OtherCasesSearchDialog.validation.invalidHash=The supplied value is not a valid MD5 hash.", + "# {0} - number of cases", + "OtherCasesSearchDialog.caseLabel.text=The current Central Repository contains {0} case(s)." }) /** * The Search Other Cases dialog allows users to search for specific @@ -113,12 +113,12 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { try { super.done(); List correlationInstances = this.get(); - DataResultViewerTable table = new CommonAttributesSearchResultsViewerTable(); + DataResultViewerTable table = new DataResultViewerTable(); Collection viewers = new ArrayList<>(1); viewers.add(table); OtherCasesSearchNode searchNode = new OtherCasesSearchNode(correlationInstances); - OtherCasesFilterNode tableFilterNode = new OtherCasesFilterNode(searchNode, true, searchNode.getName()); + TableFilterNode tableFilterNode = new TableFilterNode(searchNode, true, searchNode.getName()); String resultsText = String.format("%s (%s; \"%s\")", Bundle.OtherCasesSearchDialog_resultsTitle_text(), @@ -132,7 +132,7 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { resultsText, Bundle.OtherCasesSearchDialog_resultsDescription_text(), emptyNode, 0); } else { searchResultWin = DataResultTopComponent.createInstance( - resultsText, Bundle.OtherCasesSearchDialog_resultsDescription_text(), tableFilterNode, HIDE_ON_CLOSE, viewers); + resultsText, Bundle.OtherCasesSearchDialog_resultsDescription_text(), tableFilterNode, correlationInstances.size(), viewers); } searchResultWin.requestActive(); // make it the active top component } catch (ExecutionException | InterruptedException ex) { @@ -158,6 +158,7 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { correlationTypeLabel = new javax.swing.JLabel(); errorLabel = new javax.swing.JLabel(); descriptionLabel = new javax.swing.JLabel(); + casesLabel = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setResizable(false); @@ -180,6 +181,9 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.descriptionLabel.text")); // NOI18N + casesLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + org.openide.awt.Mnemonics.setLocalizedText(casesLabel, org.openide.util.NbBundle.getMessage(OtherCasesSearchDialog.class, "OtherCasesSearchDialog.casesLabel.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -188,9 +192,12 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(casesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(18, 18, 18) .addComponent(searchButton)) + .addGroup(layout.createSequentialGroup() + .addComponent(descriptionLabel) + .addGap(0, 0, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(correlationValueLabel) @@ -198,10 +205,8 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(correlationTypeComboBox, 0, 289, Short.MAX_VALUE) - .addComponent(correlationValueTextField))) - .addGroup(layout.createSequentialGroup() - .addComponent(descriptionLabel) - .addGap(0, 0, Short.MAX_VALUE))) + .addComponent(correlationValueTextField) + .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( @@ -217,10 +222,12 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(correlationValueLabel) .addComponent(correlationValueTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(errorLabel) + .addGap(11, 11, 11) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(searchButton) - .addComponent(errorLabel)) + .addComponent(casesLabel)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -261,8 +268,10 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { EamDb dbManager = EamDb.getInstance(); correlationTypes.clear(); correlationTypes.addAll(dbManager.getDefinedCorrelationTypes()); + int numberOfCases = dbManager.getCases().size(); + casesLabel.setText(Bundle.OtherCasesSearchDialog_caseLabel_text(numberOfCases)); } catch (EamDbException ex) { - Exceptions.printStackTrace(ex); + logger.log(Level.SEVERE, "Unable to connect to the Central Repository database.", ex); } for (CorrelationAttributeInstance.Type type : correlationTypes) { @@ -358,6 +367,7 @@ final class OtherCasesSearchDialog extends javax.swing.JDialog { } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel casesLabel; private javax.swing.JComboBox correlationTypeComboBox; private javax.swing.JLabel correlationTypeLabel; private javax.swing.JLabel correlationValueLabel; diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java index 312744ffdc..ff9c3a6d80 100755 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchNode.java @@ -22,15 +22,12 @@ import java.util.List; import org.openide.nodes.AbstractNode; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; -import org.sleuthkit.autopsy.othercasessearch.Bundle; /** * Parent node to OtherCasesSearchChildren. */ class OtherCasesSearchNode extends AbstractNode { - private OtherCasesSearchChildren children; - /** * Create an instance of OtherCasesSearchNode. * @@ -38,7 +35,6 @@ class OtherCasesSearchNode extends AbstractNode { */ OtherCasesSearchNode(List keys) { super(new OtherCasesSearchChildren(true, keys)); - this.children = (OtherCasesSearchChildren) this.getChildren(); } @Messages({ From ab78771f52c153f749970634f8f354b7e7a88a27 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Tue, 20 Nov 2018 10:44:37 -0500 Subject: [PATCH 28/32] Added missing annotation for Codacy. --- .../autopsy/othercasessearch/OtherCasesSearchDialog.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java index 86d037865e..51e21631d2 100755 --- a/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java +++ b/Core/src/org/sleuthkit/autopsy/othercasessearch/OtherCasesSearchDialog.java @@ -62,8 +62,10 @@ import org.sleuthkit.autopsy.datamodel.EmptyNode; * The Search Other Cases dialog allows users to search for specific * types of correlation properties in the Central Repository. */ +@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class OtherCasesSearchDialog extends javax.swing.JDialog { private static final Logger logger = Logger.getLogger(OtherCasesSearchDialog.class.getName()); + private static final long serialVersionUID = 1L; private static final String FILES_CORRELATION_TYPE = "Files"; From 82104e12354c3b5e3973bb6227e1c0a33c97380c Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 20 Nov 2018 11:16:08 -0500 Subject: [PATCH 29/32] 4361 update comments to reflect changes from device id to ds obj id dependence --- .../datamodel/AbstractSqlEamDb.java | 4 +-- .../datamodel/CorrelationDataSource.java | 30 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 58e92c2119..0de53fa409 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -647,7 +647,7 @@ abstract class AbstractSqlEamDb implements EamDb { * * @param correlationCase the current CorrelationCase used for ensuring * uniqueness of DataSource - * @param dataSourceObjectId the data source device ID number + * @param dataSourceObjectId the object id of the data source * * @return The data source * @@ -675,7 +675,7 @@ abstract class AbstractSqlEamDb implements EamDb { * * @param correlationCase the current CorrelationCase used for ensuring * uniqueness of DataSource - * @param dataSourceDeviceId the data source device ID number + * @param dataSourceDeviceId the object id of the data source * * @return The data source * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java index f5684966e7..b1d48d07b2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java @@ -44,34 +44,36 @@ public class CorrelationDataSource implements Serializable { * Create a CorrelationDataSource object, the object will not have the data * source id for the row in the central repository. * - * @param correlationCase CorrelationCase object data source is associated - * with. Must have been created by EamDB and have a - * valid ID. - * @param deviceId User specified case-specific ID - * @param name Display name of data source + * @param correlationCase CorrelationCase object data source is + * associated with. Must have been created by + * EamDB and have a valid ID. + * @param deviceId User specified case-specific ID + * @param name Display name of data source + * @param dataSourceObjectId The object ID for the datasource */ - public CorrelationDataSource(CorrelationCase correlationCase, String deviceId, String name, long caseDataSourceId) { - this(correlationCase.getID(), -1, deviceId, name, caseDataSourceId); + public CorrelationDataSource(CorrelationCase correlationCase, String deviceId, String name, long dataSourceObjectId) { + this(correlationCase.getID(), -1, deviceId, name, dataSourceObjectId); } /** * Create a CorrelationDataSource object. * - * @param caseId Row ID for Case in DB - * @param dataSourceId Row ID for this data source in DB (or -1) - * @param deviceId User specified ID for device (unique per case) - * @param name User specified name + * @param caseId Row ID for Case in DB + * @param dataSourceId Row ID for this data source in DB (or -1) + * @param deviceId User specified ID for device (unique per case) + * @param name User specified name + * @param dataSourceObjectId The object ID for the datasource */ CorrelationDataSource(int caseId, int dataSourceId, String deviceId, String name, - Long caseDataSourceId) { + Long dataSourceObjectId) { this.caseID = caseId; this.dataSourceID = dataSourceId; this.deviceID = deviceId; this.name = name; - this.dataSourceObjectID = caseDataSourceId; + this.dataSourceObjectID = dataSourceObjectId; } /** @@ -157,7 +159,7 @@ public class CorrelationDataSource implements Serializable { } /** - * Get the id for the data source in the case db + * Get the object id for the data source in the case db * * @return dataSourceObjectID or NULL if not available */ From d3cc7db9951b32df7d673272bce2371d06ee02e0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Tue, 20 Nov 2018 13:05:35 -0500 Subject: [PATCH 30/32] Changed close() to only close connection and not redundantly close table resources --- Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java index 286d6c672a..fdfcffd589 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/SQLiteTableReader.java @@ -528,7 +528,6 @@ public class SQLiteTableReader implements AutoCloseable { @Override public void close() throws SQLiteTableReaderException { try { - closeTableResources(); if (Objects.nonNull(conn)) { conn.close(); } From a33ed9124bb5a63e5f7f242a07f0b0870b07ebbb Mon Sep 17 00:00:00 2001 From: esaunders Date: Tue, 20 Nov 2018 13:09:30 -0500 Subject: [PATCH 31/32] Resolved merge conflicts. --- .../datamodel/AbstractAbstractFileNode.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 43b3dd5143..e5016b89ec 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -375,16 +375,8 @@ public abstract class AbstractAbstractFileNode extends A properties.add(new NodeProperty<>(SIZE.toString(), SIZE.toString(), NO_DESCR, content.getSize())); properties.add(new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(), NO_DESCR, content.getDirFlagAsString())); properties.add(new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(), NO_DESCR, content.getMetaFlagsAsString())); - properties.add(new NodeProperty<>(MODE.toString(), MODE.toString(), NO_DESCR, content.getModesAsString())); - properties.add(new NodeProperty<>(USER_ID.toString(), USER_ID.toString(), NO_DESCR, content.getUid())); - properties.add(new NodeProperty<>(GROUP_ID.toString(), GROUP_ID.toString(), NO_DESCR, content.getGid())); - properties.add(new NodeProperty<>(META_ADDR.toString(), META_ADDR.toString(), NO_DESCR, content.getMetaAddr())); - properties.add(new NodeProperty<>(ATTR_ADDR.toString(), ATTR_ADDR.toString(), NO_DESCR, content.getAttrType().getValue() + "-" + content.getAttributeId())); - properties.add(new NodeProperty<>(TYPE_DIR.toString(), TYPE_DIR.toString(), NO_DESCR, content.getDirType().getLabel())); - properties.add(new NodeProperty<>(TYPE_META.toString(), TYPE_META.toString(), NO_DESCR, content.getMetaType().toString())); properties.add(new NodeProperty<>(KNOWN.toString(), KNOWN.toString(), NO_DESCR, content.getKnown().getName())); properties.add(new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getMd5Hash()))); - properties.add(new NodeProperty<>(ObjectID.toString(), ObjectID.toString(), NO_DESCR, content.getId())); properties.add(new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(), NO_DESCR, StringUtils.defaultString(content.getMIMEType()))); properties.add(new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(), NO_DESCR, content.getNameExtension())); @@ -615,16 +607,8 @@ public abstract class AbstractAbstractFileNode extends A map.put(SIZE.toString(), content.getSize()); map.put(FLAGS_DIR.toString(), content.getDirFlagAsString()); map.put(FLAGS_META.toString(), content.getMetaFlagsAsString()); - map.put(MODE.toString(), content.getModesAsString()); - map.put(USER_ID.toString(), content.getUid()); - map.put(GROUP_ID.toString(), content.getGid()); - map.put(META_ADDR.toString(), content.getMetaAddr()); - map.put(ATTR_ADDR.toString(), content.getAttrType().getValue() + "-" + content.getAttributeId()); - map.put(TYPE_DIR.toString(), content.getDirType().getLabel()); - map.put(TYPE_META.toString(), content.getMetaType().toString()); map.put(KNOWN.toString(), content.getKnown().getName()); map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash())); - map.put(ObjectID.toString(), content.getId()); map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType())); map.put(EXTENSION.toString(), content.getNameExtension()); } From 3acf779e95b4f30d86c8b222b23621e7d41ab309 Mon Sep 17 00:00:00 2001 From: Raman Date: Wed, 21 Nov 2018 09:22:51 -0500 Subject: [PATCH 32/32] 1136: Intermittent error: "Error marking group as seen" --- .../imagegallery/ImageGalleryController.java | 40 +++---------------- .../imagegallery/ImageGalleryModule.java | 9 +---- .../datamodel/grouping/GroupManager.java | 2 +- 3 files changed, 7 insertions(+), 44 deletions(-) diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java index abe89abf40..862713a807 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java @@ -599,10 +599,11 @@ public final class ImageGalleryController { } } + /** - * Abstract base class for tasks associated with a file in the database + * task that updates one file in database with results from ingest */ - static abstract class FileTask extends BackgroundTask { + static class UpdateFileTask extends BackgroundTask { private final AbstractFile file; private final DrawableDB taskDB; @@ -614,22 +615,12 @@ public final class ImageGalleryController { public AbstractFile getFile() { return file; } - - FileTask(AbstractFile f, DrawableDB taskDB) { + + UpdateFileTask(AbstractFile f, DrawableDB taskDB) { super(); this.file = f; this.taskDB = taskDB; } - } - - /** - * task that updates one file in database with results from ingest - */ - static class UpdateFileTask extends FileTask { - - UpdateFileTask(AbstractFile f, DrawableDB taskDB) { - super(f, taskDB); - } /** * Update a file in the database @@ -645,27 +636,6 @@ public final class ImageGalleryController { } } - /** - * task that updates one file in database with results from ingest - */ - static class RemoveFileTask extends FileTask { - - RemoveFileTask(AbstractFile f, DrawableDB taskDB) { - super(f, taskDB); - } - - /** - * Update a file in the database - */ - @Override - public void run() { - try { - getTaskDB().removeFile(getFile().getId()); - } catch (TskCoreException | SQLException ex) { - Logger.getLogger(RemoveFileTask.class.getName()).log(Level.SEVERE, "Error in remove file task", ex); //NON-NLS - } - } - } /** * Base abstract class for various methods of copying image files data, for diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryModule.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryModule.java index 530e3eb7d6..5341e0be27 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryModule.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryModule.java @@ -189,14 +189,7 @@ public class ImageGalleryModule { if (isDrawableAndNotKnown(file)) { con.queueDBTask(new ImageGalleryController.UpdateFileTask(file, controller.getDatabase())); } - // Remove it from the DB if it is no longer relevant, but had the correct extension - else if (FileTypeUtils.getAllSupportedExtensions().contains(file.getNameExtension())) { - /* Doing this check results in fewer tasks queued - * up, and faster completion of db update. This file - * would have gotten scooped up in initial grab, but - * actually we don't need it */ - con.queueDBTask(new ImageGalleryController.RemoveFileTask(file, controller.getDatabase())); - } + } catch (FileTypeDetector.FileTypeDetectorInitException ex) { logger.log(Level.SEVERE, "Unable to determine if file is drawable and not known. Not making any changes to DB", ex); //NON-NLS MessageNotifyUtil.Notify.error("Image Gallery Error", diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/grouping/GroupManager.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/grouping/GroupManager.java index 99069b7790..0b52e0ff0e 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/grouping/GroupManager.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/grouping/GroupManager.java @@ -279,7 +279,7 @@ public class GroupManager { updateUnSeenGroups(group); } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error marking group as seen", ex); //NON-NLS + logger.log(Level.SEVERE, String.format("Error setting seen status for group: %s", group.getGroupKey().getValue().toString()), ex); //NON-NLS } }); }