From 5fad7ae67bf153cae734556c6dd61e05bb163b71 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Mon, 23 Jul 2018 12:55:04 -0400 Subject: [PATCH 1/2] minor refactor. No logic changes --- ... AbstractCommonAttributeSearchResult.java} | 7 ++-- .../AbstractCommonAttributeSearcher.java | 2 +- .../CommonAttributePanel.form | 3 -- .../CommonAttributePanel.java | 4 +- ... CommonAttributeSearchResultRootNode.java} | 25 ++++++------ .../CommonAttributeSearchResults.java | 19 ++++----- .../CommonAttributeValue.java | 25 +++++++----- .../CommonAttributeValueNode.java | 37 ++++++++--------- .../commonfilesearch/InstanceCountNode.java | 40 ++++++++++--------- ...InterCaseCommonAttributeSearchResult.java} | 12 ++++-- .../InterCaseCommonAttributeSearcher.java | 26 +++++++----- .../InterCaseSearchResultsProcessor.java | 2 + ...IntraCaseCommonAttributeSearchResults.java | 2 +- .../datamodel/DisplayableItemNodeVisitor.java | 6 +-- .../commonfilessearch/IntraCaseUtils.java | 4 +- 15 files changed, 116 insertions(+), 98 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AbstractCommonAttributeInstanceNode.java => AbstractCommonAttributeSearchResult.java} (97%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{CommonAttributeSearchResultNode.java => CommonAttributeSearchResultRootNode.java} (72%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonAttributeSearchResults.java => InterCaseCommonAttributeSearchResult.java} (88%) diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java index a0735eb617..6efb525b35 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java @@ -34,9 +34,10 @@ import org.sleuthkit.datamodel.TskCoreException; * multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ -public abstract class AbstractCommonAttributeInstanceNode { +public abstract class AbstractCommonAttributeSearchResult { private final Long abstractFileObjectId; + // maps object ID to file private final Map cachedFiles; private final String caseName; private final String dataSource; @@ -51,7 +52,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ - AbstractCommonAttributeInstanceNode(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + AbstractCommonAttributeSearchResult(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; @@ -65,7 +66,7 @@ public abstract class AbstractCommonAttributeInstanceNode { * @param cachedFiles storage for abstract files which have been used * already so we can avoid extra roundtrips to the case db */ - AbstractCommonAttributeInstanceNode(Map cachedFiles) { + AbstractCommonAttributeSearchResult(Map cachedFiles) { this.abstractFileObjectId = -1L; this.cachedFiles = cachedFiles; this.caseName = ""; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java index 09a7e89d5d..fb8cbd312d 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearcher.java @@ -97,7 +97,7 @@ public abstract class AbstractCommonAttributeSearcher { //collate matches by number of matching instances - doing this in sql doesnt seem efficient Map> instanceCollatedCommonFiles = new TreeMap<>(); for(CommonAttributeValue md5Metadata : commonFiles.values()){ - Integer size = md5Metadata.size(); + Integer size = md5Metadata.getInstanceCount(); if(instanceCollatedCommonFiles.containsKey(size)){ instanceCollatedCommonFiles.get(size).add(md5Metadata); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form index 601366d8f0..c08c3c2d78 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.form @@ -11,9 +11,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java index 24f1352598..c83876f3ce 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributePanel.java @@ -185,9 +185,9 @@ public final class CommonAttributePanel extends javax.swing.JDialog { CommonAttributeSearchResults metadata = this.get(); - CommonAttributeSearchResultNode commonFilesNode = new CommonAttributeSearchResultNode(metadata); + CommonAttributeSearchResultRootNode commonFilesNode = new CommonAttributeSearchResultRootNode(metadata); - // #VIK-3969 + // -3969 DataResultFilterNode dataResultFilterNode = new DataResultFilterNode(commonFilesNode, ExplorerManager.find(CommonAttributePanel.this)); TableFilterNode tableFilterWithDescendantsNode = new TableFilterNode(dataResultFilterNode, 3); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java similarity index 72% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java index 334cebe68b..066a780afb 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java @@ -27,13 +27,14 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; /** - * Wrapper node for Md5Node used to display common files search - * results in the top right pane. Calls InstanceCountNodeFactory. + * Top-level node to store common file search results. Current structure is: + * - node for number of matches + * -- node for MD5/commmon attribute + * --- node for instance. */ -final public class CommonAttributeSearchResultNode extends DisplayableItemNode { - +final public class CommonAttributeSearchResultRootNode extends DisplayableItemNode { - CommonAttributeSearchResultNode(CommonAttributeSearchResults metadataList) { + CommonAttributeSearchResultRootNode(CommonAttributeSearchResults metadataList) { super(Children.create(new InstanceCountNodeFactory(metadataList), true)); } @@ -64,27 +65,27 @@ final public class CommonAttributeSearchResultNode extends DisplayableItemNode { */ static class InstanceCountNodeFactory extends ChildFactory{ - private final CommonAttributeSearchResults metadata; + private final CommonAttributeSearchResults searchResults; /** * Build a factory which converts a CommonAttributeSearchResults * object into DisplayableItemNodes. - * @param metadata + * @param searchResults */ - InstanceCountNodeFactory(CommonAttributeSearchResults metadata){ - this.metadata = metadata; + InstanceCountNodeFactory(CommonAttributeSearchResults searchResults){ + this.searchResults = searchResults; } @Override protected boolean createKeys(List list) { - list.addAll(this.metadata.getMetadata().keySet()); + list.addAll(this.searchResults.getMetadata().keySet()); return true; } @Override protected Node createNodeForKey(Integer instanceCount){ - List md5Metadata = this.metadata.getMetadataForMd5(instanceCount); - return new InstanceCountNode(instanceCount, md5Metadata); + List attributeValues = this.searchResults.getAttributeValuesForInstanceCount(instanceCount); + return new InstanceCountNode(instanceCount, attributeValues); } } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java index 58fa884516..b46cde1316 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResults.java @@ -24,12 +24,13 @@ import java.util.List; import java.util.Map; /** - * Utility and wrapper model around data required for Common Files Search results. - * Subclass this to implement different selections of files from the case. + * Stores the results from the various types of common attribute searching + * Stores results based on how they are currently displayed in the UI */ final public class CommonAttributeSearchResults { - private final Map> metadata; + // maps instance count to list of attribute values. + private final Map> instanceCountToAttributeValues; /** * Create a metadata object which can be handed off to the node @@ -38,7 +39,7 @@ final public class CommonAttributeSearchResults { * @param metadata list of CommonAttributeValue indexed by size of CommonAttributeValue */ CommonAttributeSearchResults(Map> metadata){ - this.metadata = metadata; + this.instanceCountToAttributeValues = metadata; } /** @@ -50,12 +51,12 @@ final public class CommonAttributeSearchResults { * @param md5 key * @return */ - List getMetadataForMd5(Integer instanceCount) { - return this.metadata.get(instanceCount); + List getAttributeValuesForInstanceCount(Integer instanceCount) { + return this.instanceCountToAttributeValues.get(instanceCount); } public Map> getMetadata() { - return Collections.unmodifiableMap(this.metadata); + return Collections.unmodifiableMap(this.instanceCountToAttributeValues); } /** @@ -65,9 +66,9 @@ final public class CommonAttributeSearchResults { public int size() { int count = 0; - for (List data : this.metadata.values()) { + for (List data : this.instanceCountToAttributeValues.values()) { for(CommonAttributeValue md5 : data){ - count += md5.size(); + count += md5.getInstanceCount(); } } return count; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index f997c3b111..32ef80f491 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -28,14 +28,14 @@ import java.util.Set; import java.util.stream.Collectors; /** - * Encapsulates data required to instantiate an Md5Node. + * Defines a value that is used for correlation, such as file MD5 or email address. */ final public class CommonAttributeValue { private final String md5; - private final List fileInstances; + private final List fileInstances; - CommonAttributeValue(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } @@ -45,18 +45,23 @@ final public class CommonAttributeValue { this.fileInstances = new ArrayList<>(); } - public String getMd5() { + public String getValue() { return this.md5; } + /** + * concatenate cases this value was seen into a single string + * + * @return + */ public String getCases() { - final String cases = this.fileInstances.stream().map(AbstractCommonAttributeInstanceNode::getCaseName).collect(Collectors.joining(", ")); + final String cases = this.fileInstances.stream().map(AbstractCommonAttributeSearchResult::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (AbstractCommonAttributeInstanceNode data : this.fileInstances) { + for (AbstractCommonAttributeSearchResult data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -64,15 +69,15 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata) { + void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata, String caseName) { this.fileInstances.add(metadata); } - public Collection getMetadata() { + public Collection getInstances() { return Collections.unmodifiableCollection(this.fileInstances); } @@ -82,7 +87,7 @@ final public class CommonAttributeValue { * * @return number of instances */ - public int size() { + public int getInstanceCount() { return this.fileInstances.size(); } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index 56623bc2af..a5169d63e6 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -31,16 +31,14 @@ import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.NodeProperty; /** - * Represents a common files match - two or more files which appear to be the - * same file and appear as children of this node. This node will simply contain - * the MD5 of the matched files, the data sources those files were found within, - * and a count of the instances represented by the md5. + * Represents the layer in the tree for the value (such as MD5) that was in multiple places. + * Children are instances of that value. */ public class CommonAttributeValueNode extends DisplayableItemNode { private static final Logger LOGGER = Logger.getLogger(CommonAttributeValueNode.class.getName()); - private final String md5Hash; + private final String value; private final int commonFileCount; private final String cases; private final String dataSources; @@ -56,12 +54,13 @@ public class CommonAttributeValueNode extends DisplayableItemNode { super(Children.create( new FileInstanceNodeFactory(data), true)); - this.commonFileCount = data.size(); + this.commonFileCount = data.getInstanceCount(); this.cases = data.getCases(); + // @@ We seem to be doing this string concat twice. We also do it in getDataSources() this.dataSources = String.join(", ", data.getDataSources()); - this.md5Hash = data.getMd5(); + this.value = data.getValue(); - this.setDisplayName(String.format(Bundle.Md5Node_Md5Node_format(), this.md5Hash)); + this.setDisplayName(String.format(Bundle.Md5Node_Md5Node_format(), this.value)); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS } @@ -89,8 +88,8 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * MD5 which is common to these matches * @return string md5 hash */ - public String getMd5() { - return this.md5Hash; + public String getValue() { + return this.value; } @NbBundle.Messages({"Md5Node.createSheet.noDescription= "}) @@ -132,7 +131,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * CommonAttributeValueNode. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { private final CommonAttributeValue descendants; @@ -141,14 +140,16 @@ public class CommonAttributeValueNode extends DisplayableItemNode { } @Override - protected Node[] createNodesForKey(AbstractCommonAttributeInstanceNode file) { - return file.generateNodes(); - } - - @Override - protected boolean createKeys(List list) { - list.addAll(this.descendants.getMetadata()); + protected boolean createKeys(List list) { + list.addAll(this.descendants.getInstances()); return true; } + + @Override + protected Node[] createNodesForKey(AbstractCommonAttributeSearchResult searchResult) { + return searchResult.generateNodes(); + } + + } } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java index 3b29e9ce38..dbc3d362e9 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InstanceCountNode.java @@ -40,24 +40,24 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; final public class InstanceCountNode extends DisplayableItemNode { final private int instanceCount; - final private List metadataList; + final private List attributeValues; /** * Create a node with the given number of instances, and the given * selection of metadata. * @param instanceCount - * @param md5Metadata + * @param attributeValues */ @NbBundle.Messages({ "InstanceCountNode.displayName=Files with %s instances (%s)" }) - public InstanceCountNode(int instanceCount, List md5Metadata) { - super(Children.create(new Md5NodeFactory(md5Metadata), true)); + public InstanceCountNode(int instanceCount, List attributeValues) { + super(Children.create(new CommonAttributeValueNodeFactory(attributeValues), true)); this.instanceCount = instanceCount; - this.metadataList = md5Metadata; + this.attributeValues = attributeValues; - this.setDisplayName(String.format(Bundle.InstanceCountNode_displayName(), Integer.toString(instanceCount), md5Metadata.size())); + this.setDisplayName(String.format(Bundle.InstanceCountNode_displayName(), Integer.toString(instanceCount), attributeValues.size())); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS } @@ -73,8 +73,8 @@ final public class InstanceCountNode extends DisplayableItemNode { * Get a list of metadata for the MD5s which are children of this object. * @return List */ - List getMetadata() { - return Collections.unmodifiableList(this.metadataList); + List getAttributeValues() { + return Collections.unmodifiableList(this.attributeValues); } @Override @@ -113,34 +113,36 @@ final public class InstanceCountNode extends DisplayableItemNode { * ChildFactory which builds CommonFileParentNodes from the * CommonFilesMetaaData models. */ - static class Md5NodeFactory extends ChildFactory { + static class CommonAttributeValueNodeFactory extends ChildFactory { /** * List of models, each of which is a parent node matching a single md5, * containing children FileNodes. */ + // maps sting version of value to value Object (??) private final Map metadata; - Md5NodeFactory(List metadata) { + CommonAttributeValueNodeFactory(List attributeValues) { this.metadata = new HashMap<>(); - Iterator iterator = metadata.iterator(); + Iterator iterator = attributeValues.iterator(); while (iterator.hasNext()) { - CommonAttributeValue md5Metadata = iterator.next(); - this.metadata.put(md5Metadata.getMd5(), md5Metadata); + CommonAttributeValue attributeValue = iterator.next(); + this.metadata.put(attributeValue.getValue(), attributeValue); } } - @Override - protected Node createNodeForKey(String md5) { - CommonAttributeValue md5Metadata = this.metadata.get(md5); - return new CommonAttributeValueNode(md5Metadata); - } - @Override protected boolean createKeys(List list) { + // @@@ We should just use CommonAttributeValue as the key... list.addAll(this.metadata.keySet()); return true; } + + @Override + protected Node createNodeForKey(String attributeValue) { + CommonAttributeValue md5Metadata = this.metadata.get(attributeValue); + return new CommonAttributeValueNode(md5Metadata); + } } } \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java similarity index 88% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java index 46ca88f439..f5b0703fd2 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java @@ -35,15 +35,17 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** + * Represents that a row in the CR was found in multiple cases. + * * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class InterCaseCommonAttributeSearchResults extends AbstractCommonAttributeInstanceNode { +final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAttributeSearchResult { - private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); + private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResult.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInstance; - InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { + InterCaseCommonAttributeSearchResult(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } @@ -79,6 +81,8 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA @Override public DisplayableItemNode[] generateNodes() { + // @@@ We should be doing more of this work in teh generateKeys method. We want to do as little as possible in generateNodes + InterCaseSearchResultsProcessor eamDbAttrInst = new InterCaseSearchResultsProcessor(); CorrelationAttribute corrAttr = eamDbAttrInst.findSingleCorrelationAttribute(crFileId); List attrInstNodeList = new ArrayList<>(0); @@ -90,7 +94,7 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstanceNode.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeSearchResult.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); attrInstNodeList.add(generatedInstNode); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 604dbaece2..9dc4ad661f 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -56,17 +56,18 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS /** * @param artifactInstances all 'common files' in central repo - * @param commonFiles matches must ultimately have appeared in this + * @param commonValues matches must ultimately have appeared in this * collection * @return collated map of instance counts to lists of matches */ - Map> gatherIntercaseResults(Map commonFiles, Map commonFileCases) { + Map> gatherIntercaseResults(Map commonValues, Map commonFileCases) { + // keyis string of value Map interCaseCommonFiles = new HashMap<>(); - for (int commonAttrId : commonFiles.keySet()) { + for (int commonAttrId : commonValues.keySet()) { - String md5 = commonFiles.get(commonAttrId); + String md5 = commonValues.get(commonAttrId); if (md5 == null || HashUtility.isNoDataMd5(md5)) { continue; } @@ -82,15 +83,18 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS if (interCaseCommonFiles.containsKey(md5)) { //Add to intercase metaData - final CommonAttributeValue md5Metadata = interCaseCommonFiles.get(md5); - AbstractCommonAttributeInstanceNode nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); - md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); + final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); + + AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } else { - CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - AbstractCommonAttributeInstanceNode nodeGenerator = new InterCaseCommonAttributeSearchResults(commonAttrId, fileCache); - md5Metadata.addFileInstanceMetadata(nodeGenerator, correlationCaseDisplayName); - interCaseCommonFiles.put(md5, md5Metadata); + CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); + interCaseCommonFiles.put(md5, commonAttributeValue); + + AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); + } } catch (Exception ex) { LOGGER.log(Level.WARNING, "Error getting artifact instances from database.", ex); // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java index ae679dfee4..8416bbd856 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseSearchResultsProcessor.java @@ -42,7 +42,9 @@ final class InterCaseSearchResultsProcessor { 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<>(); /** diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java index ba77d3e2c1..bc39fa60ef 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java @@ -33,7 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Encapsulates data required to instantiate a FileInstanceNode. */ -final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeInstanceNode { +final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeSearchResult { private static final Logger LOGGER = Logger.getLogger(IntraCaseCommonAttributeSearchResults.class.getName()); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index d7e4cf3ebb..6e6cbb7e70 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.datamodel; import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; -import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultNode; +import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultRootNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; @@ -118,7 +118,7 @@ public interface DisplayableItemNodeVisitor { T visit(CommonAttributeValueNode mn); - T visit(CommonAttributeSearchResultNode cfn); + T visit(CommonAttributeSearchResultRootNode cfn); T visit(IntraCaseCommonAttributeInstanceNode fin); @@ -205,7 +205,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(CommonAttributeSearchResultNode cfn) { + public T visit(CommonAttributeSearchResultRootNode cfn) { return defaultVisit(cfn); } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index 634968638f..e44e1a3b40 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -33,7 +33,7 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearchResult; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; @@ -207,7 +207,7 @@ class IntraCaseUtils { for (Map.Entry> entry : metadata.getMetadata().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { - for (AbstractCommonAttributeInstanceNode fim : md.getMetadata()) { + for (AbstractCommonAttributeSearchResult fim : md.getInstances()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); } } From 23a487c1901828cbd508581949c3c1a5c8cc5c53 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Mon, 23 Jul 2018 14:06:49 -0400 Subject: [PATCH 2/2] minor refactor --- ...a => AbstractCommonAttributeInstance.java} | 30 ++++--- ...ava => CaseDBCommonAttributeInstance.java} | 12 +-- ...=> CaseDBCommonAttributeInstanceNode.java} | 13 +-- ...> CentralRepoCommonAttributeInstance.java} | 12 +-- ...ntralRepoCommonAttributeInstanceNode.java} | 6 +- .../CommonAttributeInstanceNode.java | 89 ------------------- .../CommonAttributeValue.java | 18 ++-- .../CommonAttributeValueNode.java | 6 +- .../InterCaseCommonAttributeSearcher.java | 4 +- .../IntraCaseCommonAttributeSearcher.java | 10 +-- .../datamodel/DisplayableItemNodeVisitor.java | 12 +-- .../directorytree/DataResultFilterNode.java | 8 +- .../commonfilessearch/InterCaseUtils.java | 2 +- .../commonfilessearch/IntraCaseUtils.java | 4 +- 14 files changed, 70 insertions(+), 156 deletions(-) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{AbstractCommonAttributeSearchResult.java => AbstractCommonAttributeInstance.java} (86%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{IntraCaseCommonAttributeSearchResults.java => CaseDBCommonAttributeInstance.java} (79%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{IntraCaseCommonAttributeInstanceNode.java => CaseDBCommonAttributeInstanceNode.java} (84%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonAttributeSearchResult.java => CentralRepoCommonAttributeInstance.java} (86%) rename Core/src/org/sleuthkit/autopsy/commonfilesearch/{InterCaseCommonAttributeInstanceNode.java => CentralRepoCommonAttributeInstanceNode.java} (95%) delete mode 100644 Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index 6efb525b35..6f445ca0a3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeSearchResult.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java @@ -26,6 +26,10 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; /** + * Represents an instance in either the CaseDB or CR that had a common match. + * Different implementations know how to get the instance details from either + * CaseDB or CR. + * * Defines leaf-type nodes used in the Common Files Search results tree. Leaf * nodes, may describe common attributes which exist in the current case DB or * in the Central Repo. When a reference to the AbstractFile is lacking (such as @@ -34,7 +38,7 @@ import org.sleuthkit.datamodel.TskCoreException; * multiple types of leaf nodes are required to represent Common Attribute * Instance nodes. */ -public abstract class AbstractCommonAttributeSearchResult { +public abstract class AbstractCommonAttributeInstance { private final Long abstractFileObjectId; // maps object ID to file @@ -52,7 +56,7 @@ public abstract class AbstractCommonAttributeSearchResult { * @param dataSource datasource where this attribute appears * @param caseName case where this attribute appears */ - AbstractCommonAttributeSearchResult(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + AbstractCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; @@ -66,7 +70,7 @@ public abstract class AbstractCommonAttributeSearchResult { * @param cachedFiles storage for abstract files which have been used * already so we can avoid extra roundtrips to the case db */ - AbstractCommonAttributeSearchResult(Map cachedFiles) { + AbstractCommonAttributeInstance(Map cachedFiles) { this.abstractFileObjectId = -1L; this.cachedFiles = cachedFiles; this.caseName = ""; @@ -80,11 +84,11 @@ public abstract class AbstractCommonAttributeSearchResult { * @return AbstractFile which is identical to the file instance generated by * implementations of this object */ - AbstractFile lookupOrLoadAbstractFile() { + protected AbstractFile lookupOrLoadAbstractFile() { if (this.cachedFiles.containsKey(this.getAbstractFileObjectId())) { return this.cachedFiles.get(this.getAbstractFileObjectId()); } else { - AbstractFile file = this.loadFileFromSleuthkitCase(); + AbstractFile file = this.getAbstractFile(); final long abstractFileId = file.getId(); this.cachedFiles.put(abstractFileId, file); return file; @@ -92,14 +96,14 @@ public abstract class AbstractCommonAttributeSearchResult { } /** - * Implement this in subclasses to find the AbstractFile by whatever means - * available. This will be called by this.lookupOrLoadAbstractFile. In some - * cases we may have the object abstractFileId, in other cases we may need - * to use the file name. + * Get an AbstractFile for this instance if it can be retrieved from + * the CaseDB. * - * @return AbstractFile corresponding to this common attribute + * @return AbstractFile corresponding to this common attribute or null if + * it cannot be found + * @@@ Consider throwing exception instead of NULL */ - abstract AbstractFile loadFileFromSleuthkitCase(); + abstract AbstractFile getAbstractFile(); /** * Create a list of leaf nodes, to be used to display a row in the tree @@ -184,9 +188,9 @@ public abstract class AbstractCommonAttributeSearchResult { final boolean sameDataSource = attributeDataSourceName.equalsIgnoreCase(abstractFileDataSourceName); if (sameCase && sameFileName && sameDataSource) { - leafNode = new IntraCaseCommonAttributeInstanceNode(equivalentAbstractFile, currentCaseName, abstractFileDataSourceName); + leafNode = new CaseDBCommonAttributeInstanceNode(equivalentAbstractFile, currentCaseName, abstractFileDataSourceName); } else { - leafNode = new InterCaseCommonAttributeInstanceNode(attributeInstance, equivalentAbstractFile); + leafNode = new CentralRepoCommonAttributeInstanceNode(attributeInstance, equivalentAbstractFile); } return leafNode; } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java similarity index 79% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java index bc39fa60ef..74363a869b 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstance.java @@ -31,11 +31,11 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Encapsulates data required to instantiate a FileInstanceNode. + * Encapsulates data required to instantiate a FileInstanceNode for an instance in the CaseDB */ -final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonAttributeSearchResult { +final public class CaseDBCommonAttributeInstance extends AbstractCommonAttributeInstance { - private static final Logger LOGGER = Logger.getLogger(IntraCaseCommonAttributeSearchResults.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CaseDBCommonAttributeInstance.class.getName()); /** @@ -45,18 +45,18 @@ final public class IntraCaseCommonAttributeSearchResults extends AbstractCommonA * @param objectId id of abstract file to find * @param dataSourceName name of datasource where the object is found */ - IntraCaseCommonAttributeSearchResults(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { + CaseDBCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { super(abstractFileReference, cachedFiles, dataSource, caseName); } @Override public DisplayableItemNode[] generateNodes() { - final IntraCaseCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new IntraCaseCommonAttributeInstanceNode(this.lookupOrLoadAbstractFile(), this.getCaseName(), this.getDataSource()); + final CaseDBCommonAttributeInstanceNode intraCaseCommonAttributeInstanceNode = new CaseDBCommonAttributeInstanceNode(this.lookupOrLoadAbstractFile(), this.getCaseName(), this.getDataSource()); return Arrays.asList(intraCaseCommonAttributeInstanceNode).toArray(new DisplayableItemNode[1]); } @Override - AbstractFile loadFileFromSleuthkitCase() { + AbstractFile getAbstractFile() { Case currentCase; try { diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java similarity index 84% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java index f977e72d88..59e5318801 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CaseDBCommonAttributeInstanceNode.java @@ -26,15 +26,10 @@ import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.datamodel.AbstractFile; /** - * Used by the Common Files search feature to encapsulate instances of a given - * MD5s matched in the search. These nodes will be children of Md5Nodes. - * - * Use this type for files which are in the current case. Contrast with - * CentralRepositoryFileInstanceNode which should be used when the - * FileInstance was found in some case not presently open in Autopsy, but present - * in the Central Repository. + * Node that wraps CaseDBCommonAttributeInstance to represent a file instance stored + * in the CaseDB. */ -public class IntraCaseCommonAttributeInstanceNode extends FileNode { +public class CaseDBCommonAttributeInstanceNode extends FileNode { private final String caseName; private final String dataSource; @@ -46,7 +41,7 @@ public class IntraCaseCommonAttributeInstanceNode extends FileNode { * @param fsContent * @param dataSource */ - public IntraCaseCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { + public CaseDBCommonAttributeInstanceNode(AbstractFile fsContent, String caseName, String dataSource) { super(fsContent); this.caseName = caseName; this.dataSource = dataSource; diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index f5b0703fd2..d154e6f1df 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResult.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java @@ -39,13 +39,13 @@ import org.sleuthkit.datamodel.TskCoreException; * * Generates a DisplayableItmeNode using a CentralRepositoryFile. */ -final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAttributeSearchResult { +final public class CentralRepoCommonAttributeInstance extends AbstractCommonAttributeInstance { - private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResult.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInstance; - InterCaseCommonAttributeSearchResult(Integer attrInstId, Map cachedFiles) { + CentralRepoCommonAttributeInstance(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } @@ -55,9 +55,10 @@ final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAt } @Override - AbstractFile loadFileFromSleuthkitCase() { + AbstractFile getAbstractFile() { Case currentCase; + // @@@ Need to CHeck for NULL. This seems to depend on generateNodes to be called first String currentFullPath = this.currentAttributeInstance.getFilePath(); try { @@ -88,13 +89,14 @@ final public class InterCaseCommonAttributeSearchResult extends AbstractCommonAt List attrInstNodeList = new ArrayList<>(0); String currCaseDbName = Case.getCurrentCase().getDisplayName(); + // @@@ This seems wrong that we are looping here, but only setting one attrInst in the class, which is then used by getAbstractFile(). for (CorrelationAttributeInstance attrInst : corrAttr.getInstances()) { try { this.setCurrentAttributeInst(attrInst); AbstractFile equivalentAbstractFile = this.lookupOrLoadAbstractFile(); - DisplayableItemNode generatedInstNode = AbstractCommonAttributeSearchResult.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); + DisplayableItemNode generatedInstNode = AbstractCommonAttributeInstance.createInstance(attrInst, equivalentAbstractFile, currCaseDbName); attrInstNodeList.add(generatedInstNode); diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java similarity index 95% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java index ee9b173d3e..ea5b19950c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstanceNode.java @@ -42,7 +42,7 @@ import org.sleuthkit.datamodel.Content; * Central Repo. Contrast with SleuthkitCase which should be used * when the FileInstance was found in the case presently open in Autopsy. */ -public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { +public class CentralRepoCommonAttributeInstanceNode extends DisplayableItemNode { private final CorrelationAttributeInstance crFile; @@ -50,7 +50,7 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { // and we can use this to support certain actions in the tree table and crFile viewer private final AbstractFile md5Reference; - InterCaseCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { + CentralRepoCommonAttributeInstanceNode(CorrelationAttributeInstance content, AbstractFile md5Reference) { super(Children.LEAF, Lookups.fixed(content)); // Using md5Reference enables Other Occurances, but for the current file path this.crFile = content; this.setDisplayName(new File(this.crFile.getFilePath()).getName()); @@ -88,7 +88,7 @@ public class InterCaseCommonAttributeInstanceNode extends DisplayableItemNode { public String getItemType() { //objects of type FileNode will co-occur in the treetable with objects // of this type and they will need to provide the same key - return IntraCaseCommonAttributeInstanceNode.class.getName(); + return CaseDBCommonAttributeInstanceNode.class.getName(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java deleted file mode 100644 index 1b385467d4..0000000000 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeInstanceNode.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.commonfilesearch; - -import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.Sheet; -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; -import org.sleuthkit.autopsy.datamodel.FileNode; -import org.sleuthkit.autopsy.datamodel.NodeProperty; -import org.sleuthkit.datamodel.AbstractFile; - -/** - * Used by the Common Files search feature to encapsulate instances of a given - MD5s matched in the search. These nodes will be children of Md5Nodes. - */ -public class CommonAttributeInstanceNode extends FileNode { - - private final String dataSource; - - /** - * Create a node which can be used in a multilayer tree table and is based - * on an AbstractFile. - * - * @param fsContent - * @param dataSource - */ - public CommonAttributeInstanceNode(AbstractFile fsContent, String dataSource) { - super(fsContent); - this.dataSource = dataSource; - - this.setDisplayName(fsContent.getName()); - } - - @Override - public boolean isLeafTypeNode(){ - //Not used atm - could maybe be leveraged for better use in Children objects - return true; - } - - @Override - public T accept(DisplayableItemNodeVisitor visitor) { - return visitor.visit(this); - } - - String getDataSource() { - return this.dataSource; - } - - @NbBundle.Messages({"FileInstanceNode.createSheet.noDescription= "}) - @Override - protected Sheet createSheet() { - Sheet sheet = new Sheet(); - Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); - if (sheetSet == null) { - sheetSet = Sheet.createPropertiesSet(); - sheet.put(sheetSet); - } - - final String NO_DESCR = Bundle.FileInstanceNode_createSheet_noDescription(); - - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), Bundle.CommonFilesSearchResultsViewerTable_filesColLbl(), NO_DESCR, this.getContent().getName())); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), Bundle.CommonFilesSearchResultsViewerTable_pathColLbl(), NO_DESCR, this.getContent().getParentPath())); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), Bundle.CommonFilesSearchResultsViewerTable_hashsetHitsColLbl(), NO_DESCR, getHashSetHitsForFile(this.getContent()))); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), Bundle.CommonFilesSearchResultsViewerTable_dataSourceColLbl(), NO_DESCR, this.getDataSource())); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), Bundle.CommonFilesSearchResultsViewerTable_mimeTypeColLbl(), NO_DESCR, StringUtils.defaultString(this.getContent().getMIMEType()))); - this.addTagProperty(sheetSet); - sheetSet.put(new NodeProperty<>(Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), Bundle.CommonFilesSearchResultsViewerTable_caseColLbl1(), NO_DESCR, Case.getCurrentCase().getDisplayName())); - - return sheet; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java index 32ef80f491..3ed386ab10 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValue.java @@ -28,14 +28,15 @@ import java.util.Set; import java.util.stream.Collectors; /** - * Defines a value that is used for correlation, such as file MD5 or email address. + * Defines a value that was in the common file search results + * as well as information about its instances. */ final public class CommonAttributeValue { private final String md5; - private final List fileInstances; + private final List fileInstances; - CommonAttributeValue(String md5, List fileInstances) { + CommonAttributeValue(String md5, List fileInstances) { this.md5 = md5; this.fileInstances = fileInstances; } @@ -55,13 +56,13 @@ final public class CommonAttributeValue { * @return */ public String getCases() { - final String cases = this.fileInstances.stream().map(AbstractCommonAttributeSearchResult::getCaseName).collect(Collectors.joining(", ")); + final String cases = this.fileInstances.stream().map(AbstractCommonAttributeInstance::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (AbstractCommonAttributeSearchResult data : this.fileInstances) { + for (AbstractCommonAttributeInstance data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -69,15 +70,16 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata) { + void addInstance(AbstractCommonAttributeInstance metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeSearchResult metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeInstance metadata, String caseName) { this.fileInstances.add(metadata); + // @@@ Why are we ignoring caseName? } - public Collection getInstances() { + public Collection getInstances() { return Collections.unmodifiableCollection(this.fileInstances); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java index a5169d63e6..e7160e8d11 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeValueNode.java @@ -131,7 +131,7 @@ public class CommonAttributeValueNode extends DisplayableItemNode { * Child generator for SleuthkitCaseFileInstanceNode of * CommonAttributeValueNode. */ - static class FileInstanceNodeFactory extends ChildFactory { + static class FileInstanceNodeFactory extends ChildFactory { private final CommonAttributeValue descendants; @@ -140,13 +140,13 @@ public class CommonAttributeValueNode extends DisplayableItemNode { } @Override - protected boolean createKeys(List list) { + protected boolean createKeys(List list) { list.addAll(this.descendants.getInstances()); return true; } @Override - protected Node[] createNodesForKey(AbstractCommonAttributeSearchResult searchResult) { + protected Node[] createNodesForKey(AbstractCommonAttributeInstance searchResult) { return searchResult.generateNodes(); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 9dc4ad661f..a5c5f642b7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java @@ -85,14 +85,14 @@ abstract class InterCaseCommonAttributeSearcher extends AbstractCommonAttributeS //Add to intercase metaData final CommonAttributeValue commonAttributeValue = interCaseCommonFiles.get(md5); - AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } else { CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); interCaseCommonFiles.put(md5, commonAttributeValue); - AbstractCommonAttributeSearchResult searchResult = new InterCaseCommonAttributeSearchResult(commonAttrId, fileCache); + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(commonAttrId, fileCache); commonAttributeValue.addFileInstanceMetadata(searchResult, correlationCaseDisplayName); } diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java index e60476da36..60a89fb5e5 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/IntraCaseCommonAttributeSearcher.java @@ -124,12 +124,12 @@ public abstract class IntraCaseCommonAttributeSearcher extends AbstractCommonAtt } if (commonFiles.containsKey(md5)) { - final CommonAttributeValue md5Metadata = commonFiles.get(md5); - md5Metadata.addFileInstanceMetadata(new IntraCaseCommonAttributeSearchResults(objectId, fileCache, dataSource, caseName)); + final CommonAttributeValue commonAttributeValue = commonFiles.get(md5); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, fileCache, dataSource, caseName)); } else { - final CommonAttributeValue md5Metadata = new CommonAttributeValue(md5); - md5Metadata.addFileInstanceMetadata(new IntraCaseCommonAttributeSearchResults(objectId, fileCache, dataSource, caseName)); - commonFiles.put(md5, md5Metadata); + final CommonAttributeValue commonAttributeValue = new CommonAttributeValue(md5); + commonAttributeValue.addInstance(new CaseDBCommonAttributeInstance(objectId, fileCache, dataSource, caseName)); + commonFiles.put(md5, commonAttributeValue); } } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index 6e6cbb7e70..cd14117c95 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -18,11 +18,11 @@ */ package org.sleuthkit.autopsy.datamodel; -import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepoCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResultRootNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsChildren.DeletedContentNode; import org.sleuthkit.autopsy.datamodel.DeletedContent.DeletedContentsNode; import org.sleuthkit.autopsy.datamodel.FileSize.FileSizeRootChildren.FileSizeNode; @@ -120,9 +120,9 @@ public interface DisplayableItemNodeVisitor { T visit(CommonAttributeSearchResultRootNode cfn); - T visit(IntraCaseCommonAttributeInstanceNode fin); + T visit(CaseDBCommonAttributeInstanceNode fin); - T visit(InterCaseCommonAttributeInstanceNode crfin); + T visit(CentralRepoCommonAttributeInstanceNode crfin); T visit(InstanceCountNode icn); @@ -195,7 +195,7 @@ public interface DisplayableItemNodeVisitor { protected abstract T defaultVisit(DisplayableItemNode c); @Override - public T visit(IntraCaseCommonAttributeInstanceNode fin) { + public T visit(CaseDBCommonAttributeInstanceNode fin) { return defaultVisit(fin); } @@ -215,7 +215,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(InterCaseCommonAttributeInstanceNode crfin){ + public T visit(CentralRepoCommonAttributeInstanceNode crfin){ return defaultVisit(crfin); } diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 32598d4cfd..098789597c 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -56,14 +56,14 @@ import org.sleuthkit.autopsy.datamodel.FileTypeExtensions; import org.sleuthkit.autopsy.datamodel.FileTypes.FileTypesNode; import org.sleuthkit.autopsy.commonfilesearch.InstanceCountNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValueNode; -import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CentralRepoCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.LayoutFileNode; import org.sleuthkit.autopsy.datamodel.LocalFileNode; import org.sleuthkit.autopsy.datamodel.LocalDirectoryNode; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; import org.sleuthkit.autopsy.datamodel.Reports; import org.sleuthkit.autopsy.datamodel.SlackFileNode; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeInstanceNode; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstanceNode; import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode; import static org.sleuthkit.autopsy.directorytree.Bundle.DataResultFilterNode_viewSourceArtifact_text; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; @@ -535,12 +535,12 @@ public class DataResultFilterNode extends FilterNode { } @Override - public AbstractAction visit(IntraCaseCommonAttributeInstanceNode fin){ + public AbstractAction visit(CaseDBCommonAttributeInstanceNode fin){ return null; } @Override - public AbstractAction visit(InterCaseCommonAttributeInstanceNode iccan){ + public AbstractAction visit(CentralRepoCommonAttributeInstanceNode iccan){ return null; } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java index 1dbc67a180..bc626b6459 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/InterCaseUtils.java @@ -52,7 +52,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; -import org.sleuthkit.autopsy.commonfilesearch.IntraCaseCommonAttributeSearchResults; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstance; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; /** diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java index e44e1a3b40..035a16a0ed 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/commonfilessearch/IntraCaseUtils.java @@ -33,7 +33,7 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeSearchResult; +import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstance; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; @@ -207,7 +207,7 @@ class IntraCaseUtils { for (Map.Entry> entry : metadata.getMetadata().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { - for (AbstractCommonAttributeSearchResult fim : md.getInstances()) { + for (AbstractCommonAttributeInstance fim : md.getInstances()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); } }