From 75f889da1428d7d7c227350fd85eadb64f7748ae Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 7 Dec 2018 14:34:58 -0500 Subject: [PATCH] 4440 refactor casesearchresults, fix value column for non files --- .../AbstractCommonAttributeInstance.java | 3 +- .../CaseDBCommonAttributeInstance.java | 7 +- .../CaseDBCommonAttributeInstanceNode.java | 6 +- .../CommonAttributeCaseSearchResults.java | 89 ++++++++----------- .../CommonAttributePanel.java | 9 +- .../IntraCaseCommonAttributeSearcher.java | 4 +- 6 files changed, 51 insertions(+), 67 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 6db539ca4b..f9af06f5fe 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -165,9 +165,8 @@ public abstract class AbstractCommonAttributeInstance { leafNode = new CentralRepoCommonAttributeInstanceNode(attribute, nodeType); } else { final String abstractFileDataSourceName = abstractFile.getDataSource().getName(); - leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName, nodeType); + leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName, attribute.getCorrelationValue(), nodeType); } - return leafNode; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java index 67332cc572..f80bd3ca61 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java @@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException; final public class CaseDBCommonAttributeInstance extends AbstractCommonAttributeInstance { private static final Logger LOGGER = Logger.getLogger(CaseDBCommonAttributeInstance.class.getName()); - + private final String value; /** * Create meta data required to find an abstract file and build a @@ -45,13 +45,14 @@ final public class CaseDBCommonAttributeInstance extends AbstractCommonAttribute * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - CaseDBCommonAttributeInstance(Long abstractFileReference, String dataSource, String caseName) { + CaseDBCommonAttributeInstance(Long abstractFileReference, String dataSource, String caseName, String value) { super(abstractFileReference, dataSource, caseName); + this.value = value; } @Override public DisplayableItemNode[] generateNodes() { - final CaseDBCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new CaseDBCommonAttributeInstanceNode(this.getAbstractFile(), this.getCaseName(), this.getDataSource(), NODE_TYPE.COUNT_NODE); + final CaseDBCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new CaseDBCommonAttributeInstanceNode(this.getAbstractFile(), this.getCaseName(), this.getDataSource(), this.value, NODE_TYPE.COUNT_NODE); return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java index dc2e1f7df0..a70ac1926a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java @@ -37,6 +37,7 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode { private final String caseName; private final String dataSource; + private final String value; private final AbstractCommonAttributeInstance.NODE_TYPE nodeType; /** @@ -48,11 +49,12 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode { * @param dataSource the datasource which contains the file * */ - public CaseDBCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource, AbstractCommonAttributeInstance.NODE_TYPE nodeType) { + public CaseDBCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource, String value, AbstractCommonAttributeInstance.NODE_TYPE nodeType) { super(fsContent, false); this.caseName = caseName; this.dataSource = dataSource; this.nodeType = nodeType; + this.value = value; } @Override @@ -96,7 +98,7 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode { sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl(), NO_DESCR, caseName)); } else if (nodeType == AbstractCommonAttributeInstance.NODE_TYPE.CASE_NODE) { - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_valueColLbl(), Bundle.CommonFilesSearchResultsViewerTable_valueColLbl(), NO_DESCR, this.getContent().getMd5Hash())); + sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_valueColLbl(), Bundle.CommonFilesSearchResultsViewerTable_valueColLbl(), NO_DESCR, this.value)); } return sheet; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeCaseSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeCaseSearchResults.java index 4f4caed0e7..53331e4dc1 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeCaseSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeCaseSearchResults.java @@ -19,8 +19,6 @@ */ package org.sleuthkit.autopsy.commonfilesearch; -import java.util.ArrayList; -import java.util.List; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -46,10 +44,7 @@ final public class CommonAttributeCaseSearchResults { private static final Logger LOGGER = Logger.getLogger(CommonAttributeCaseSearchResults.class.getName()); // maps instance count to list of attribute values. - private Map> caseNameToDataSources; - private final Set mimeTypesToInclude; - private final int percentageThreshold; - private final int resultTypeId; + private final Map> caseNameToDataSources; /** * Create a values object which can be handed off to the node factories. @@ -64,11 +59,7 @@ final public class CommonAttributeCaseSearchResults { * searches */ CommonAttributeCaseSearchResults(Map> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType, Set mimeTypesToFilterOn) { - //wrap in a new object in case any client code has used an unmodifiable collection - this.caseNameToDataSources = new HashMap<>(metadata); - this.percentageThreshold = percentageThreshold; - this.resultTypeId = resultType.getId(); - this.mimeTypesToInclude = mimeTypesToFilterOn; + this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, resultType.getId(), mimeTypesToFilterOn); } /** @@ -80,11 +71,7 @@ final public class CommonAttributeCaseSearchResults { * common, value of 0 is disabled */ CommonAttributeCaseSearchResults(Map> metadata, int percentageThreshold) { - //wrap in a new object in case any client code has used an unmodifiable collection - this.caseNameToDataSources = new HashMap<>(metadata); - this.percentageThreshold = percentageThreshold; - this.resultTypeId = CorrelationAttributeInstance.FILES_TYPE_ID; - this.mimeTypesToInclude = new HashSet<>(); //don't filter on mimetypes + this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, CorrelationAttributeInstance.FILES_TYPE_ID, new HashSet<>()); } /** @@ -112,10 +99,6 @@ final public class CommonAttributeCaseSearchResults { return Collections.unmodifiableMap(this.caseNameToDataSources); } - public void filterMetaData() throws EamDbException { - filterMetadata(this.percentageThreshold); - } - /** * Get an unmodifiable collection of values, indexed by number of * grandchildren, which represents the common attributes found in the @@ -126,46 +109,52 @@ final public class CommonAttributeCaseSearchResults { * * @return metadata */ - private void filterMetadata(int maximumPercentageThreshold) throws EamDbException { - CorrelationAttributeInstance.Type attributeType = CorrelationAttributeInstance - .getDefaultCorrelationTypes() - .stream() - .filter(filterType -> filterType.getId() == this.resultTypeId) - .findFirst().get(); - final String currentCaseName; + private Map> filterMetadata(Map> metadata, int percentageThreshold, int resultTypeId, Set mimeTypesToFilterOn) { try { - currentCaseName = Case.getCurrentCaseThrows().getDisplayName(); - } catch (NoCurrentCaseException ex) { - throw new EamDbException("Unable to get current case while performing filtering", ex); - } - Double uniqueCaseDataSourceTuples = EamDb.getInstance().getCountUniqueDataSources().doubleValue(); - - //Call countUniqueDataSources once to reduce the number of DB queries needed to get - //the frequencyPercentage - Map currentCaseDataSourceMap = this.caseNameToDataSources.get(currentCaseName); - if (currentCaseDataSourceMap == null) { - LOGGER.log(Level.INFO, "No data for current case found in results, indicating there are no results and nothing will be filtered"); - return; - } - Map> filteredCaseNameToDataSourcesTree = new HashMap<>(); - Map valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, maximumPercentageThreshold, uniqueCaseDataSourceTuples); - for (Entry> mapOfDataSources : Collections.unmodifiableMap(this.caseNameToDataSources).entrySet()) { - if (!mapOfDataSources.getKey().equals(currentCaseName)) { - Map newTreeForCase = createTreeForCase(valuesToKeepCurrentCase, mapOfDataSources.getValue(), attributeType, maximumPercentageThreshold, uniqueCaseDataSourceTuples); - filteredCaseNameToDataSourcesTree.put(mapOfDataSources.getKey(), newTreeForCase); + CorrelationAttributeInstance.Type attributeType = CorrelationAttributeInstance + .getDefaultCorrelationTypes() + .stream() + .filter(filterType -> filterType.getId() == resultTypeId) + .findFirst().get(); + final String currentCaseName; + try { + currentCaseName = Case.getCurrentCaseThrows().getDisplayName(); + } catch (NoCurrentCaseException ex) { + throw new EamDbException("Unable to get current case while performing filtering", ex); } + Double uniqueCaseDataSourceTuples = EamDb.getInstance().getCountUniqueDataSources().doubleValue(); + + //Call countUniqueDataSources once to reduce the number of DB queries needed to get + //the frequencyPercentage + Map currentCaseDataSourceMap = metadata.get(currentCaseName); + if (currentCaseDataSourceMap == null) { + + throw new EamDbException("No data for current case found in results, indicating there are no results and nothing will be filtered"); + } + Map> filteredCaseNameToDataSourcesTree = new HashMap<>(); + Map valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, percentageThreshold, uniqueCaseDataSourceTuples, mimeTypesToFilterOn); + for (Entry> mapOfDataSources : Collections.unmodifiableMap(metadata).entrySet()) { + if (!mapOfDataSources.getKey().equals(currentCaseName)) { + Map newTreeForCase = createTreeForCase(valuesToKeepCurrentCase, mapOfDataSources.getValue(), attributeType, percentageThreshold, uniqueCaseDataSourceTuples); + filteredCaseNameToDataSourcesTree.put(mapOfDataSources.getKey(), newTreeForCase); + } + } + return filteredCaseNameToDataSourcesTree; + } catch (EamDbException ex) { + LOGGER.log(Level.INFO, "Unable to perform filtering returning unfiltered result set", ex); + return metadata; } - this.caseNameToDataSources = filteredCaseNameToDataSourcesTree; + } - private Map getValuesToKeepFromCurrentCase(Map dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples) throws EamDbException { + private Map getValuesToKeepFromCurrentCase(Map dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set mimeTypesToFilterOn) throws EamDbException { Map valuesToKeep = new HashMap<>(); Set valuesToRemove = new HashSet<>(); for (Entry mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) { for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataList()) { if (valuesToRemove.contains(value.getValue())) { //do nothing this value will not be added - } else if (filterValue(attributeType, value, maximumPercentageThreshold, uniqueCaseDataSourceTuples)) { + } else if (filterValue(attributeType, value, maximumPercentageThreshold, uniqueCaseDataSourceTuples, mimeTypesToFilterOn)) { valuesToRemove.add(value.getValue()); } else { valuesToKeep.put(value.getValue(), value); @@ -190,7 +179,7 @@ final public class CommonAttributeCaseSearchResults { return treeForCase; } - private boolean filterValue(CorrelationAttributeInstance.Type attributeType, CommonAttributeValue value, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples) throws EamDbException { + private boolean filterValue(CorrelationAttributeInstance.Type attributeType, CommonAttributeValue value, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set mimeTypesToInclude) throws EamDbException { //Intracase common attribute searches will have been created with an empty mimeTypesToInclude list //because when performing intra case search this filtering will have been done during the query of the case database boolean mimeTypeToRemove = false; //allow code to be more efficient by not attempting to remove the same value multiple times diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 599bb04e2c..1aefcd3c5c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -390,14 +390,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer try { super.done(); CommonAttributeCaseSearchResults metadata = this.get(); - boolean noKeysExist = true; - try { - metadata.filterMetaData(); - noKeysExist = metadata.getMetadata().keySet().isEmpty(); - } catch (EamDbException ex) { - LOGGER.log(Level.SEVERE, "Unable to get keys from metadata", ex); - } - if (noKeysExist) { + if (metadata.getMetadata().keySet().isEmpty()) { Node commonFilesNode = new TableFilterNode(new EmptyNode(Bundle.CommonAttributePanel_search_done_noResults()), true); progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay()); DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), commonFilesNode, 1); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index 9f21adcdb1..b22e77cc61 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -128,10 +128,10 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt if (commonFiles.containsKey(md5)) { final CommonAttributeValue commonAttributeValue = commonFiles.get(md5); - commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName)); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName, md5)); } else { final CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); - commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName)); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName, md5)); commonFiles.put(md5, commonAttributeValue); } }