diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 61e8aee1f4..8fa50d7ac2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.commonfilesearch; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; +import java.util.HashMap; +import java.util.Map; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.datamodel.AbstractFile; @@ -69,6 +71,7 @@ public abstract class AbstractCommonAttributeInstance { */ AbstractCommonAttributeInstance() { this.abstractFileObjectId = -1L; + this.cachedFiles = new HashMap<>(); this.caseName = ""; this.dataSource = ""; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java index 7e039a9419..680d31f7dc 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AllInterCaseCommonAttributeSearcher.java @@ -48,9 +48,7 @@ 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()); - + Map> interCaseCommonFiles = eamDbAttrInst.findInterCaseCommonAttributeValues(Case.getCurrentCase()); return new CommonAttributeSearchResults(interCaseCommonFiles); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 32b97bd3c5..1160635b2f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -51,49 +51,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 498cfb36a7..0b4c2c6d4d 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; @@ -34,6 +35,7 @@ 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 @@ -85,13 +87,13 @@ 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); int caseId = DbManager.getCase(currentCase).getID(); - + return instancetableCallback.getInstanceCollatedCommonFiles(); DbManager.processInstanceTableWhere(fileType, String.format(interCaseWhereClause, caseId, TskData.FileKnown.KNOWN.getFileKnownValue()), instancetableCallback); @@ -99,7 +101,7 @@ final class InterCaseSearchResultsProcessor { } catch (EamDbException ex) { LOGGER.log(Level.SEVERE, "Error accessing EamDb processing CaseInstancesTable.", ex); } - + return new HashMap<>(); } /** @@ -110,7 +112,7 @@ 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(); @@ -119,17 +121,11 @@ final class InterCaseSearchResultsProcessor { 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<>(); } /** @@ -138,17 +134,66 @@ 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 { + + EamDb dbManager = EamDb.getInstance(); + 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; + } + int caseId = InstanceTableCallback.getCaseId(resultSet); + CorrelationCase autopsyCrCase = dbManager.getCaseById(caseId); + final String correlationCaseDisplayName = autopsyCrCase.getDisplayName(); + + countAndAddCommonAttributes(md5Value, resultId, correlationCaseDisplayName); + } - } catch (SQLException ex) { - Exceptions.printStackTrace(ex); + } catch (SQLException | EamDbException ex) { + LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS } + + } + + private void countAndAddCommonAttributes(String md5Value, int resultId, String correlationCaseDisplayName) { + 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); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + } + + Map> getInstanceCollatedCommonFiles() { + return Collections.unmodifiableMap(instanceCollatedCommonFiles); } } @@ -178,7 +223,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/SingleInterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/SingleInterCaseCommonAttributeSearcher.java index 66a7106c63..18d2faf8b7 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 { - + 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()); + Map> interCaseCommonFiles = eamDbAttrInst.findSingleInterCaseCommonAttributeValues(Case.getCurrentCase(), correlationCase); return new CommonAttributeSearchResults(interCaseCommonFiles); }