diff --git a/Core/build.xml b/Core/build.xml index af90bfdbba..14a6a5a28c 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -97,12 +97,12 @@ - + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index 1a419b8bd1..1d4e215f8b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -759,6 +759,7 @@ abstract class AbstractSqlEamDb implements EamDb { return artifactInstances; } + /** * Retrieves eamArtifact instances from the database that are associated * with the aType and filePath @@ -1918,16 +1919,17 @@ abstract class AbstractSqlEamDb implements EamDb { EamDbUtil.closeConnection(conn); } } - - /** - * Process the Artifact instance in the EamDb + + /** + * Process the Artifact instance in the EamDb give a where clause * * @param type EamArtifact.Type to search for * @param instanceTableCallback callback to process the instance + * @param whereClause query string to execute * @throws EamDbException */ @Override - public void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException { + public void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException { if (type == null) { throw new EamDbException("Correlation type is null"); } @@ -1935,6 +1937,10 @@ abstract class AbstractSqlEamDb implements EamDb { if (instanceTableCallback == null) { throw new EamDbException("Callback interface is null"); } + + if(whereClause == null) { + throw new EamDbException("Where clause is null"); + } Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -1943,115 +1949,11 @@ abstract class AbstractSqlEamDb implements EamDb { StringBuilder sql = new StringBuilder(3); sql.append("select * from "); sql.append(tableName); - sql.append(" WHERE id = ?"); + sql.append(" WHERE "); + sql.append(whereClause); try { preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setInt(1, id); - resultSet = preparedStatement.executeQuery(); - instanceTableCallback.process(resultSet); - } catch (SQLException ex) { - throw new EamDbException("Error getting all artifact instances from instances table", ex); - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - } - - /** - * Process the Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException { - if (type == null) { - throw new EamDbException("Correlation type is null"); - } - - if (instanceTableCallback == null) { - throw new EamDbException("Callback interface is null"); - } - - if(correlationCase == null) { - throw new EamDbException("Correlation Case is null"); - } - - Connection conn = connect(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(7); - sql.append("SELECT id, value, case_id FROM "); - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"); - - try { - preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); - resultSet = preparedStatement.executeQuery(); - instanceTableCallback.process(resultSet); - } catch (SQLException ex) { - throw new EamDbException("Error getting all artifact instances from instances table", ex); - } finally { - EamDbUtil.closeStatement(preparedStatement); - EamDbUtil.closeResultSet(resultSet); - EamDbUtil.closeConnection(conn); - } - } - - /** - * Process the Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param singleCase Single Case to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException { - if (type == null) { - throw new EamDbException("Correlation type is null"); - } - - if (instanceTableCallback == null) { - throw new EamDbException("Callback interface is null"); - } - - if(correlationCase == null) { - throw new EamDbException("Correlation Case is null"); - } - - Connection conn = connect(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String tableName = EamDbUtil.correlationTypeToInstanceTableName(type); - StringBuilder sql = new StringBuilder(8); - sql.append("SELECT id, value, case_id FROM "); - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); // TODO should this select * so any field is available? - sql.append(tableName); - sql.append(" WHERE value IN (SELECT value FROM "); - sql.append(tableName); - sql.append(" WHERE case_id=? AND (known_status !=? OR known_status IS NULL) GROUP BY value)"); - sql.append(" AND (case_id=? OR case_id=?) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"); - - try { - preparedStatement = conn.prepareStatement(sql.toString()); - preparedStatement.setInt(1, correlationCase.getID()); - preparedStatement.setByte(2, TskData.FileKnown.KNOWN.getFileKnownValue()); - preparedStatement.setInt(3, correlationCase.getID()); - preparedStatement.setInt(4, singleCase.getID()); resultSet = preparedStatement.executeQuery(); instanceTableCallback.process(resultSet); } catch (SQLException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index f9f37a86f0..e4fb30583e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -706,34 +706,14 @@ public interface EamDb { */ void processInstanceTable(CorrelationAttribute.Type type, InstanceTableCallback instanceTableCallback) throws EamDbException; - /** - * Process a single Artifact instance in the EamDb - * - * @param type EamArtifact.Type to search for - * @param id the id of the row to return - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException; - - /** - * Process the Artifact md5s in the EamDb for matches of case files which are not known - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException; - /** * Process the Artifact instance in the EamDb * * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param singleCase Single Case to filter by * @param instanceTableCallback callback to process the instance + * @param whereClause query string to execute * @throws EamDbException */ - void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException; - + void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException; + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index a9f930fd0c..74d0c36a66 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -735,62 +735,23 @@ final class SqliteEamDb extends AbstractSqlEamDb { releaseSharedLock(); } } - - /** - * Process a single Artifact instance row in the EamDb - * - * @param type EamArtifact.Type to search for - * @param id the id of the row to return - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processInstanceTableRow(CorrelationAttribute.Type type, int id, InstanceTableCallback instanceTableCallback) throws EamDbException { - try { - acquireSharedLock(); - super.processInstanceTableRow(type, id, instanceTableCallback); - } finally { - releaseSharedLock(); - } - } - - /** - * Process the Artifact md5s in the EamDb for matches of case files which - * are not known - * - * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param instanceTableCallback callback to process the instance - * @throws EamDbException - */ - @Override - public void processCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, InstanceTableCallback instanceTableCallback) throws EamDbException { - try { - acquireSharedLock(); - super.processCaseInstancesTable(type, correlationCase, instanceTableCallback); - } finally { - releaseSharedLock(); - } - } /** * Process the Artifact instance in the EamDb * * @param type EamArtifact.Type to search for - * @param correlationCase CorrelationCase to filter by - * @param singleCase Single Case to filter by * @param instanceTableCallback callback to process the instance * @throws EamDbException */ @Override - public void processSingleCaseInstancesTable(CorrelationAttribute.Type type, CorrelationCase correlationCase, CorrelationCase singleCase,InstanceTableCallback instanceTableCallback) throws EamDbException { - try { + public void processInstanceTableWhere(CorrelationAttribute.Type type, String whereClause, InstanceTableCallback instanceTableCallback) throws EamDbException { + try { acquireSharedLock(); - super.processSingleCaseInstancesTable(type, correlationCase, singleCase, instanceTableCallback); + super.processInstanceTableWhere(type, whereClause, instanceTableCallback); } finally { releaseSharedLock(); } - } + } /** * Check whether a reference set with the given name/version is in the diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 61e8aee1f4..7732c5d393 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -78,7 +78,8 @@ public abstract class AbstractCommonAttributeInstance { * CaseDB. * * @return AbstractFile corresponding to this common attribute or null if it - * cannot be found (for example, in the event that this is a central repo file) + * cannot be found (for example, in the event that this is a central repo + * file) */ abstract AbstractFile getAbstractFile(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 7e039a9419..ca436b7809 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -47,10 +47,8 @@ public class AllInterCaseCommonAttributeSearcher extends InterCaseCommonAttribut @Override public CommonAttributeSearchResults findFiles() throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase()); - Map> interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); - + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap()); + Map> interCaseCommonFiles = eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase()); return new CommonAttributeSearchResults(interCaseCommonFiles); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index 9babcbb831..0e70722b6d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -45,7 +45,7 @@ final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttr private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; private CorrelationAttribute currentAttribute; - private Map dataSourceNameToIdMap; + private final Map dataSourceNameToIdMap; CentralRepoCommonAttributeInstance(Integer attrInstId, Map dataSourceIdToNameMap) { super(); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index fcdb4a319c..2c745b5271 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -19,13 +19,10 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.HashMap; -import java.util.List; import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; -import org.sleuthkit.datamodel.HashUtility; /** * Provides logic for selecting common files from all data sources and all cases @@ -51,49 +48,6 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS dbManager = EamDb.getInstance(); } - /** - * @param artifactInstances all 'common files' in central repo - * @param commonValues matches must ultimately have appeared in this - * collection - * @return collated map of instance counts to lists of matches - */ - Map> gatherIntercaseResults(Map commonValues, Map commonFileCases) { - - // keyis string of value - Map interCaseCommonFiles = new HashMap<>(); - - for (int commonAttrId : commonValues.keySet()) { - - String md5 = commonValues.get(commonAttrId); - if (md5 == null || HashUtility.isNoDataMd5(md5)) { - continue; - } - - // we don't *have* all the information for the rows in the CR, - // so we need to consult the present case via the SleuthkitCase object - // Later, when the FileInstanceNodde is built. Therefore, build node generators for now. - - if (interCaseCommonFiles.containsKey(md5)) { - //Add to intercase metaData - final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, this.getDataSourceIdToNameMap()); - commonAttributeValue.addInstance(searchResult); - - } else { - CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); - interCaseCommonFiles.put(md5, commonAttributeValue); - - AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, this.getDataSourceIdToNameMap()); - commonAttributeValue.addInstance(searchResult); - } - } - - Map> instanceCollatedCommonFiles = collateMatchesByNumberOfInstances(interCaseCommonFiles); - - return instanceCollatedCommonFiles; - } - protected CorrelationCase getCorrelationCaseFromId(int correlationCaseId) throws EamDbException { for (CorrelationCase cCase : this.dbManager.getCases()) { if (cCase.getID() == correlationCaseId) { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index 8416bbd856..c8d065bff6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -20,11 +20,12 @@ package org.sleuthkit.autopsy.commonfilesearch; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.logging.Level; -import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; @@ -33,6 +34,8 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.HashUtility; /** * Used to process and return CorrelationCase md5s from the EamDB for @@ -40,13 +43,26 @@ import org.sleuthkit.autopsy.coreutils.Logger; */ final class InterCaseSearchResultsProcessor { + private Map dataSources; + private static final Logger LOGGER = Logger.getLogger(CommonAttributePanel.class.getName()); - // maps row ID to value - private final Map intercaseCommonValuesMap = new HashMap<>(); - // maps row ID to case ID - private final Map intercaseCommonCasesMap = new HashMap<>(); - + private final String interCaseWhereClause = "value IN (SELECT value FROM file_instances" + + " WHERE value IN (SELECT value FROM file_instances" + + " WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value)" + + " GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"; + + private final String singleInterCaseWhereClause = "value IN (SELECT value FROM file_instances " + + "WHERE value IN (SELECT value FROM file_instances " + + "WHERE case_id=%s AND (known_status !=%s OR known_status IS NULL) GROUP BY value) " + + "AND (case_id=%s OR case_id=%s) GROUP BY value HAVING COUNT(DISTINCT case_id) > 1) ORDER BY value"; + + InterCaseSearchResultsProcessor(Map dataSources){ + this.dataSources = dataSources; + } + + InterCaseSearchResultsProcessor(){} + /** * Finds a single CorrelationAttribute given an id. * @@ -58,7 +74,7 @@ final class InterCaseSearchResultsProcessor { InterCaseCommonAttributeRowCallback instancetableCallback = new InterCaseCommonAttributeRowCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - DbManager.processInstanceTableRow(fileType, attrbuteId, instancetableCallback); + DbManager.processInstanceTableWhere(fileType, String.format("id = %s", attrbuteId), instancetableCallback); return instancetableCallback.getCorrelationAttribute(); @@ -75,17 +91,23 @@ final class InterCaseSearchResultsProcessor { * * @param currentCase The current TSK Case. */ - void findInterCaseCommonAttributeValues(Case currentCase) { + Map> findInterCaseCommonAttributeValues(Case currentCase) { try { InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - DbManager.processCaseInstancesTable(fileType, DbManager.getCase(currentCase), instancetableCallback); - + int caseId = DbManager.getCase(currentCase).getID(); + + DbManager.processInstanceTableWhere(fileType, String.format(interCaseWhereClause, caseId, + TskData.FileKnown.KNOWN.getFileKnownValue()), + instancetableCallback); + + return instancetableCallback.getInstanceCollatedCommonFiles(); + } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - + return new HashMap<>(); } /** @@ -96,23 +118,20 @@ final class InterCaseSearchResultsProcessor { * @param currentCase The current TSK Case. * @param singleCase The case of interest. Matches must exist in this case. */ - void findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) { + Map> findSingleInterCaseCommonAttributeValues(Case currentCase, CorrelationCase singleCase) { try { InterCaseCommonAttributesCallback instancetableCallback = new InterCaseCommonAttributesCallback(); EamDb DbManager = EamDb.getInstance(); CorrelationAttribute.Type fileType = DbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); - DbManager.processSingleCaseInstancesTable(fileType, DbManager.getCase(currentCase), singleCase, instancetableCallback); + int caseId = DbManager.getCase(currentCase).getID(); + int targetCaseId = singleCase.getID(); + DbManager.processInstanceTableWhere(fileType, String.format(singleInterCaseWhereClause, caseId, + TskData.FileKnown.KNOWN.getFileKnownValue(), caseId, targetCaseId), instancetableCallback); + return instancetableCallback.getInstanceCollatedCommonFiles(); } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - } - - Map getIntercaseCommonValuesMap() { - return Collections.unmodifiableMap(intercaseCommonValuesMap); - } - - Map getIntercaseCommonCasesMap() { - return Collections.unmodifiableMap(intercaseCommonCasesMap); + return new HashMap<>(); } /** @@ -121,19 +140,60 @@ final class InterCaseSearchResultsProcessor { */ private class InterCaseCommonAttributesCallback implements InstanceTableCallback { + final Map> instanceCollatedCommonFiles = new HashMap<>(); + + private CommonAttributeValue commonAttributeValue = null; + private String previousRowMd5 = ""; + @Override public void process(ResultSet resultSet) { try { while (resultSet.next()) { + int resultId = InstanceTableCallback.getId(resultSet); - intercaseCommonValuesMap.put(resultId, InstanceTableCallback.getValue(resultSet)); - intercaseCommonCasesMap.put(resultId, InstanceTableCallback.getCaseId(resultSet)); + String md5Value = InstanceTableCallback.getValue(resultSet); + if (previousRowMd5.isEmpty()) { + previousRowMd5 = md5Value; + } + if (md5Value == null || HashUtility.isNoDataMd5(md5Value)) { + continue; + } + + countAndAddCommonAttributes(md5Value, resultId); + } } catch (SQLException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } } + private void countAndAddCommonAttributes(String md5Value, int resultId) { + if (commonAttributeValue == null) { + commonAttributeValue = new CommonAttributeValue(md5Value); + } + if (!md5Value.equals(previousRowMd5)) { + int size = commonAttributeValue.getInstanceCount(); + if (instanceCollatedCommonFiles.containsKey(size)) { + instanceCollatedCommonFiles.get(size).add(commonAttributeValue); + } else { + ArrayList value = new ArrayList<>(); + value.add(commonAttributeValue); + instanceCollatedCommonFiles.put(size, value); + } + + commonAttributeValue = new CommonAttributeValue(md5Value); + previousRowMd5 = md5Value; + } + // we don't *have* all the information for the rows in the CR, + // so we need to consult the present case via the SleuthkitCase object + // Later, when the FileInstanceNode is built. Therefore, build node generators for now. + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(resultId, InterCaseSearchResultsProcessor.this.dataSources); + commonAttributeValue.addInstance(searchResult); + } + + Map> getInstanceCollatedCommonFiles() { + return Collections.unmodifiableMap(instanceCollatedCommonFiles); + } } /** @@ -161,7 +221,7 @@ final class InterCaseSearchResultsProcessor { } } catch (SQLException | EamDbException ex) { - Exceptions.printStackTrace(ex); + LOGGER.log(Level.WARNING, "Error getting single correlation artifact instance from database.", ex); // NON-NLS } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java index 89036d1824..e0938df3f8 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCasePanel.java @@ -28,8 +28,10 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; /** - * - * @author bsweeney + * UI controls for Common Files Search scenario where the user intends to find + * common files between datasources. It is an inner panel which provides the ability + * to select all datasources or a single datasource from a dropdown list of + * sources in the current case. */ public class IntraCasePanel extends javax.swing.JPanel { @@ -41,7 +43,7 @@ public class IntraCasePanel extends javax.swing.JPanel { private boolean singleDataSource; private String selectedDataSource; private ComboBoxModel dataSourcesList = new DataSourceComboBoxModel(); - private Map dataSourceMap; + private final Map dataSourceMap; private String errorMessage; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 66a7106c63..6c06da8b38 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java @@ -70,11 +70,9 @@ public class SingleInterCaseCommonAttributeSearcher extends InterCaseCommonAttri return this.findFiles(cCase); } - protected CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { - - InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); - eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); - Map> interCaseCommonFiles = gatherIntercaseResults(eamDbAttrInst.getIntercaseCommonValuesMap(), eamDbAttrInst.getIntercaseCommonCasesMap()); + CommonAttributeSearchResults findFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException { + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(this.getDataSourceIdToNameMap()); + Map> interCaseCommonFiles = eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); return new CommonAttributeSearchResults(interCaseCommonFiles); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index 8dfe705d6a..cb74f6679e 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -1157,6 +1157,34 @@ public class CentralRepoDatamodelTest extends TestCase { } catch (EamDbException ex) { // This is the expected } + + // Test running processinstance which queries all rows from instances table + try { + // Add two instances to the central repository and use the callback query to verify we can see them + CorrelationAttribute attr = new CorrelationAttribute(fileType, callbackTestFileHash); + CorrelationAttributeInstance inst1 = new CorrelationAttributeInstance(case1, dataSource1fromCase1, callbackTestFilePath1); + CorrelationAttributeInstance inst2 = new CorrelationAttributeInstance(case1, dataSource1fromCase1, callbackTestFilePath2); + attr.addInstance(inst1); + attr.addInstance(inst2); + EamDb DbManager = EamDb.getInstance(); + DbManager.addArtifact(attr); + AttributeInstanceTableCallback instancetableCallback = new AttributeInstanceTableCallback(); + DbManager.processInstanceTableWhere(fileType, String.format("id = %s", attr.getID()), instancetableCallback); + int count1 = instancetableCallback.getCounter(); + int count2 = instancetableCallback.getCounterNamingConvention(); + assertTrue("Process Instance count with filepath naming convention: " + count2 + "-expected 2", count2 == 2); + assertTrue("Process Instance count with filepath without naming convention: " + count1 + "-expected greater than 0", count1 > 0); + } catch (EamDbException ex) { + Exceptions.printStackTrace(ex); + } + + try { + //test null inputs + EamDb.getInstance().processInstanceTableWhere(null, null, null); + Assert.fail("processinstance method failed to throw exception for null type value"); + } catch (EamDbException ex) { + // This is the expected + } } /**