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);
} 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;
}

View File

@ -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]);
}

View File

@ -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;
}

View File

@ -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<String, Map<String, CommonAttributeValueList>> caseNameToDataSources;
private final Set<String> mimeTypesToInclude;
private final int percentageThreshold;
private final int resultTypeId;
private final Map<String, Map<String, CommonAttributeValueList>> 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<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 = 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<String, Map<String, CommonAttributeValueList>> 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<String, Map<String, CommonAttributeValueList>> filterMetadata(Map<String, Map<String, CommonAttributeValueList>> metadata, int percentageThreshold, int resultTypeId, Set<String> 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<String, CommonAttributeValueList> 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<String, Map<String, CommonAttributeValueList>> filteredCaseNameToDataSourcesTree = new HashMap<>();
Map<String, CommonAttributeValue> valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, maximumPercentageThreshold, uniqueCaseDataSourceTuples);
for (Entry<String, Map<String, CommonAttributeValueList>> mapOfDataSources : Collections.unmodifiableMap(this.caseNameToDataSources).entrySet()) {
if (!mapOfDataSources.getKey().equals(currentCaseName)) {
Map<String, CommonAttributeValueList> 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<String, CommonAttributeValueList> 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<String, Map<String, CommonAttributeValueList>> filteredCaseNameToDataSourcesTree = new HashMap<>();
Map<String, CommonAttributeValue> valuesToKeepCurrentCase = getValuesToKeepFromCurrentCase(currentCaseDataSourceMap, attributeType, percentageThreshold, uniqueCaseDataSourceTuples, mimeTypesToFilterOn);
for (Entry<String, Map<String, CommonAttributeValueList>> mapOfDataSources : Collections.unmodifiableMap(metadata).entrySet()) {
if (!mapOfDataSources.getKey().equals(currentCaseName)) {
Map<String, CommonAttributeValueList> 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<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<>();
Set<String> valuesToRemove = new HashSet<>();
for (Entry<String, CommonAttributeValueList> 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<String> 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

View File

@ -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);

View File

@ -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);
}
}