Merge remote-tracking branch 'upstream/develop' into 4154_UserPreferencesPanel

This commit is contained in:
U-BASIS\dgrove 2018-09-13 02:28:57 -04:00
commit 3d08d3444a
2 changed files with 112 additions and 105 deletions

View File

@ -41,6 +41,7 @@ public class AutopsyOptionProcessor extends OptionProcessor {
private static final Logger logger = Logger.getLogger(AutopsyOptionProcessor.class.getName()); private static final Logger logger = Logger.getLogger(AutopsyOptionProcessor.class.getName());
private final Option liveAutopsyOption = Option.optionalArgument('l', "liveAutopsy"); private final Option liveAutopsyOption = Option.optionalArgument('l', "liveAutopsy");
// @@@ We should centralize where we store this. It is defined in 2 other places.
private final static String PROP_BASECASE = "LBL_BaseCase_PATH"; private final static String PROP_BASECASE = "LBL_BaseCase_PATH";
@ -56,13 +57,20 @@ public class AutopsyOptionProcessor extends OptionProcessor {
if(values.containsKey(liveAutopsyOption)){ if(values.containsKey(liveAutopsyOption)){
try { try {
RuntimeProperties.setRunningInTarget(true); RuntimeProperties.setRunningInTarget(true);
String[] dir= values.get(liveAutopsyOption);
String directory = dir == null ? PlatformUtil.getUserDirectory().toString() : dir[0]; // get the starting folder to store cases in
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, directory); String[] argDirs= values.get(liveAutopsyOption);
String startingCaseDir;
if (argDirs == null || argDirs.length == 0) {
startingCaseDir = PlatformUtil.getUserDirectory().toString();
}
else {
startingCaseDir = argDirs[0];
}
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, startingCaseDir);
} catch (RuntimeProperties.RuntimePropertiesException ex) { } catch (RuntimeProperties.RuntimePropertiesException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex); logger.log(Level.SEVERE, ex.getMessage(), ex);
} }
} }
} }
} }

View File

@ -40,13 +40,15 @@ import org.sleuthkit.datamodel.AbstractFile;
import com.monitorjbl.xlsx.StreamingReader; import com.monitorjbl.xlsx.StreamingReader;
import org.apache.poi.hssf.OldExcelFormatException; import org.apache.poi.hssf.OldExcelFormatException;
/** /**
* Reads excel files and implements the abstract reader api for interfacing with the * Reads excel files and implements the abstract reader api for interfacing with
* content. Supports .xls and .xlsx files. * the content. Supports .xls and .xlsx files.
*/ */
public final class ExcelReader extends AbstractReader { public final class ExcelReader extends AbstractReader {
/* Boilerplate code */
/*
* Boilerplate code
*/
private final static IngestServices services = IngestServices.getInstance(); private final static IngestServices services = IngestServices.getInstance();
private final static Logger logger = services.getLogger(ExcelReader.class.getName()); private final static Logger logger = services.getLogger(ExcelReader.class.getName());
@ -68,17 +70,20 @@ public final class ExcelReader extends AbstractReader {
} }
/** /**
* Internal factory for creating the correct workbook given the mime type. The * Internal factory for creating the correct workbook given the mime type.
* file reader factory in this module passes both the XLSMimeType and XLSXMimeType * The file reader factory in this module passes both the XLSMimeType and
* into this constructor for the reader to handle. This avoided the need for creating * XLSXMimeType into this constructor for the reader to handle. This avoided
* an AbstractExcelReader class and two sub classes overriding the workbook field. * the need for creating an AbstractExcelReader class and two sub classes
* Additionally, I don't forsee needing to support more than these two mime types. * overriding the workbook field. Additionally, I don't forsee needing to
* support more than these two mime types.
* *
* @param localDiskPath To open an input stream for poi to read from * @param localDiskPath To open an input stream for poi to read from
* @param mimeType The mimeType passed to the constructor * @param mimeType The mimeType passed to the constructor
*
* @return The corrent workbook instance * @return The corrent workbook instance
* @throws IOException Issue with input stream and opening file location at *
* localDiskPath * @throws IOException Issue with input stream and opening file
* location at localDiskPath
* @throws FileReaderInitException mimetype unsupported * @throws FileReaderInitException mimetype unsupported
*/ */
private Workbook createWorkbook(String localDiskPath, String mimeType) throws private Workbook createWorkbook(String localDiskPath, String mimeType) throws
@ -100,8 +105,8 @@ public final class ExcelReader extends AbstractReader {
//and this can use the same functions below. //and this can use the same functions below.
return StreamingReader.builder().rowCacheSize(500).open(new File(localDiskPath)); return StreamingReader.builder().rowCacheSize(500).open(new File(localDiskPath));
default: default:
throw new FileReaderInitException(String.format("Excel reader for mime " + throw new FileReaderInitException(String.format("Excel reader for mime "
"type [%s] is not supported", mimeType)); + "type [%s] is not supported", mimeType));
} }
} }
@ -109,8 +114,11 @@ public final class ExcelReader extends AbstractReader {
* Returns the number of rows in a given excel table (aka sheet). * Returns the number of rows in a given excel table (aka sheet).
* *
* @param tableName Name of table to count total rows from * @param tableName Name of table to count total rows from
*
* @return row count for requested table name * @return row count for requested table name
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException *
* @throws
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
*/ */
@Override @Override
public Integer getRowCountFromTable(String tableName) throws FileReaderException { public Integer getRowCountFromTable(String tableName) throws FileReaderException {
@ -118,38 +126,18 @@ public final class ExcelReader extends AbstractReader {
} }
/** /**
* Returns a collection of all the rows from a given table in an excel document. * Returns a collection of all the rows from a given table in an excel
* document.
* *
* @param tableName Current sheet name being read * @param tableName Current sheet name being read
*
* @return A collection of row maps * @return A collection of row maps
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException *
* @throws
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
*/ */
@Override @Override
public List<Map<String, Object>> getRowsFromTable(String tableName) throws FileReaderException { public List<Map<String, Object>> getRowsFromTable(String tableName) throws FileReaderException {
//Pad with + 1 because rows are zero index, thus a LastRowNum() (in getRowCountFromTable()) of 1
//indicates that there are records in 0 and 1 and so a total row count of
//2. This also implies there is no way to determine if a workbook is empty,
//since a last row num of 0 doesnt differentiate between a record in 0 or
//nothing in the workbook. Such a HSSF.
return getRowsFromTable(tableName, 0, getRowCountFromTable(tableName));
}
/**
* Returns a window of rows starting at the offset and ending when the number of rows read
* equals the 'numRowsToRead' parameter or the iterator has nothing left to read.
*
* For instance: offset 1, numRowsToRead 5 would return 5 results (1-5).
* offset 0, numRowsToRead 5 would return 5 results (0-4).
*
* @param tableName Current name of sheet to be read
* @param offset start index to begin reading (documents are 0 indexed)
* @param numRowsToRead number of rows to read
* @return
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
*/
@Override
public List<Map<String, Object>> getRowsFromTable(String tableName,
int offset, int numRowsToRead) throws FileReaderException {
//StreamingReader maintains the same pointer to a sheet rowIterator, so this //StreamingReader maintains the same pointer to a sheet rowIterator, so this
//call returns an iterator that could have already been iterated on instead //call returns an iterator that could have already been iterated on instead
//of a fresh copy. We must cache the header value from the call to //of a fresh copy. We must cache the header value from the call to
@ -157,41 +145,48 @@ public final class ExcelReader extends AbstractReader {
//missed. //missed.
Iterator<Row> sheetIter = workbook.getSheet(tableName).rowIterator(); Iterator<Row> sheetIter = workbook.getSheet(tableName).rowIterator();
List<Map<String, Object>> rowList = new ArrayList<>(); List<Map<String, Object>> rowList = new ArrayList<>();
//Read the header value as the header may be a row of data in the
//excel sheet
if (headerCache.containsKey(tableName)) { if (headerCache.containsKey(tableName)) {
Row header = headerCache.get(tableName); Row header = headerCache.get(tableName);
if(header.getRowNum() >= offset
&& header.getRowNum() < (offset + numRowsToRead)) {
rowList.add(getRowMap(tableName, header)); rowList.add(getRowMap(tableName, header));
} }
}
while (sheetIter.hasNext()) { while (sheetIter.hasNext()) {
Row currRow = sheetIter.next(); Row currRow = sheetIter.next();
//If the current row number is within the window of our row capture
if(currRow.getRowNum() >= offset
&& currRow.getRowNum() < (offset + numRowsToRead)) {
rowList.add(getRowMap(tableName, currRow)); rowList.add(getRowMap(tableName, currRow));
} }
//if current row number is equal to our upper bound
//of rows requested to be read.
if(currRow.getRowNum() >= (offset + numRowsToRead)) {
break;
}
}
return rowList; return rowList;
} }
/**
* Currently not supported. Returns a window of rows starting at the offset
* and ending when the number of rows read equals the 'numRowsToRead'
* parameter or the iterator has nothing left to read.
*
* For instance: offset 1, numRowsToRead 5 would return 5 results (1-5).
* offset 0, numRowsToRead 5 would return 5 results (0-4).
*
* @param tableName Current name of sheet to be read
* @param offset start index to begin reading (documents are 0
* indexed)
* @param numRowsToRead number of rows to read
*
* @return
*
* @throws
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
*/
@Override
public List<Map<String, Object>> getRowsFromTable(String tableName,
int offset, int numRowsToRead) throws FileReaderException {
throw new FileReaderException("Operation Not Supported.");
}
private Map<String, Object> getRowMap(String tableName, Row row) { private Map<String, Object> getRowMap(String tableName, Row row) {
Map<String, Object> rowMap = new HashMap<>(); Map<String, Object> rowMap = new HashMap<>();
for (Cell cell : row) { for (Cell cell : row) {
String columnName = getColumnName(cell, tableName);
Object value = getCellValue(cell); Object value = getCellValue(cell);
rowMap.put(columnName, value); rowMap.put(String.valueOf(cell.getColumnIndex()), value);
} }
return rowMap; return rowMap;
} }
@ -201,6 +196,7 @@ public final class ExcelReader extends AbstractReader {
* called on a cell depending on its type, hence the switch. * called on a cell depending on its type, hence the switch.
* *
* @param cell Cell object containing a getter function for its value type * @param cell Cell object containing a getter function for its value type
*
* @return A generic object pointer to the cell's value * @return A generic object pointer to the cell's value
*/ */
private Object getCellValue(Cell cell) { private Object getCellValue(Cell cell) {
@ -208,7 +204,7 @@ public final class ExcelReader extends AbstractReader {
case BOOLEAN: case BOOLEAN:
return cell.getBooleanCellValue(); return cell.getBooleanCellValue();
case STRING: case STRING:
return cell.getRichStringCellValue().getString(); return cell.getStringCellValue();
case NUMERIC: case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) { if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue(); return cell.getDateCellValue();
@ -224,11 +220,12 @@ public final class ExcelReader extends AbstractReader {
} }
/** /**
* Returns the name of the column that the cell currently lives in * Returns the name of the column that the cell currently lives in Cell
* Cell Value: 6784022342 -> Header name: Phone Number * Value: 6784022342 -> Header name: Phone Number
* *
* @param cell current cell being read * @param cell current cell being read
* @param tableName current sheet name being read * @param tableName current sheet name being read
*
* @return the name of the column the current cell lives in * @return the name of the column the current cell lives in
*/ */
private String getColumnName(Cell cell, String tableName) { private String getColumnName(Cell cell, String tableName) {
@ -246,11 +243,13 @@ public final class ExcelReader extends AbstractReader {
} }
/** /**
* Returns a map of sheet names to headers (header is in a comma-seperated string). * Returns a map of sheet names to headers (header is in a comma-seperated
* Warning: Only call this ONCE per excel file. * string). Warning: Only call this ONCE per excel file.
* *
* @return A map of sheet names to header strings. * @return A map of sheet names to header strings.
* @throws org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException *
* @throws
* org.sleuthkit.autopsy.tabulardatareader.AbstractReader.FileReaderException
*/ */
@Override @Override
public Map<String, String> getTableSchemas() throws FileReaderException { public Map<String, String> getTableSchemas() throws FileReaderException {