4440 refactor casesearchresults, fix value column for non files

This commit is contained in:
William Schaefer 2018-12-07 14:34:58 -05:00
parent 5e48285cd2
commit 75f889da14
6 changed files with 51 additions and 67 deletions

View File

@ -165,9 +165,8 @@ public abstract class AbstractCommonAttributeInstance {
leafNode = new CentralRepoCommonAttributeInstanceNode(attribute, nodeType); leafNode = new CentralRepoCommonAttributeInstanceNode(attribute, nodeType);
} else { } else {
final String abstractFileDataSourceName = abstractFile.getDataSource().getName(); final String abstractFileDataSourceName = abstractFile.getDataSource().getName();
leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName, nodeType); leafNode = new CaseDBCommonAttributeInstanceNode(abstractFile, currentCaseName, abstractFileDataSourceName, attribute.getCorrelationValue(), nodeType);
} }
return leafNode; return leafNode;
} }

View File

@ -36,7 +36,7 @@ import org.sleuthkit.datamodel.TskCoreException;
final public class CaseDBCommonAttributeInstance extends AbstractCommonAttributeInstance { final public class CaseDBCommonAttributeInstance extends AbstractCommonAttributeInstance {
private static final Logger LOGGER = Logger.getLogger(CaseDBCommonAttributeInstance.class.getName()); 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 * 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 objectId id of abstract file to find
* @param dataSourceName name of datasource where the object is found * @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); super(abstractFileReference, dataSource, caseName);
this.value = value;
} }
@Override @Override
public DisplayableItemNode[] generateNodes() { 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]); return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]);
} }

View File

@ -37,6 +37,7 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode {
private final String caseName; private final String caseName;
private final String dataSource; private final String dataSource;
private final String value;
private final AbstractCommonAttributeInstance.NODE_TYPE nodeType; private final AbstractCommonAttributeInstance.NODE_TYPE nodeType;
/** /**
@ -48,11 +49,12 @@ public class CaseDBCommonAttributeInstanceNode extends FileNode {
* @param dataSource the datasource which contains the file * @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); super(fsContent, false);
this.caseName = caseName; this.caseName = caseName;
this.dataSource = dataSource; this.dataSource = dataSource;
this.nodeType = nodeType; this.nodeType = nodeType;
this.value = value;
} }
@Override @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_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource()));
sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl(), NO_DESCR, caseName)); sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl(), NO_DESCR, caseName));
} else if (nodeType == AbstractCommonAttributeInstance.NODE_TYPE.CASE_NODE) { } 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; return sheet;
} }

View File

@ -19,8 +19,6 @@
*/ */
package org.sleuthkit.autopsy.commonfilesearch; package org.sleuthkit.autopsy.commonfilesearch;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -46,10 +44,7 @@ final public class CommonAttributeCaseSearchResults {
private static final Logger LOGGER = Logger.getLogger(CommonAttributeCaseSearchResults.class.getName()); private static final Logger LOGGER = Logger.getLogger(CommonAttributeCaseSearchResults.class.getName());
// maps instance count to list of attribute values. // maps instance count to list of attribute values.
private Map<String, Map<String, CommonAttributeValueList>> caseNameToDataSources; private final Map<String, Map<String, CommonAttributeValueList>> caseNameToDataSources;
private final Set<String> mimeTypesToInclude;
private final int percentageThreshold;
private final int resultTypeId;
/** /**
* Create a values object which can be handed off to the node factories. * Create a values object which can be handed off to the node factories.
@ -64,11 +59,7 @@ final public class CommonAttributeCaseSearchResults {
* searches * searches
*/ */
CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType, Set<String> mimeTypesToFilterOn) { CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, CorrelationAttributeInstance.Type resultType, Set<String> mimeTypesToFilterOn) {
//wrap in a new object in case any client code has used an unmodifiable collection this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, resultType.getId(), mimeTypesToFilterOn);
this.caseNameToDataSources = new HashMap<>(metadata);
this.percentageThreshold = percentageThreshold;
this.resultTypeId = resultType.getId();
this.mimeTypesToInclude = mimeTypesToFilterOn;
} }
/** /**
@ -80,11 +71,7 @@ final public class CommonAttributeCaseSearchResults {
* common, value of 0 is disabled * common, value of 0 is disabled
*/ */
CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold) { CommonAttributeCaseSearchResults(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold) {
//wrap in a new object in case any client code has used an unmodifiable collection this.caseNameToDataSources = filterMetadata(metadata, percentageThreshold, CorrelationAttributeInstance.FILES_TYPE_ID, new HashSet<>());
this.caseNameToDataSources = new HashMap<>(metadata);
this.percentageThreshold = percentageThreshold;
this.resultTypeId = CorrelationAttributeInstance.FILES_TYPE_ID;
this.mimeTypesToInclude = new HashSet<>(); //don't filter on mimetypes
} }
/** /**
@ -112,10 +99,6 @@ final public class CommonAttributeCaseSearchResults {
return Collections.unmodifiableMap(this.caseNameToDataSources); return Collections.unmodifiableMap(this.caseNameToDataSources);
} }
public void filterMetaData() throws EamDbException {
filterMetadata(this.percentageThreshold);
}
/** /**
* Get an unmodifiable collection of values, indexed by number of * Get an unmodifiable collection of values, indexed by number of
* grandchildren, which represents the common attributes found in the * grandchildren, which represents the common attributes found in the
@ -126,11 +109,12 @@ final public class CommonAttributeCaseSearchResults {
* *
* @return metadata * @return metadata
*/ */
private void filterMetadata(int maximumPercentageThreshold) throws EamDbException { private Map<String, Map<String, CommonAttributeValueList>> filterMetadata(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, int resultTypeId, Set<String> mimeTypesToFilterOn) {
try {
CorrelationAttributeInstance.Type attributeType = CorrelationAttributeInstance CorrelationAttributeInstance.Type attributeType = CorrelationAttributeInstance
.getDefaultCorrelationTypes() .getDefaultCorrelationTypes()
.stream() .stream()
.filter(filterType -> filterType.getId() == this.resultTypeId) .filter(filterType -> filterType.getId() == resultTypeId)
.findFirst().get(); .findFirst().get();
final String currentCaseName; final String currentCaseName;
try { try {
@ -142,30 +126,35 @@ final public class CommonAttributeCaseSearchResults {
//Call countUniqueDataSources once to reduce the number of DB queries needed to get //Call countUniqueDataSources once to reduce the number of DB queries needed to get
//the frequencyPercentage //the frequencyPercentage
Map<String, CommonAttributeValueList> currentCaseDataSourceMap = this.caseNameToDataSources.get(currentCaseName); Map<String, CommonAttributeValueList> currentCaseDataSourceMap = metadata.get(currentCaseName);
if (currentCaseDataSourceMap == null) { 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; throw new EamDbException("No data for current case found in results, indicating there are no results and nothing will be filtered");
} }
Map<String, Map<String, CommonAttributeValueList>> filteredCaseNameToDataSourcesTree = new HashMap<>(); Map<String, Map<String, CommonAttributeValueList>> filteredCaseNameToDataSourcesTree = new HashMap<>();
Map<String, CommonAttributeValue> valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, maximumPercentageThreshold, uniqueCaseDataSourceTuples); Map<String, CommonAttributeValue> valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, percentageThreshold, uniqueCaseDataSourceTuples, mimeTypesToFilterOn);
for (Entry<String, Map<String, CommonAttributeValueList>> mapOfDataSources : Collections.unmodifiableMap(this.caseNameToDataSources).entrySet()) { for (Entry<String, Map<String, CommonAttributeValueList>> mapOfDataSources : Collections.unmodifiableMap(metadata).entrySet()) {
if (!mapOfDataSources.getKey().equals(currentCaseName)) { if (!mapOfDataSources.getKey().equals(currentCaseName)) {
Map<String, CommonAttributeValueList> newTreeForCase = createTreeForCase(valuesToKeepCurrentCase, mapOfDataSources.getValue(), attributeType, maximumPercentageThreshold, uniqueCaseDataSourceTuples); Map<String, CommonAttributeValueList> newTreeForCase = createTreeForCase(valuesToKeepCurrentCase, mapOfDataSources.getValue(), attributeType, percentageThreshold, uniqueCaseDataSourceTuples);
filteredCaseNameToDataSourcesTree.put(mapOfDataSources.getKey(), newTreeForCase); filteredCaseNameToDataSourcesTree.put(mapOfDataSources.getKey(), newTreeForCase);
} }
} }
this.caseNameToDataSources = filteredCaseNameToDataSourcesTree; return filteredCaseNameToDataSourcesTree;
} catch (EamDbException ex) {
LOGGER.log(Level.INFO, "Unable to perform filtering returning unfiltered result set", ex);
return metadata;
} }
private Map<String, CommonAttributeValue> getValuesToKeepFromCurrentCase(Map<String, CommonAttributeValueList> dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples) throws EamDbException { }
private Map<String, CommonAttributeValue> getValuesToKeepFromCurrentCase(Map<String, CommonAttributeValueList> dataSourceToValueList, CorrelationAttributeInstance.Type attributeType, int maximumPercentageThreshold, Double uniqueCaseDataSourceTuples, Set<String> mimeTypesToFilterOn) throws EamDbException {
Map<String, CommonAttributeValue> valuesToKeep = new HashMap<>(); Map<String, CommonAttributeValue> valuesToKeep = new HashMap<>();
Set<String> valuesToRemove = new HashSet<>(); Set<String> valuesToRemove = new HashSet<>();
for (Entry<String, CommonAttributeValueList> mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) { for (Entry<String, CommonAttributeValueList> mapOfValueLists : Collections.unmodifiableMap(dataSourceToValueList).entrySet()) {
for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataList()) { for (CommonAttributeValue value : mapOfValueLists.getValue().getDelayedMetadataList()) {
if (valuesToRemove.contains(value.getValue())) { if (valuesToRemove.contains(value.getValue())) {
//do nothing this value will not be added //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()); valuesToRemove.add(value.getValue());
} else { } else {
valuesToKeep.put(value.getValue(), value); valuesToKeep.put(value.getValue(), value);
@ -190,7 +179,7 @@ final public class CommonAttributeCaseSearchResults {
return treeForCase; 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<String> mimeTypesToInclude) throws EamDbException {
//Intracase common attribute searches will have been created with an empty mimeTypesToInclude list //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 //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 boolean mimeTypeToRemove = false; //allow code to be more efficient by not attempting to remove the same value multiple times

View File

@ -390,14 +390,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer
try { try {
super.done(); super.done();
CommonAttributeCaseSearchResults metadata = this.get(); CommonAttributeCaseSearchResults metadata = this.get();
boolean noKeysExist = true; if (metadata.getMetadata().keySet().isEmpty()) {
try {
metadata.filterMetaData();
noKeysExist = metadata.getMetadata().keySet().isEmpty();
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Unable to get keys from metadata", ex);
}
if (noKeysExist) {
Node commonFilesNode = new TableFilterNode(new EmptyNode(Bundle.CommonAttributePanel_search_done_noResults()), true); Node commonFilesNode = new TableFilterNode(new EmptyNode(Bundle.CommonAttributePanel_search_done_noResults()), true);
progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay()); progress.setDisplayName(Bundle.CommonAttributePanel_search_done_searchProgressDisplay());
DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), commonFilesNode, 1); DataResultTopComponent.createInstance(tabTitle, Bundle.CommonAttributePanel_search_results_pathText(), commonFilesNode, 1);

View File

@ -128,10 +128,10 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt
if (commonFiles.containsKey(md5)) { if (commonFiles.containsKey(md5)) {
final CommonAttributeValue commonAttributeValue = commonFiles.get(md5); final CommonAttributeValue commonAttributeValue = commonFiles.get(md5);
commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName)); commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, dataSource, caseName, md5));
} else { } else {
final CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); 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); commonFiles.put(md5, commonAttributeValue);
} }
} }