diff --git a/Core/ivy.xml b/Core/ivy.xml
index 601077eb91..1ed71d69cf 100644
--- a/Core/ivy.xml
+++ b/Core/ivy.xml
@@ -29,6 +29,8 @@
+
+
diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index 80bb473653..90ce31dab9 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -15,7 +15,7 @@ file.reference.postgresql-9.4.1211.jre7.jar=release/modules/ext/postgresql-9.4.1
file.reference.Rejistry-1.0-SNAPSHOT.jar=release/modules/ext/Rejistry-1.0-SNAPSHOT.jar
file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
-file.reference.sqlite-jdbc-3.8.11.jar=release/modules/ext/sqlite-jdbc-3.8.11.jar
+file.reference.sqlite-jdbc-3.8.11.jar=release\\modules\\ext\\sqlite-jdbc-3.8.11.jar
file.reference.StixLib.jar=release/modules/ext/StixLib.jar
file.reference.bcprov-jdk15on-1.54.jar=release/modules/ext/bcprov-jdk15on-1.54.jar
file.reference.jackcess-2.1.8.jar=release/modules/ext/jackcess-2.1.8.jar
@@ -35,6 +35,7 @@ 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 2e0de7619a..303d14422c 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -337,7 +337,7 @@
org.sleuthkit.autopsy.modules.vmextractor
org.sleuthkit.autopsy.progress
org.sleuthkit.autopsy.report
- org.sleuthkit.autopsy.sqlitereader
+ org.sleuthkit.autopsy.tabulardatareader
org.sleuthkit.datamodel
@@ -388,6 +388,10 @@
ext/sevenzipjbinding.jar
release/modules/ext/sevenzipjbinding.jar
+
+ ext/sleuthkit-postgresql-4.6.2.jar
+ release/modules/ext/sleuthkit-postgresql-4.6.2.jar
+
ext/mchange-commons-java-0.2.9.jar
release/modules/ext/mchange-commons-java-0.2.9.jar
@@ -412,10 +416,6 @@
ext/metadata-extractor-2.10.1.jar
release/modules/ext/metadata-extractor-2.10.1.jar
-
- ext/sleuthkit-postgresql-4.6.2.jar
- release/modules/ext/sleuthkit-postgresql-4.6.2.jar
-
ext/tika-core-1.17.jar
release/modules/ext/tika-core-1.17.jar
@@ -442,7 +442,7 @@
ext/sqlite-jdbc-3.8.11.jar
- release/modules/ext/sqlite-jdbc-3.8.11.jar
+ release\modules\ext\sqlite-jdbc-3.8.11.jar
ext/activemq-all-5.11.1.jar
@@ -488,6 +488,14 @@
ext/jdom-2.0.5-contrib.jar
release/modules/ext/jdom-2.0.5-contrib.jar
+
+ 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
@@ -500,10 +508,6 @@
ext/xmpcore-5.1.3.jar
release/modules/ext/xmpcore-5.1.3.jar
-
- ext/SparseBitSet-1.1.jar
- release/modules/ext/SparseBitSet-1.1.jar
-
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
index 6988e46527..47a33dc578 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/SQLiteViewer.java
@@ -25,7 +25,6 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -44,9 +43,11 @@ 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.sqlitereader.SQLiteReader;
+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;
/**
* A file content viewer for SQLite database files.
@@ -61,7 +62,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
private final SQLiteTableView selectedTableView = new SQLiteTableView();
private AbstractFile sqliteDbFile;
private File tmpDbFile;
- private SQLiteReader sqliteReader;
+ private AbstractReader sqliteReader;
private int numRows; // num of rows in the selected table
private int currPage = 0; // curr page of rows being displayed
@@ -339,12 +340,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
// close DB connection to file
if (null != sqliteReader) {
- try {
- sqliteReader.close();
- sqliteReader = null;
- } catch (SQLException ex) {
- logger.log(Level.SEVERE, "Failed to close DB connection to file.", ex); //NON-NLS
- }
+ sqliteReader.close();
+ sqliteReader = null;
}
sqliteDbFile = null;
@@ -366,7 +363,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
try {
String localDiskPath = Case.getCurrentCaseThrows().getTempDirectory() +
File.separator + sqliteDbFile.getName();
- sqliteReader = new SQLiteReader(sqliteDbFile, localDiskPath);
+
+ sqliteReader = FileReaderFactory.createReader(SUPPORTED_MIMETYPES[0], sqliteDbFile, localDiskPath);
Map dbTablesMap = sqliteReader.getTableSchemas();
@@ -381,24 +379,16 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
} catch (NoCurrentCaseException ex) {
logger.log(Level.SEVERE, "Current case has been closed", ex); //NON-NLS
MessageNotifyUtil.Message.error(Bundle.SQLiteViewer_errorMessage_noCurrentCase());
- } catch (IOException | TskCoreException ex) {
- logger.log(Level.SEVERE, String.format(
- "Failed to create temp copy of DB file '%s' (objId=%d)", //NON-NLS
- sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
- MessageNotifyUtil.Message.error(
- Bundle.SQLiteViewer_errorMessage_failedToExtractFile());
- } catch (ClassNotFoundException ex) {
- logger.log(Level.SEVERE, String.format(
- "Failed to initialize JDBC SQLite '%s' (objId=%d)", //NON-NLS
- sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
- MessageNotifyUtil.Message.error(
- Bundle.SQLiteViewer_errorMessage_failedToinitJDBCDriver());
- } catch (SQLException ex) {
+ } 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 '%s' (objId=%d)", //NON-NLS
+ sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
}
}
@@ -407,7 +397,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
})
private void selectTable(String tableName) {
try {
- numRows = sqliteReader.getTableRowCount(tableName);
+ numRows = sqliteReader.getRowCountFromTable(tableName);
numEntriesField.setText(numRows + " entries");
currPage = 1;
@@ -426,7 +416,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
selectedTableView.setupTable(Collections.emptyList());
}
- } catch (SQLException ex) {
+ } 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);
@@ -447,7 +437,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
} else {
selectedTableView.setupTable(Collections.emptyList());
}
- } catch (SQLException ex) {
+ } catch (FileReaderException ex) {
logger.log(Level.SEVERE, String.format(
"Failed to read table %s from DB file '%s' (objId=%d)", tableName, //NON-NLS
sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
@@ -461,7 +451,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
*
* @param file
* @param tableName
- * @param rowMap -- A list of rows in the table, where each row is represented as a column-value
+ * @param rowMap A list of rows in the table, where each row is represented as a column-value
* map.
* @throws FileNotFoundException
* @throws IOException
@@ -516,7 +506,7 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
} else {
exportTableToCSV(file, tableName, currentTableRows);
}
- } catch (SQLException ex) {
+ } catch (FileReaderException ex) {
logger.log(Level.SEVERE, String.format(
"Failed to read table %s from DB file '%s' (objId=%d)", //NON-NLS
tableName, sqliteDbFile.getName(), sqliteDbFile.getId()), ex);
@@ -534,8 +524,8 @@ class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
* Returns a comma seperated header string from the keys of the column
* row map.
*
- * @param row -- column header row map
- * @return -- comma seperated header string
+ * @param row column header row map
+ * @return comma seperated header string
*/
private String createColumnHeader(Map row) {
return row.entrySet()
diff --git a/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java
new file mode 100755
index 0000000000..cb74819142
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/tabulardatareader/AbstractReader.java
@@ -0,0 +1,143 @@
+/*
+ * 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.tabulardatareader;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import org.sleuthkit.autopsy.datamodel.ContentUtils;
+import org.sleuthkit.datamodel.AbstractFile;
+import org.sleuthkit.datamodel.TskCoreException;
+
+/**
+ * An abstract reader interface for retrieving contents from files via a common
+ * API.
+ */
+public abstract class AbstractReader implements AutoCloseable {
+
+ public AbstractReader(AbstractFile file, String localDiskPath)
+ throws FileReaderInitException {
+
+ writeDataSourceToLocalDisk(file, localDiskPath);
+ }
+
+ /**
+ * Copies the data source file contents to local drive for processing.
+ * This function is common to all readers.
+ *
+ * @param file AbstractFile from the data source
+ * @param localDiskPath Local drive path to copy AbstractFile contents
+ * @throws IOException Exception writing file contents
+ * @throws NoCurrentCaseException Current case closed during file copying
+ * @throws TskCoreException Exception finding files from abstract file
+ */
+ private void writeDataSourceToLocalDisk(AbstractFile file, String localDiskPath)
+ throws FileReaderInitException {
+
+ try {
+ File localDatabaseFile = new File(localDiskPath);
+ if (!localDatabaseFile.exists()) {
+ ContentUtils.writeToFile(file, localDatabaseFile);
+ }
+ } catch (IOException ex) {
+ throw new FileReaderInitException(ex);
+ }
+ }
+
+ /**
+ * Return the a mapping of table names to table schemas (may be in the form of
+ * headers or create table statements for databases).
+ *
+ * @return Mapping of table names to schemas
+ * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
+ */
+ public abstract Map getTableSchemas() throws FileReaderException;
+
+ /**
+ * Returns the row count fo the given table name.
+ *
+ * @param tableName
+ * @return number of rows in the current table
+ * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
+ */
+ public abstract Integer getRowCountFromTable(String tableName) throws FileReaderException;
+
+ /**
+ * Returns a collection view of the rows in a table.
+ *
+ * @param tableName
+ * @return List view of the rows in the table
+ * @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
+ */
+ public abstract List