From e9b80d09a16f1df7c1eb6ff1a77f31b868c0388a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 20 Aug 2020 16:07:34 -0400 Subject: [PATCH] 6711 add ResultDomain object --- .../discovery/search/AbstractFilter.java | 2 +- .../discovery/search/DiscoveryAttributes.java | 171 +++++++++++------- .../discovery/search/DiscoveryEventUtils.java | 6 +- .../discovery/search/DiscoveryKeyUtils.java | 31 ++-- .../autopsy/discovery/search/FileSearch.java | 34 ++-- .../autopsy/discovery/search/FileSorter.java | 94 ++++++---- .../autopsy/discovery/search/Group.java | 30 +-- .../autopsy/discovery/search/Result.java | 60 +++++- .../discovery/search/ResultDomain.java | 31 +++- .../autopsy/discovery/search/ResultFile.java | 70 +++---- .../discovery/search/SearchFiltering.java | 31 ++-- .../discovery/search/SearchResults.java | 40 ++-- .../discovery/ui/DiscoveryUiUtils.java | 3 +- .../discovery/ui/OpenDiscoveryAction.java | 2 - .../autopsy/discovery/ui/PageWorker.java | 4 +- 15 files changed, 369 insertions(+), 240 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java index d31fe246b0..cb44c29415 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java @@ -61,7 +61,7 @@ public abstract class AbstractFilter { * * @throws DiscoveryException */ - public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, + public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { return new ArrayList<>(); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java index 54123077e8..6c4a2095f1 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java @@ -52,19 +52,19 @@ public class DiscoveryAttributes { * * @return the key for the group this file goes in */ - public abstract DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file); + public abstract DiscoveryKeyUtils.GroupKey getGroupKey(Result file); /** * Add any extra data to the ResultFile object from this attribute. * - * @param files The list of files to enhance + * @param files The list of results to enhance * @param caseDb The case database * @param centralRepoDb The central repository database. Can be null if * not needed. * * @throws DiscoveryException */ - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { // Default is to do nothing } } @@ -75,8 +75,8 @@ public class DiscoveryAttributes { public static class FileSizeAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.FileSizeGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { + return new DiscoveryKeyUtils.FileSizeGroupKey((ResultFile) file); } } @@ -86,8 +86,8 @@ public class DiscoveryAttributes { public static class ParentPathAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.ParentPathGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { + return new DiscoveryKeyUtils.ParentPathGroupKey((ResultFile) file); } } @@ -97,7 +97,7 @@ public class DiscoveryAttributes { static class NoGroupingAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { + public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) { return new DiscoveryKeyUtils.NoGroupingGroupKey(); } } @@ -108,8 +108,8 @@ public class DiscoveryAttributes { static class DataSourceAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.DataSourceGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) { + return new DiscoveryKeyUtils.DataSourceGroupKey(result); } } @@ -119,7 +119,7 @@ public class DiscoveryAttributes { static class FileTypeAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { return new DiscoveryKeyUtils.FileTypeGroupKey(file); } } @@ -130,20 +130,20 @@ public class DiscoveryAttributes { static class KeywordListAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.KeywordListGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { + return new DiscoveryKeyUtils.KeywordListGroupKey((ResultFile) file); } @Override - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { // Get pairs of (object ID, keyword list name) for all files in the list of files that have // keyword list hits. - String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(), + String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()); - SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(files); + SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(results); try { caseDb.getCaseDbAccessManager().select(selectQuery, callback); } catch (TskCoreException ex) { @@ -158,14 +158,14 @@ public class DiscoveryAttributes { */ private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - List resultFiles; + List resultFiles; /** * Create the callback. * * @param resultFiles List of files to add keyword list names to */ - SetKeywordListNamesCallback(List resultFiles) { + SetKeywordListNamesCallback(List resultFiles) { this.resultFiles = resultFiles; } @@ -174,7 +174,11 @@ public class DiscoveryAttributes { try { // Create a temporary map of object ID to ResultFile Map tempMap = new HashMap<>(); - for (ResultFile file : resultFiles) { + for (Result result : resultFiles) { + if (result.getType() == SearchData.Type.DOMAIN) { + break; + } + ResultFile file = (ResultFile) result; tempMap.put(file.getFirstInstance().getId(), file); } @@ -204,21 +208,21 @@ public class DiscoveryAttributes { static final int BATCH_SIZE = 50; // Number of hashes to look up at one time @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { return new DiscoveryKeyUtils.FrequencyGroupKey(file); } @Override - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { if (centralRepoDb == null) { - for (ResultFile file : files) { - if (file.getFrequency() == SearchData.Frequency.UNKNOWN && file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) { - file.setFrequency(SearchData.Frequency.KNOWN); + for (Result result : results) { + if (result.getFrequency() == SearchData.Frequency.UNKNOWN && result.getKnown() == TskData.FileKnown.KNOWN) { + result.setFrequency(SearchData.Frequency.KNOWN); } } } else { - processResultFilesForCR(files, centralRepoDb); + processResultFilesForCR(results, centralRepoDb); } } @@ -230,19 +234,22 @@ public class DiscoveryAttributes { * for. * @param centralRepoDb The central repository currently in use. */ - private void processResultFilesForCR(List files, + private void processResultFilesForCR(List results, CentralRepository centralRepoDb) { List currentFiles = new ArrayList<>(); Set hashesToLookUp = new HashSet<>(); - for (ResultFile file : files) { - if (file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) { - file.setFrequency(SearchData.Frequency.KNOWN); + for (Result result : results) { + if (result.getKnown() == TskData.FileKnown.KNOWN) { + result.setFrequency(SearchData.Frequency.KNOWN); } - if (file.getFrequency() == SearchData.Frequency.UNKNOWN - && file.getFirstInstance().getMd5Hash() != null - && !file.getFirstInstance().getMd5Hash().isEmpty()) { - hashesToLookUp.add(file.getFirstInstance().getMd5Hash()); - currentFiles.add(file); + if (result.getType() != SearchData.Type.DOMAIN) { + ResultFile file = (ResultFile) result; + if (file.getFrequency() == SearchData.Frequency.UNKNOWN + && file.getFirstInstance().getMd5Hash() != null + && !file.getFirstInstance().getMd5Hash().isEmpty()) { + hashesToLookUp.add(file.getFirstInstance().getMd5Hash()); + currentFiles.add(file); + } } if (hashesToLookUp.size() >= BATCH_SIZE) { computeFrequency(hashesToLookUp, currentFiles, centralRepoDb); @@ -299,20 +306,23 @@ public class DiscoveryAttributes { static class HashHitsAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.HashHitsGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) { + if (result.getType() == SearchData.Type.DOMAIN) { + return null; + } + return new DiscoveryKeyUtils.HashHitsGroupKey((ResultFile) result); } @Override - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { // Get pairs of (object ID, hash set name) for all files in the list of files that have // hash set hits. - String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(), + String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()); - HashSetNamesCallback callback = new HashSetNamesCallback(files); + HashSetNamesCallback callback = new HashSetNamesCallback(results); try { caseDb.getCaseDbAccessManager().select(selectQuery, callback); } catch (TskCoreException ex) { @@ -326,15 +336,15 @@ public class DiscoveryAttributes { */ private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - List resultFiles; + List results; /** * Create the callback. * * @param resultFiles List of files to add hash set names to */ - HashSetNamesCallback(List resultFiles) { - this.resultFiles = resultFiles; + HashSetNamesCallback(List results) { + this.results = results; } @Override @@ -342,7 +352,11 @@ public class DiscoveryAttributes { try { // Create a temporary map of object ID to ResultFile Map tempMap = new HashMap<>(); - for (ResultFile file : resultFiles) { + for (Result result : results) { + if (result.getType() == SearchData.Type.DOMAIN) { + return; + } + ResultFile file = (ResultFile) result; tempMap.put(file.getFirstInstance().getId(), file); } @@ -370,20 +384,20 @@ public class DiscoveryAttributes { static class InterestingItemAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.InterestingItemGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { + return new DiscoveryKeyUtils.InterestingItemGroupKey((ResultFile) file); } @Override - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { // Get pairs of (object ID, interesting item set name) for all files in the list of files that have // interesting file set hits. - String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), + String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()); - InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(files); + InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(results); try { caseDb.getCaseDbAccessManager().select(selectQuery, callback); } catch (TskCoreException ex) { @@ -398,7 +412,7 @@ public class DiscoveryAttributes { */ private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - List resultFiles; + List results; /** * Create the callback. @@ -406,8 +420,8 @@ public class DiscoveryAttributes { * @param resultFiles List of files to add interesting file set * names to */ - InterestingFileSetNamesCallback(List resultFiles) { - this.resultFiles = resultFiles; + InterestingFileSetNamesCallback(List results) { + this.results = results; } @Override @@ -415,7 +429,11 @@ public class DiscoveryAttributes { try { // Create a temporary map of object ID to ResultFile Map tempMap = new HashMap<>(); - for (ResultFile file : resultFiles) { + for (Result result : results) { + if (result.getType() == SearchData.Type.DOMAIN) { + return; + } + ResultFile file = (ResultFile) result; tempMap.put(file.getFirstInstance().getId(), file); } @@ -443,20 +461,20 @@ public class DiscoveryAttributes { static class ObjectDetectedAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { + return new DiscoveryKeyUtils.ObjectDetectedGroupKey((ResultFile) file); } @Override - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { // Get pairs of (object ID, object type name) for all files in the list of files that have // objects detected - String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(), + String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(), BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID()); - ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(files); + ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(results); try { caseDb.getCaseDbAccessManager().select(selectQuery, callback); } catch (TskCoreException ex) { @@ -471,15 +489,15 @@ public class DiscoveryAttributes { */ private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - List resultFiles; + List results; /** * Create the callback. * * @param resultFiles List of files to add object detected names to */ - ObjectDetectedNamesCallback(List resultFiles) { - this.resultFiles = resultFiles; + ObjectDetectedNamesCallback(List results) { + this.results = results; } @Override @@ -487,7 +505,11 @@ public class DiscoveryAttributes { try { // Create a temporary map of object ID to ResultFile Map tempMap = new HashMap<>(); - for (ResultFile file : resultFiles) { + for (Result result : results) { + if (result.getType() == SearchData.Type.DOMAIN) { + return; + } + ResultFile file = (ResultFile) result; tempMap.put(file.getFirstInstance().getId(), file); } @@ -515,20 +537,24 @@ public class DiscoveryAttributes { static class FileTagAttribute extends AttributeType { @Override - public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) { - return new DiscoveryKeyUtils.FileTagGroupKey(file); + public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) { + return new DiscoveryKeyUtils.FileTagGroupKey((ResultFile) file); } @Override - public void addAttributeToResultFiles(List files, SleuthkitCase caseDb, + public void addAttributeToResultFiles(List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { try { - for (ResultFile resultFile : files) { - List contentTags = caseDb.getContentTagsByContent(resultFile.getFirstInstance()); + for (Result result : results) { + if (result.getType() == SearchData.Type.DOMAIN) { + return; + } + ResultFile file = (ResultFile) result; + List contentTags = caseDb.getContentTagsByContent(file.getFirstInstance()); for (ContentTag tag : contentTags) { - resultFile.addTagName(tag.getName().getDisplayName()); + result.addTagName(tag.getName().getDisplayName()); } } } catch (TskCoreException ex) { @@ -625,12 +651,16 @@ public class DiscoveryAttributes { } - private static String createSetNameClause(List files, + private static String createSetNameClause(List results, int artifactTypeID, int setNameAttrID) throws DiscoveryException { // Concatenate the object IDs in the list of files String objIdList = ""; // NON-NLS - for (ResultFile file : files) { + for (Result result : results) { + if (result.getType() == SearchData.Type.DOMAIN) { + break; + } + ResultFile file = (ResultFile) result; if (!objIdList.isEmpty()) { objIdList += ","; // NON-NLS } @@ -644,7 +674,8 @@ public class DiscoveryAttributes { + "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id " + "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' " + "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' " - + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS + + "AND blackboard_artifacts.obj_id IN (" + objIdList + + ") "; // NON-NLS } private DiscoveryAttributes() { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java index f58a6eb08b..62aba44045 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java @@ -197,7 +197,7 @@ public final class DiscoveryEventUtils { */ public static final class PageRetrievedEvent { - private final List results; + private final List results; private final int page; private final Type resultType; @@ -208,7 +208,7 @@ public final class DiscoveryEventUtils { * @param page The number of the page which was retrieved. * @param results The list of files in the page retrieved. */ - public PageRetrievedEvent(Type resultType, int page, List results) { + public PageRetrievedEvent(Type resultType, int page, List results) { this.results = results; this.page = page; this.resultType = resultType; @@ -219,7 +219,7 @@ public final class DiscoveryEventUtils { * * @return The list of files in the page retrieved. */ - public List getSearchResults() { + public List getSearchResults() { return Collections.unmodifiableList(results); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java index 9eb172094f..f970a6541e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java @@ -155,11 +155,12 @@ public class DiscoveryKeyUtils { private final SearchData.FileSize fileSize; - FileSizeGroupKey(ResultFile file) { - if (file.getFileType() == SearchData.Type.VIDEO) { - fileSize = SearchData.FileSize.fromVideoSize(file.getFirstInstance().getSize()); + FileSizeGroupKey(Result file) { + ResultFile resultFile = (ResultFile) file; + if (resultFile.getFileType() == SearchData.Type.VIDEO) { + fileSize = SearchData.FileSize.fromVideoSize(resultFile.getFirstInstance().getSize()); } else { - fileSize = SearchData.FileSize.fromImageSize(file.getFirstInstance().getSize()); + fileSize = SearchData.FileSize.fromImageSize(resultFile.getFirstInstance().getSize()); } } @@ -212,8 +213,8 @@ public class DiscoveryKeyUtils { private final SearchData.Type fileType; - FileTypeGroupKey(ResultFile file) { - fileType = file.getFileType(); + FileTypeGroupKey(Result file) { + fileType = ((ResultFile) file).getFileType(); } @Override @@ -539,19 +540,19 @@ public class DiscoveryKeyUtils { @NbBundle.Messages({ "# {0} - Data source name", "# {1} - Data source ID", - "FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})", + "DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})", "# {0} - Data source ID", - "FileSearch.DataSourceGroupKey.idOnly=Data source (ID: {0})"}) - DataSourceGroupKey(ResultFile file) { - dataSourceID = file.getFirstInstance().getDataSourceObjectId(); - + "DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})"}) + DataSourceGroupKey(Result result) { + //get the id first so that it can be used when logging if necessary + dataSourceID = result.getDataSourceObjectId(); try { // The data source should be cached so this won't actually be a database query. - Content ds = file.getFirstInstance().getDataSource(); - displayName = Bundle.FileSearch_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId()); + Content ds = result.getDataSource(); + displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId()); } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS - displayName = Bundle.FileSearch_DataSourceGroupKey_idOnly(dataSourceID); + displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_idOnly(dataSourceID); } } @@ -646,7 +647,7 @@ public class DiscoveryKeyUtils { private final SearchData.Frequency frequency; - FrequencyGroupKey(ResultFile file) { + FrequencyGroupKey(Result file) { frequency = file.getFrequency(); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java index b5d51d6810..3f667c302c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSearch.java @@ -45,7 +45,7 @@ public class FileSearch { private final static Logger logger = Logger.getLogger(FileSearch.class.getName()); private static final int MAXIMUM_CACHE_SIZE = 10; - private static final Cache>> searchCache = CacheBuilder.newBuilder() + private static final Cache>> searchCache = CacheBuilder.newBuilder() .maximumSize(MAXIMUM_CACHE_SIZE) .build(); @@ -82,18 +82,18 @@ public class FileSearch { attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes()); // Run the queries for each filter - List resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb); + List results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb); // Add the data to resultFiles for any attributes needed for sorting and grouping - addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb); + addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb); // Collect everything in the search results SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod); - searchResults.add(resultFiles); + searchResults.add(results); // Sort and group the results searchResults.sortGroupsAndFiles(); - Map> resultHashMap = searchResults.toLinkedHashMap(); + Map> resultHashMap = searchResults.toLinkedHashMap(); SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod); synchronized (searchCache) { searchCache.put(searchKey, resultHashMap); @@ -125,7 +125,7 @@ public class FileSearch { Group.GroupSortingAlgorithm groupSortingType, FileSorter.SortingMethod fileSortingMethod, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { - Map> searchResults = runFileSearch(userName, filters, + Map> searchResults = runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb); LinkedHashMap groupSizes = new LinkedHashMap<>(); for (GroupKey groupKey : searchResults.keySet()) { @@ -156,7 +156,7 @@ public class FileSearch { * * @throws DiscoveryException */ - public static List getFilesInGroup(String userName, + public static List getFilesInGroup(String userName, List filters, AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, @@ -166,16 +166,16 @@ public class FileSearch { int numberOfEntries, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { //the group should be in the cache at this point - List filesInGroup = null; + List filesInGroup = null; SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod); - Map> resultsMap; + Map> resultsMap; synchronized (searchCache) { resultsMap = searchCache.getIfPresent(searchKey); } if (resultsMap != null) { filesInGroup = resultsMap.get(groupKey); } - List page = new ArrayList<>(); + List page = new ArrayList<>(); if (filesInGroup == null) { logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey); runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb); @@ -252,7 +252,7 @@ public class FileSearch { * * @throws DiscoveryException */ - private static Map> runFileSearch(String userName, + private static Map> runFileSearch(String userName, List filters, AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, @@ -268,15 +268,15 @@ public class FileSearch { attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes()); // Run the queries for each filter - List resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb); + List results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb); // Add the data to resultFiles for any attributes needed for sorting and grouping - addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb); + addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb); // Collect everything in the search results SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod); - searchResults.add(resultFiles); - Map> resultHashMap = searchResults.toLinkedHashMap(); + searchResults.add(results); + Map> resultHashMap = searchResults.toLinkedHashMap(); SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod); synchronized (searchCache) { searchCache.put(searchKey, resultHashMap); @@ -298,10 +298,10 @@ public class FileSearch { * * @throws DiscoveryException */ - private static void addAttributes(List attrs, List resultFiles, SleuthkitCase caseDb, CentralRepository centralRepoDb) + private static void addAttributes(List attrs, List results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { for (AttributeType attr : attrs) { - attr.addAttributeToResultFiles(resultFiles, caseDb, centralRepoDb); + attr.addAttributeToResultFiles(results, caseDb, centralRepoDb); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java index a97f99d8cd..f6d3e31ad0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/FileSorter.java @@ -29,9 +29,9 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Class used to sort ResultFiles using the supplied method. */ -public class FileSorter implements Comparator { +public class FileSorter implements Comparator { - private final List> comparators = new ArrayList<>(); + private final List> comparators = new ArrayList<>(); /** * Set up the sorter using the supplied sorting method. The sorting is @@ -51,7 +51,7 @@ public class FileSorter implements Comparator { comparators.add(getFileSizeComparator()); break; case BY_FILE_TYPE: - comparators.add(getFileTypeComparator()); + comparators.add(getTypeComparator()); comparators.add(getMIMETypeComparator()); break; case BY_FREQUENCY: @@ -77,11 +77,11 @@ public class FileSorter implements Comparator { } @Override - public int compare(ResultFile file1, ResultFile file2) { + public int compare(Result result1, Result result2) { int result = 0; - for (Comparator comp : comparators) { - result = comp.compare(file1, file2); + for (Comparator comp : comparators) { + result = comp.compare(result1, result2); if (result != 0) { return result; } @@ -96,8 +96,8 @@ public class FileSorter implements Comparator { * * @return -1 if file1 has the lower data source ID, 0 if equal, 1 otherwise */ - private static Comparator getDataSourceComparator() { - return (ResultFile file1, ResultFile file2) -> Long.compare(file1.getFirstInstance().getDataSourceObjectId(), file2.getFirstInstance().getDataSourceObjectId()); + private static Comparator getDataSourceComparator() { + return (Result result1, Result result2) -> Long.compare(result1.getDataSourceObjectId(), result2.getDataSourceObjectId()); } /** @@ -106,8 +106,8 @@ public class FileSorter implements Comparator { * * @return -1 if file1 has the lower FileType value, 0 if equal, 1 otherwise */ - private static Comparator getFileTypeComparator() { - return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFileType().getRanking(), file2.getFileType().getRanking()); + private static Comparator getTypeComparator() { + return (Result result1, Result result2) -> Integer.compare(result1.getType().getRanking(), result2.getType().getRanking()); } /** @@ -118,9 +118,14 @@ public class FileSorter implements Comparator { * @return -1 if file1 has the earliest combined keyword list name, 0 if * equal, 1 otherwise */ - private static Comparator getKeywordListNameComparator() { - return (ResultFile file1, ResultFile file2) -> { + private static Comparator getKeywordListNameComparator() { + return (Result result1, Result result2) -> { // Put empty lists at the bottom + if (result1.getType() == SearchData.Type.DOMAIN) { + return 0; + } + ResultFile file1 = (ResultFile) result1; + ResultFile file2 = (ResultFile) result2; if (file1.getKeywordListNames().isEmpty()) { if (file2.getKeywordListNames().isEmpty()) { return 0; @@ -142,11 +147,16 @@ public class FileSorter implements Comparator { * @return -1 if file1's path comes first alphabetically, 0 if equal, 1 * otherwise */ - private static Comparator getParentPathComparator() { + private static Comparator getParentPathComparator() { - return new Comparator() { + return new Comparator() { @Override - public int compare(ResultFile file1, ResultFile file2) { + public int compare(Result result1, Result result2) { + if (result1.getType() == SearchData.Type.DOMAIN) { + return 0; + } + ResultFile file1 = (ResultFile) result1; + ResultFile file2 = (ResultFile) result2; String file1ParentPath; try { file1ParentPath = file1.getFirstInstance().getParent().getUniquePath(); @@ -170,8 +180,8 @@ public class FileSorter implements Comparator { * * @return -1 if file1's rarity is lower than file2, 0 if equal, 1 otherwise */ - private static Comparator getFrequencyComparator() { - return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFrequency().getRanking(), file2.getFrequency().getRanking()); + private static Comparator getFrequencyComparator() { + return (Result result1, Result result2) -> Integer.compare(result1.getFrequency().getRanking(), result2.getFrequency().getRanking()); } /** @@ -180,8 +190,13 @@ public class FileSorter implements Comparator { * @return -1 if file1's MIME type comes before file2's, 0 if equal, 1 * otherwise */ - private static Comparator getMIMETypeComparator() { - return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getFirstInstance().getMIMEType(), file2.getFirstInstance().getMIMEType()); + private static Comparator getMIMETypeComparator() { + return (Result result1, Result result2) -> { + if (result1.getType() == SearchData.Type.DOMAIN) { + return 0; + } + return compareStrings(((ResultFile) result1).getFirstInstance().getMIMEType(), ((ResultFile) result2).getFirstInstance().getMIMEType()); + }; } /** @@ -189,9 +204,13 @@ public class FileSorter implements Comparator { * * @return -1 if file1 is larger than file2, 0 if equal, 1 otherwise */ - private static Comparator getFileSizeComparator() { - return (ResultFile file1, ResultFile file2) -> -1 * Long.compare(file1.getFirstInstance().getSize(), file2.getFirstInstance().getSize()) // Sort large to small - ; + private static Comparator getFileSizeComparator() { + return (Result result1, Result result2) -> { + if (result1.getType() == SearchData.Type.DOMAIN) { + return 0; + } + return -1 * Long.compare(((ResultFile) result1).getFirstInstance().getSize(), ((ResultFile) result2).getFirstInstance().getSize()); // Sort large to small + }; } /** @@ -199,8 +218,13 @@ public class FileSorter implements Comparator { * * @return -1 if file1 comes before file2, 0 if equal, 1 otherwise */ - private static Comparator getFileNameComparator() { - return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getFirstInstance().getName().toLowerCase(), file2.getFirstInstance().getName().toLowerCase()); + private static Comparator getFileNameComparator() { + return (Result result1, Result result2) -> { + if (result1.getType() == SearchData.Type.DOMAIN) { + return 0; + } + return compareStrings(((ResultFile) result1).getFirstInstance().getName().toLowerCase(), (((ResultFile) result2).getFirstInstance().getName().toLowerCase())); + }; } /** @@ -211,14 +235,21 @@ public class FileSorter implements Comparator { * * @return -1 if file1 comes before file2, 0 if equal, 1 otherwise */ - private static Comparator getDefaultComparator() { - return (ResultFile file1, ResultFile file2) -> { + private static Comparator getDefaultComparator() { + return (Result result1, Result result2) -> { // Compare file names and then object ID (to ensure a consistent sort) - int result = getFileNameComparator().compare(file1, file2); - if (result == 0) { - return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId()); + if (result1.getType() == SearchData.Type.DOMAIN) { + return getFrequencyComparator().compare(result1, result2); + } else { + ResultFile file1 = (ResultFile) result1; + ResultFile file2 = (ResultFile) result2; + int result = getFileNameComparator().compare(file1, file2); + if (result == 0) { + return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId()); + } + return result; } - return result; + }; } @@ -234,6 +265,7 @@ public class FileSorter implements Comparator { String string1 = s1 == null ? "" : s1; String string2 = s2 == null ? "" : s2; return string1.compareTo(string2); + } /** @@ -247,7 +279,7 @@ public class FileSorter implements Comparator { "FileSorter.SortingMethod.frequency.displayName=Central Repo Frequency", "FileSorter.SortingMethod.keywordlist.displayName=Keyword List Names", "FileSorter.SortingMethod.fullPath.displayName=Full Path"}) - public enum SortingMethod { + public enum SortingMethod { BY_FILE_NAME(new ArrayList<>(), Bundle.FileSorter_SortingMethod_filename_displayName()), // Sort alphabetically by file name BY_DATA_SOURCE(new ArrayList<>(), diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java b/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java index 30738df756..8c371adb5a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java @@ -30,7 +30,7 @@ public class Group implements Comparable { private final Group.GroupSortingAlgorithm groupSortingType; private final DiscoveryKeyUtils.GroupKey groupKey; - private final List files; + private final List results; private final String displayName; /** @@ -42,21 +42,23 @@ public class Group implements Comparable { public Group(Group.GroupSortingAlgorithm groupSortingType, DiscoveryKeyUtils.GroupKey groupKey) { this.groupSortingType = groupSortingType; this.groupKey = groupKey; - files = new ArrayList<>(); + results = new ArrayList<>(); this.displayName = groupKey.getDisplayName(); } /** - * Add a ResultFile to the group. Will not be sorted at this time. + * Add a Result to the group. Will not be sorted at this time. * - * @param file The ResultFile to add to the FileGroup + * @param result The Result to add to the FileGroup */ - void addFile(ResultFile file) { - if (files.contains(file)) { - ResultFile existingCopy = files.get(files.indexOf(file)); //get the copy of this which exists in the list - existingCopy.addDuplicate(file.getFirstInstance()); + void addResult(Result result) { + if (result.getType() != SearchData.Type.DOMAIN && results.contains(result)) { + //dedupe files and show instances + ResultFile existingCopy = (ResultFile)results.get(results.indexOf(result)); //get the copy of this which exists in the list + existingCopy.addDuplicate(((ResultFile)result).getFirstInstance()); } else { - files.add(file); + //Domains and non files are not being deduped currently + results.add(result); } } @@ -82,7 +84,7 @@ public class Group implements Comparable { * Sort all the files in the group */ public void sortFiles(FileSorter sorter) { - Collections.sort(files, sorter); + Collections.sort(results, sorter); } /** @@ -128,8 +130,8 @@ public class Group implements Comparable { * @return -1 if group1 should be displayed before group2, 1 otherwise */ private static int compareGroupsBySize(Group group1, Group group2) { - if (group1.getFiles().size() != group2.getFiles().size()) { - return -1 * Long.compare(group1.getFiles().size(), group2.getFiles().size()); // High to low + if (group1.getResults().size() != group2.getResults().size()) { + return -1 * Long.compare(group1.getResults().size(), group2.getResults().size()); // High to low } else { // If the groups have the same size, fall through to the BY_GROUP_NAME sorting return compareGroupsByGroupKey(group1, group2); @@ -168,8 +170,8 @@ public class Group implements Comparable { * * @return List of ResultFile objects */ - public List getFiles() { - return Collections.unmodifiableList(files); + public List getResults() { + return Collections.unmodifiableList(results); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/Result.java b/Core/src/org/sleuthkit/autopsy/discovery/search/Result.java index 5c3ede6971..5286a41b3f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/Result.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/Result.java @@ -18,9 +18,67 @@ */ package org.sleuthkit.autopsy.discovery.search; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskData; + /** * Interface implemented by all types of results. */ -public interface Result { +public abstract class Result { + private SearchData.Frequency frequency; + private final List tagNames = new ArrayList<>(); + + public abstract long getDataSourceObjectId(); + + /** + * Get the frequency of this result in the central repository. + * + * @return The Frequency enum. + */ + public SearchData.Frequency getFrequency() { + return frequency; + } + + public abstract TskData.FileKnown getKnown(); + + /** + * Set the frequency of this result in the central repository. + * + * @param frequency The frequency of the result as an enum. + */ + final public void setFrequency(SearchData.Frequency frequency) { + this.frequency = frequency; + } + + public abstract Content getDataSource() throws TskCoreException; + + public abstract SearchData.Type getType(); + + /** + * Add a tag name that matched this file. + * + * @param tagName + */ + public void addTagName(String tagName) { + if (!tagNames.contains(tagName)) { + tagNames.add(tagName); + } + + // Sort the list so the getTagNames() will be consistent regardless of the order added + Collections.sort(tagNames); + } + + /** + * Get the tag names for this file + * + * @return the tag names that matched this file. + */ + public List getTagNames() { + return Collections.unmodifiableList(tagNames); + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java index b3b03ff3e0..950c5a88e3 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java @@ -18,7 +18,34 @@ */ package org.sleuthkit.autopsy.discovery.search; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskData; + +public class ResultDomain extends Result { + + ResultDomain() { + this.setFrequency(SearchData.Frequency.UNKNOWN); + } + + @Override + public long getDataSourceObjectId() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Content getDataSource() throws TskCoreException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public TskData.FileKnown getKnown() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public SearchData.Type getType() { + return SearchData.Type.DOMAIN; + } -public class ResultDomain implements Result { - } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java index 60274310ea..59bfbf48f2 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultFile.java @@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.coreutils.Logger; import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.OTHER; import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.HashUtility; import org.sleuthkit.datamodel.Tag; @@ -40,13 +41,11 @@ import org.sleuthkit.datamodel.TskData; /** * Container for files that holds all necessary data for grouping and sorting. */ -public class ResultFile implements Result{ +public class ResultFile extends Result { private final static Logger logger = Logger.getLogger(ResultFile.class.getName()); - private SearchData.Frequency frequency; private final List keywordListNames; private final List hashSetNames; - private final List tagNames; private final List interestingSetNames; private final List objectDetectedNames; private final List instances = new ArrayList<>(); @@ -73,33 +72,13 @@ public class ResultFile implements Result{ deleted = true; } updateScoreAndDescription(abstractFile); - this.frequency = SearchData.Frequency.UNKNOWN; keywordListNames = new ArrayList<>(); hashSetNames = new ArrayList<>(); - tagNames = new ArrayList<>(); interestingSetNames = new ArrayList<>(); objectDetectedNames = new ArrayList<>(); fileType = fromMIMEtype(abstractFile.getMIMEType()); } - /** - * Get the frequency of this file in the central repository - * - * @return The Frequency enum - */ - public SearchData.Frequency getFrequency() { - return frequency; - } - - /** - * Set the frequency of this file from the central repository - * - * @param frequency The frequency of the file as an enum - */ - public void setFrequency(SearchData.Frequency frequency) { - this.frequency = frequency; - } - /** * Add an AbstractFile to the list of files which are instances of this * file. @@ -218,29 +197,6 @@ public class ResultFile implements Result{ return Collections.unmodifiableList(hashSetNames); } - /** - * Add a tag name that matched this file. - * - * @param tagName - */ - public void addTagName(String tagName) { - if (!tagNames.contains(tagName)) { - tagNames.add(tagName); - } - - // Sort the list so the getTagNames() will be consistent regardless of the order added - Collections.sort(tagNames); - } - - /** - * Get the tag names for this file - * - * @return the tag names that matched this file. - */ - public List getTagNames() { - return Collections.unmodifiableList(tagNames); - } - /** * Add an interesting file set name that matched this file. * @@ -300,7 +256,7 @@ public class ResultFile implements Result{ public String toString() { return getFirstInstance().getName() + "(" + getFirstInstance().getId() + ") - " + getFirstInstance().getSize() + ", " + getFirstInstance().getParentPath() + ", " - + getFirstInstance().getDataSourceObjectId() + ", " + frequency.toString() + ", " + + getFirstInstance().getDataSourceObjectId() + ", " + getFrequency().toString() + ", " + String.join(",", keywordListNames) + ", " + getFirstInstance().getMIMEType(); } @@ -397,4 +353,24 @@ public class ResultFile implements Result{ } return OTHER; } + + @Override + public long getDataSourceObjectId() { + return getFirstInstance().getDataSourceObjectId(); + } + + @Override + public Content getDataSource() throws TskCoreException { + return getFirstInstance().getDataSource(); + } + + @Override + public TskData.FileKnown getKnown() { + return getFirstInstance().getKnown(); + } + + @Override + public Type getType() { + return fileType; + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java index 59bf5e15d3..80def7276d 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java @@ -54,7 +54,7 @@ public class SearchFiltering { * * @return */ - static List runQueries(List filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { + static List runQueries(List filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { if (caseDb == null) { throw new DiscoveryException("Case DB parameter is null"); // NON-NLS } @@ -94,9 +94,9 @@ public class SearchFiltering { * @throws TskCoreException * @throws DiscoveryException */ - private static List getResultList(List filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws TskCoreException, DiscoveryException { + private static List getResultList(List filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws TskCoreException, DiscoveryException { // Get all matching abstract files - List resultList = new ArrayList<>(); + List resultList = new ArrayList<>(); List sqlResults = caseDb.findAllFilesWhere(combinedQuery); // If there are no results, return now @@ -329,7 +329,7 @@ public class SearchFiltering { desc += searchTerm.getSearchStr() + Bundle.SearchFiltering_ParentFilter_substring(); } if (searchTerm.isIncluded()) { - desc += Bundle.SearchFiltering_ParentFilter_included(); + desc += Bundle.SearchFiltering_ParentFilter_included(); } else { desc += Bundle.SearchFiltering_ParentFilter_excluded(); } @@ -393,7 +393,7 @@ public class SearchFiltering { * A filter for specifying keyword list names. A file must contain a keyword * from one of the given lists to pass. */ - public static class KeywordListFilter extends AbstractFilter { + public static class KeywordListFilter extends AbstractFilter { private final List listNames; @@ -514,7 +514,7 @@ public class SearchFiltering { } @Override - public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, + public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { // We have to have run some kind of SQL filter before getting to this point, @@ -528,8 +528,8 @@ public class SearchFiltering { freqAttr.addAttributeToResultFiles(currentResults, caseDb, centralRepoDb); // If the frequency matches the filter, add the file to the results - List frequencyResults = new ArrayList<>(); - for (ResultFile file : currentResults) { + List frequencyResults = new ArrayList<>(); + for (Result file : currentResults) { if (frequencies.contains(file.getFrequency())) { frequencyResults.add(file); } @@ -834,7 +834,7 @@ public class SearchFiltering { } @Override - public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, + public List applyAlternateFilter(List currentResults, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { if (centralRepoDb == null) { @@ -848,18 +848,21 @@ public class SearchFiltering { } // The matching files - List notableResults = new ArrayList<>(); + List notableResults = new ArrayList<>(); try { CorrelationAttributeInstance.Type type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID); - for (ResultFile file : currentResults) { + for (Result result : currentResults) { + ResultFile file = (ResultFile) result; + if (result.getType() == SearchData.Type.DOMAIN) { + break; + } if (file.getFirstInstance().getMd5Hash() != null && !file.getFirstInstance().getMd5Hash().isEmpty()) { - // Check if this file hash is marked as notable in the CR String value = file.getFirstInstance().getMd5Hash(); if (centralRepoDb.getCountArtifactInstancesKnownBad(type, value) > 0) { - notableResults.add(file); + notableResults.add(result); } } } @@ -927,7 +930,7 @@ public class SearchFiltering { return result; } - private SearchFiltering(){ + private SearchFiltering() { // Class should not be instantiated } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java index 176c22d652..485c5134c9 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java @@ -72,15 +72,15 @@ class SearchResults { * * @param files The list of ResultFiles to add. */ - void add(List files) { - for (ResultFile file : files) { + void add(List results) { + for (Result result : results) { // Add the file to the appropriate group, creating it if necessary - GroupKey groupKey = attrType.getGroupKey(file); + GroupKey groupKey = attrType.getGroupKey(result); if (!groupMap.containsKey(groupKey)) { groupMap.put(groupKey, new Group(groupSortingType, groupKey)); } - groupMap.get(groupKey).addFile(file); + groupMap.get(groupKey).addResult(result); } } @@ -102,25 +102,25 @@ class SearchResults { @Override public String toString() { - String result = ""; + String resultString = ""; if (groupList == null) { - return result; + return resultString; } long count = 0; for (Group group : groupList) { - result += group.getDisplayName() + "\n"; + resultString += group.getDisplayName() + "\n"; - for (ResultFile file : group.getFiles()) { - result += " " + file.toString() + "\n"; + for (Result result : group.getResults()) { + resultString += " " + result.toString() + "\n"; count++; if (count > MAX_OUTPUT_FILES) { - result += "(truncated)"; - return result; + resultString += "(truncated)"; + return resultString; } } } - return result; + return resultString; } /** @@ -129,7 +129,7 @@ class SearchResults { * @return The list of group names. */ List getGroupNamesWithCounts() { - return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getFiles().size() + ")").collect(Collectors.toList()); + return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getResults().size() + ")").collect(Collectors.toList()); } /** @@ -139,13 +139,13 @@ class SearchResults { * * @return The list of result files. */ - List getResultFilesInGroup(String groupName) { + List getResultFilesInGroup(String groupName) { if (groupName != null) { final String modifiedGroupName = groupName.replaceAll(" \\([0-9]+\\)$", ""); - java.util.Optional fileGroup = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst(); - if (fileGroup.isPresent()) { - return fileGroup.get().getFiles(); + java.util.Optional group = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst(); + if (group.isPresent()) { + return group.get().getResults(); } } return new ArrayList<>(); @@ -156,15 +156,15 @@ class SearchResults { * * @return The grouped and sorted results. */ - Map> toLinkedHashMap() throws DiscoveryException { - Map> map = new LinkedHashMap<>(); + Map> toLinkedHashMap() throws DiscoveryException { + Map> map = new LinkedHashMap<>(); // Sort the groups and files sortGroupsAndFiles(); // groupList is sorted and a LinkedHashMap will preserve that order. for (Group group : groupList) { - map.put(group.getGroupKey(), group.getFiles()); + map.put(group.getGroupKey(), group.getResults()); } return map; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java index 1e27e4e939..a1a15616e7 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryUiUtils.java @@ -232,6 +232,7 @@ final class DiscoveryUiUtils { * Helper method to display an error message when the results of the * Discovery Top component may be incomplete. */ + @NbBundle.Messages({"DiscoveryUiUtils.resultsIncomplete.text=Discovery results may be incomplete"}) static void displayErrorMessage(DiscoveryDialog dialog) { //check if modules run and assemble message try { @@ -258,7 +259,7 @@ final class DiscoveryUiUtils { messageScrollPane.setMaximumSize(new Dimension(600, 100)); messageScrollPane.setPreferredSize(new Dimension(600, 100)); messageScrollPane.setViewportView(messageTextPane); - JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE); + JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.DiscoveryUiUtils_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE); } } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java index 74fb716425..adff2a38d4 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java @@ -62,8 +62,6 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P return Case.isCaseOpen(); } - @NbBundle.Messages({"OpenDiscoveryAction.resultsIncomplete.text=Discovery results may be incomplete"}) - @Override public void performAction() { SwingUtilities.invokeLater(() -> { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java index 3a9033b08f..602c38666f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PageWorker.java @@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.discovery.search.FileSearch; import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.DiscoveryException; import org.sleuthkit.autopsy.discovery.search.FileSorter; -import org.sleuthkit.autopsy.discovery.search.ResultFile; +import org.sleuthkit.autopsy.discovery.search.Result; /** * SwingWorker to retrieve the contents of a page. @@ -52,7 +52,7 @@ final class PageWorker extends SwingWorker { private final int pageSize; private final SearchData.Type resultType; private final CentralRepository centralRepo; - private final List results = new ArrayList<>(); + private final List results = new ArrayList<>(); /** * Construct a new PageWorker.