diff --git a/Core/ivy.xml b/Core/ivy.xml
index c60161dd90..f20453a141 100644
--- a/Core/ivy.xml
+++ b/Core/ivy.xml
@@ -26,7 +26,6 @@
-
diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index 335ff4fbc3..7fbc57db78 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -35,7 +35,6 @@ file.reference.tika-parsers-1.17.jar=release/modules/ext/tika-parsers-1.17.jar
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
-file.reference.xlsx-streamer-1.2.1.jar=release/modules/ext/xlsx-streamer-1.2.1.jar
file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
file.reference.xz-1.6.jar=release/modules/ext/xz-1.6.jar
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index 50ffa2b436..0c61555746 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -497,10 +497,6 @@
ext/SparseBitSet-1.1.jar
release/modules/ext/SparseBitSet-1.1.jar
-
- ext/xlsx-streamer-1.2.1.jar
- release/modules/ext/xlsx-streamer-1.2.1.jar
-
ext/pdfbox-2.0.8.jar
release/modules/ext/pdfbox-2.0.8.jar
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java b/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java
index 95dfad8c5d..8cbf645bfa 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java
@@ -203,11 +203,11 @@ public class SingleUserCaseConverter {
icd.getCaseOutputFolder().toString(),
icd.getNewCaseName(),
new CaseDetails(icd.getNewCaseName(),
- oldCaseMetadata.getCaseNumber(),
- oldCaseMetadata.getExaminer(),
- oldCaseMetadata.getExaminerPhone(),
- oldCaseMetadata.getExaminerEmail(),
- oldCaseMetadata.getCaseNotes()));
+ oldCaseMetadata.getCaseNumber(),
+ oldCaseMetadata.getExaminer(),
+ oldCaseMetadata.getExaminerPhone(),
+ oldCaseMetadata.getExaminerEmail(),
+ oldCaseMetadata.getCaseNotes()));
newCaseMetadata.setCaseDatabaseName(dbName);
// Set created date. This calls writefile, no need to call it again
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
@@ -850,7 +850,7 @@ public class SingleUserCaseConverter {
// content_tags
biggestPK = 0;
inputStatement = sqliteConnection.createStatement();
- inputResultSet = inputStatement.executeQuery("SELECT * FROM content_tags"); //NON-NLS
+ inputResultSet = inputStatement.executeQuery("SELECT * FROM content_tags LEFT OUTER JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id"); //NON-NLS
while (inputResultSet.next()) {
outputStatement = postgreSQLConnection.createStatement();
@@ -859,14 +859,14 @@ public class SingleUserCaseConverter {
if (value > biggestPK) {
biggestPK = value;
}
- outputStatement.executeUpdate("INSERT INTO content_tags (tag_id, obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset, user_name) VALUES (" //NON-NLS
+ outputStatement.executeUpdate("INSERT INTO content_tags (tag_id, obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset, examiner_id) VALUES (" //NON-NLS
+ value + ","
+ inputResultSet.getLong(2) + ","
+ inputResultSet.getLong(3) + ",'"
+ inputResultSet.getString(4) + "',"
+ inputResultSet.getLong(5) + ","
- + inputResultSet.getLong(6) + ",'"
- + inputResultSet.getString(7)+ "')"); //NON-NLS
+ + inputResultSet.getLong(6) + ","
+ + inputResultSet.getInt(7) + ")"); //NON-NLS
} catch (SQLException ex) {
if (ex.getErrorCode() != 0) { // 0 if the entry already exists
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java b/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java
index 0698992fa7..e9e9c4270a 100755
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/AddEditCentralRepoCommentAction.java
@@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.centralrepository;
import java.awt.event.ActionEvent;
import java.util.logging.Level;
import javax.swing.AbstractAction;
+import javax.swing.Action;
+import org.apache.commons.lang.StringUtils;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle.Messages;
@@ -37,9 +39,9 @@ import org.sleuthkit.datamodel.AbstractFile;
* An AbstractAction to manage adding and modifying a Central Repository file
* instance comment.
*/
-
-
-@Messages({"AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoComment=Add/Edit Central Repository Comment"})
+@Messages({"AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentEmptyFile=Add/Edit Central Repository Comment (Empty File)",
+ "AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoCommentNoMD5=Add/Edit Central Repository Comment (No MD5 Hash)",
+ "AddEditCentralRepoCommentAction.menuItemText.addEditCentralRepoComment=Add/Edit Central Repository Comment"})
public final class AddEditCentralRepoCommentAction extends AbstractAction {
private static final Logger logger = Logger.getLogger(AddEditCentralRepoCommentAction.class.getName());
@@ -58,14 +60,19 @@ public final class AddEditCentralRepoCommentAction extends AbstractAction {
*
*/
public AddEditCentralRepoCommentAction(AbstractFile file) {
- super(Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoComment());
fileId = file.getId();
correlationAttributeInstance = EamArtifactUtil.getInstanceFromContent(file);
if (correlationAttributeInstance == null) {
addToDatabase = true;
correlationAttributeInstance = EamArtifactUtil.makeInstanceFromContent(file);
}
-
+ if (file.getSize() == 0) {
+ putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoCommentEmptyFile());
+ } else if (StringUtils.isBlank(file.getMd5Hash())) {
+ putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoCommentNoMD5());
+ } else {
+ putValue(Action.NAME, Bundle.AddEditCentralRepoCommentAction_menuItemText_addEditCentralRepoComment());
+ }
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
old mode 100644
new mode 100755
index a84dffadd7..576dc4f94e
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
@@ -22,16 +22,24 @@ import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.io.File;
-import java.io.FileNotFoundException;
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;
import java.util.logging.Level;
-import java.util.stream.Collectors;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
@@ -43,11 +51,9 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
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.autopsy.tabulardatareader.AbstractReader;
-import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException;
-import org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderInitException;
-import org.sleuthkit.autopsy.tabulardatareader.FileReaderFactory;
+import org.sleuthkit.autopsy.coreutils.SqliteUtil;
/**
* A file content viewer for SQLite database files.
@@ -62,7 +68,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
private final SQLiteTableView selectedTableView = new SQLiteTableView();
private AbstractFile sqliteDbFile;
private File tmpDbFile;
- private AbstractReader sqliteReader;
+ private Connection connection;
private int numRows; // num of rows in the selected table
private int currPage = 0; // curr page of rows being displayed
@@ -339,9 +345,13 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
numEntriesField.setText("");
// close DB connection to file
- if (null != sqliteReader) {
- sqliteReader.close();
- sqliteReader = null;
+ 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
+ }
}
sqliteDbFile = null;
@@ -358,40 +368,66 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
"SQLiteViewer.errorMessage.failedToQueryDatabase=The database tables in the file could not be read.",
"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() {
+ private void processSQLiteFile() {
+
tablesDropdownList.removeAllItems();
+
try {
- sqliteReader = FileReaderFactory.createReader(sqliteDbFile, SUPPORTED_MIMETYPES[0]);
-
- Map dbTablesMap = sqliteReader.getTableSchemas();
-
+ 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
+
+ Collection dbTablesMap = getTables();
if (dbTablesMap.isEmpty()) {
tablesDropdownList.addItem(Bundle.SQLiteViewer_comboBox_noTableEntry());
tablesDropdownList.setEnabled(false);
} else {
- dbTablesMap.keySet().forEach((tableName) -> {
+ dbTablesMap.forEach((tableName) -> {
tablesDropdownList.addItem(tableName);
});
}
- } catch (FileReaderException ex) {
- logger.log(Level.SEVERE, String.format(
- "Failed to get tables from DB file '%s' (objId=%d)", //NON-NLS
- sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
- MessageNotifyUtil.Message.error(
- Bundle.SQLiteViewer_errorMessage_failedToQueryDatabase());
- } catch (FileReaderInitException ex) {
- logger.log(Level.SEVERE, String.format(
- "Failed to create a SQLiteReader for file: '%s' (objId=%d)", //NON-NLS
- sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
+ } 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
+ 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 {
- numRows = sqliteReader.getRowCountFromTable(tableName);
+
+ try (Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery(
+ "SELECT count (*) as count FROM " + "\"" + tableName + "\"")) { //NON-NLS{
+
+ numRows = resultSet.getInt("count");
numEntriesField.setText(numRows + " entries");
currPage = 1;
@@ -410,12 +446,9 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
selectedTableView.setupTable(Collections.emptyList());
}
- } catch (FileReaderException ex) {
- logger.log(Level.SEVERE, String.format(
- "Failed to load table %s from DB file '%s' (objId=%d)", tableName, //NON-NLS
- sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
- MessageNotifyUtil.Message.error(
- Bundle.SQLiteViewer_selectTable_errorText(tableName));
+ } 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
+ MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_selectTable_errorText(tableName));
}
}
@@ -423,108 +456,109 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
"SQLiteViewer.readTable.errorText=Error getting rows for table: {0}"})
private void readTable(String tableName, int startRow, int numRowsToRead) {
- try {
- List