diff --git a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java similarity index 86% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstance.java index a0735eb617..6f445ca0a3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/AbstractCommonAttributeInstanceNode.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,9 +38,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 AbstractCommonAttributeInstance { private final Long abstractFileObjectId; + // maps object ID to file private final Map cachedFiles; private final String caseName; private final String dataSource; @@ -51,7 +56,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) { + AbstractCommonAttributeInstance(Long abstractFileReference, Map cachedFiles, String dataSource, String caseName) { this.abstractFileObjectId = abstractFileReference; this.cachedFiles = cachedFiles; this.caseName = caseName; @@ -65,7 +70,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) { + AbstractCommonAttributeInstance(Map cachedFiles) { this.abstractFileObjectId = -1L; this.cachedFiles = cachedFiles; this.caseName = ""; @@ -79,11 +84,11 @@ public abstract class AbstractCommonAttributeInstanceNode { * @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; @@ -91,14 +96,14 @@ public abstract class AbstractCommonAttributeInstanceNode { } /** - * 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 @@ -183,9 +188,9 @@ public abstract class AbstractCommonAttributeInstanceNode { 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/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/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 ba77d3e2c1..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 AbstractCommonAttributeInstanceNode { +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 b433be2848..f321b7a72a 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/InterCaseCommonAttributeSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java similarity index 81% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.java index 90107d6dc0..e720cef635 100644 --- a/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonfilesearch/CentralRepoCommonAttributeInstance.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 CentralRepoCommonAttributeInstance extends AbstractCommonAttributeInstance { - private static final Logger LOGGER = Logger.getLogger(InterCaseCommonAttributeSearchResults.class.getName()); + private static final Logger LOGGER = Logger.getLogger(CentralRepoCommonAttributeInstance.class.getName()); private final Integer crFileId; private CorrelationAttributeInstance currentAttributeInstance; - InterCaseCommonAttributeSearchResults(Integer attrInstId, Map cachedFiles) { + CentralRepoCommonAttributeInstance(Integer attrInstId, Map cachedFiles) { super(cachedFiles); this.crFileId = attrInstId; } @@ -53,9 +55,10 @@ final public class InterCaseCommonAttributeSearchResults extends AbstractCommonA } @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 { @@ -79,18 +82,21 @@ 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); 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 = AbstractCommonAttributeInstanceNode.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 8f4a0d6599..5a19aeaead 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/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 71% rename from Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultNode.java rename to Core/src/org/sleuthkit/autopsy/commonfilesearch/CommonAttributeSearchResultRootNode.java index 4a8e435d3c..8e33401af7 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.getValues().keySet()); + list.addAll(this.searchResults.getMetadata().keySet()); return true; } @Override protected Node createNodeForKey(Integer instanceCount){ - List md5Metadata = this.metadata.getValuesByChildSize(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 d38c86d96e..8ff13e87f1 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> values; + // maps instance count to list of attribute values. + private final Map> instanceCountToAttributeValues; /** * Create a values object which can be handed off to the node factories. @@ -37,8 +38,8 @@ final public class CommonAttributeSearchResults { * @param values list of CommonAttributeValue indexed by size of * CommonAttributeValue */ - CommonAttributeSearchResults(Map> values){ - this.values = values; + CommonAttributeSearchResults(Map> metadata){ + this.instanceCountToAttributeValues = metadata; } /** @@ -50,18 +51,18 @@ final public class CommonAttributeSearchResults { * @param isntanceCound key * @return list of values which represent matches */ - List getValuesByChildSize(Integer instanceCount) { - return this.values.get(instanceCount); + List getAttributeValuesForInstanceCount(Integer instanceCount) { + return this.instanceCountToAttributeValues.get(instanceCount); } - /** + /** * Get an unmodifiable collection of values, indexed by number of * grandchildren, which represents the common attributes found in the * search. * @return map of sizes of children to list of matches - */ - public Map> getValues() { - return Collections.unmodifiableMap(this.values); + */ +public Map> getMetadata() { + return Collections.unmodifiableMap(this.instanceCountToAttributeValues); } /** @@ -71,9 +72,9 @@ final public class CommonAttributeSearchResults { public int size() { int count = 0; - for (List data : this.values.values()) { - for(CommonAttributeValue value : data){ - count += value.size(); + for (List data : this.instanceCountToAttributeValues.values()) { + for(CommonAttributeValue md5 : data){ + 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..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; /** - * Encapsulates data required to instantiate an Md5Node. + * 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; } @@ -45,18 +46,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(AbstractCommonAttributeInstance::getCaseName).collect(Collectors.joining(", ")); return cases; } public String getDataSources() { Set sources = new HashSet<>(); - for (AbstractCommonAttributeInstanceNode data : this.fileInstances) { + for (AbstractCommonAttributeInstance data : this.fileInstances) { sources.add(data.getDataSource()); } @@ -64,15 +70,16 @@ final public class CommonAttributeValue { return dataSources; } - void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata) { + void addInstance(AbstractCommonAttributeInstance metadata) { this.fileInstances.add(metadata); } - void addFileInstanceMetadata(AbstractCommonAttributeInstanceNode metadata, String caseName) { + void addFileInstanceMetadata(AbstractCommonAttributeInstance metadata, String caseName) { this.fileInstances.add(metadata); + // @@@ Why are we ignoring caseName? } - public Collection getMetadata() { + public Collection getInstances() { return Collections.unmodifiableCollection(this.fileInstances); } @@ -82,7 +89,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..e7160e8d11 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(AbstractCommonAttributeInstance 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/InterCaseCommonAttributeSearcher.java b/Core/src/org/sleuthkit/autopsy/commonfilesearch/InterCaseCommonAttributeSearcher.java index 604dbaece2..a5c5f642b7 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); + + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(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); + + AbstractCommonAttributeInstance searchResult = new CentralRepoCommonAttributeInstance(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/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 d7e4cf3ebb..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.CommonAttributeSearchResultNode; +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; @@ -118,11 +118,11 @@ public interface DisplayableItemNodeVisitor { T visit(CommonAttributeValueNode mn); - T visit(CommonAttributeSearchResultNode cfn); + 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); } @@ -205,7 +205,7 @@ public interface DisplayableItemNodeVisitor { } @Override - public T visit(CommonAttributeSearchResultNode cfn) { + public T visit(CommonAttributeSearchResultRootNode cfn) { return defaultVisit(cfn); } @@ -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 c385daa789..07e06332f8 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 @@ -53,6 +53,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.commonfilesearch.AbstractCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeSearchResults; import org.sleuthkit.autopsy.commonfilesearch.DataSourceLoader; +import org.sleuthkit.autopsy.commonfilesearch.CaseDBCommonAttributeInstance; import org.sleuthkit.autopsy.commonfilesearch.CommonAttributeValue; import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeInstanceNode; import org.sleuthkit.autopsy.commonfilesearch.InterCaseCommonAttributeSearchResults; 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 cae0b4d828..550d46be2a 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.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.getValues().entrySet()) { for (CommonAttributeValue md : entry.getValue()) { - for (AbstractCommonAttributeInstanceNode fim : md.getMetadata()) { + for (AbstractCommonAttributeInstance fim : md.getInstances()) { instanceIdToDataSource.put(fim.getAbstractFileObjectId(), fim.getDataSource()); } }