diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java index cb44c29415..bb2e258f2e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/AbstractFilter.java @@ -29,8 +29,7 @@ import org.sleuthkit.datamodel.SleuthkitCase; public abstract class AbstractFilter { /** - * Returns part of a query on the table that can be AND-ed with - * other pieces + * Returns part of a query on the table that can be AND-ed with other pieces * * @return the SQL query or an empty string if there is no SQL query for * this filter. diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java index 68b5df4314..4acb503485 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryAttributes.java @@ -61,20 +61,20 @@ public class DiscoveryAttributes { public abstract static class AttributeType { /** - * For a given file, return the key for the group it belongs to for this - * attribute type. + * For a given Result, return the key for the group it belongs to for + * this attribute type. * - * @param file the result file to be grouped + * @param result The result to be grouped. * - * @return the key for the group this file goes in + * @return The key for the group this result goes in. */ - public abstract DiscoveryKeyUtils.GroupKey getGroupKey(Result file); + public abstract DiscoveryKeyUtils.GroupKey getGroupKey(Result result); /** * Add any extra data to the ResultFile object from this attribute. * - * @param files The list of results to enhance - * @param caseDb The case database + * @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. * @@ -86,7 +86,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by file size + * Attribute for grouping/sorting by file size. */ public static class FileSizeAttribute extends AttributeType { @@ -97,7 +97,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by parent path + * Attribute for grouping/sorting by parent path. */ public static class ParentPathAttribute extends AttributeType { @@ -108,7 +108,7 @@ public class DiscoveryAttributes { } /** - * Default attribute used to make one group + * Default attribute used to make one group. */ static class NoGroupingAttribute extends AttributeType { @@ -119,7 +119,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by data source + * Attribute for grouping/sorting by data source. */ static class DataSourceAttribute extends AttributeType { @@ -130,7 +130,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by file type + * Attribute for grouping/sorting by file type. */ static class FileTypeAttribute extends AttributeType { @@ -141,7 +141,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by keyword lists + * Attribute for grouping/sorting by keyword lists. */ static class KeywordListAttribute extends AttributeType { @@ -179,7 +179,7 @@ public class DiscoveryAttributes { /** * Create the callback. * - * @param resultFiles List of files to add keyword list names to + * @param resultFiles List of files to add keyword list names to. */ SetKeywordListNamesCallback(List resultFiles) { this.resultFiles = resultFiles; @@ -217,7 +217,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by frequency in the central repository + * Attribute for grouping/sorting by frequency in the central repository. */ static class FrequencyAttribute extends AttributeType { @@ -294,11 +294,18 @@ public class DiscoveryAttributes { } } + /** + * Query to get the frequency of a domain. + * + * @param domainsToQuery List of domains to check the frequency of. + * @param centralRepository The central repository to query. + * + * @throws DiscoveryException + */ private static void queryDomainFrequency(List domainsToQuery, CentralRepository centralRepository) throws DiscoveryException { if (domainsToQuery.isEmpty()) { return; } - try { final Map> resultDomainTable = new HashMap<>(); final StringJoiner joiner = new StringJoiner(", "); @@ -334,11 +341,19 @@ public class DiscoveryAttributes { } } + /** + * Callback to get the frequency of domain. + */ private static class DomainFrequencyCallback implements InstanceTableCallback { private final Map> domainLookup; private SQLException sqlCause; + /** + * Construct a new DomainFrequencyCallback. + * + * @param domainLookup The map to get domain from. + */ private DomainFrequencyCallback(Map> domainLookup) { this.domainLookup = domainLookup; } @@ -360,6 +375,11 @@ public class DiscoveryAttributes { } } + /** + * Get the SQL exception if one occurred during this callback. + * + * @return + */ SQLException getCause() { return this.sqlCause; } @@ -373,6 +393,11 @@ public class DiscoveryAttributes { private final List files; + /** + * Construct a new FrequencyCallback. + * + * @param resultFiles List of files to add hash set names to. + */ private FrequencyCallback(List files) { this.files = new ArrayList<>(files); } @@ -404,7 +429,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by hash set lists + * Attribute for grouping/sorting by hash set lists. */ static class HashHitsAttribute extends AttributeType { @@ -444,7 +469,7 @@ public class DiscoveryAttributes { /** * Create the callback. * - * @param resultFiles List of files to add hash set names to + * @param resultFiles List of files to add hash set names to. */ HashSetNamesCallback(List results) { this.results = results; @@ -482,7 +507,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by interesting item set lists + * Attribute for grouping/sorting by interesting item set lists. */ static class InterestingItemAttribute extends AttributeType { @@ -521,7 +546,7 @@ public class DiscoveryAttributes { * Create the callback. * * @param resultFiles List of files to add interesting file set - * names to + * names to. */ InterestingFileSetNamesCallback(List results) { this.results = results; @@ -581,12 +606,12 @@ public class DiscoveryAttributes { } } - + /** * Attribute for grouping/sorting by number of visits. */ static class NumberOfVisitsAttribute extends AttributeType { - + @Override public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) { return new DiscoveryKeyUtils.NumberOfVisitsGroupKey(result); @@ -594,7 +619,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by objects detected + * Attribute for grouping/sorting by objects detected. */ static class ObjectDetectedAttribute extends AttributeType { @@ -632,7 +657,7 @@ public class DiscoveryAttributes { /** * Create the callback. * - * @param resultFiles List of files to add object detected names to + * @param resultFiles List of files to add object detected names to. */ ObjectDetectedNamesCallback(List results) { this.results = results; @@ -670,7 +695,7 @@ public class DiscoveryAttributes { } /** - * Attribute for grouping/sorting by tag name + * Attribute for grouping/sorting by tag name. */ static class FileTagAttribute extends AttributeType { @@ -737,6 +762,14 @@ public class DiscoveryAttributes { private final AttributeType attributeType; private final String displayName; + /** + * Construct a new GroupingAttributeType enum value. + * + * @param attributeType The type of attribute this enum value was + * constructed for. + * @param displayName The display name for this grouping attribute + * type. + */ GroupingAttributeType(AttributeType attributeType, String displayName) { this.attributeType = attributeType; this.displayName = displayName; @@ -747,6 +780,11 @@ public class DiscoveryAttributes { return displayName; } + /** + * Get the type of attribute this enum value was constructed for. + * + * @return The type of attribute this enum value was constructed for. + */ public AttributeType getAttributeType() { return attributeType; } @@ -774,8 +812,9 @@ public class DiscoveryAttributes { * Computes the CR frequency of all the given hashes and updates the list of * files. * - * @param hashesToLookUp Hashes to find the frequency of - * @param currentFiles List of files to update with frequencies + * @param hashesToLookUp Hashes to find the frequency of. + * @param currentFiles List of files to update with frequencies. + * @param centralRepoDb The central repository being used. */ private static void computeFrequency(Set hashesToLookUp, List currentFiles, CentralRepository centralRepoDb) { @@ -804,6 +843,19 @@ public class DiscoveryAttributes { } + /** + * Private helper method to create a set name clause to be used in queries. + * + * @param results The list of results to create the set name clause + * for. + * @param artifactTypeID The Blackboard Artifact type ID for the artifact + * type. + * @param setNameAttrID The set name attribute id. + * + * @return The String to use as a set name clause in queries. + * + * @throws DiscoveryException + */ private static String createSetNameClause(List results, int artifactTypeID, int setNameAttrID) throws DiscoveryException { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java index 88ff2efc38..67c69904fa 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryEventUtils.java @@ -57,19 +57,18 @@ public final class DiscoveryEventUtils { private final Type type; /** - * Construct a new SearchStartedEvent + * Construct a new SearchStartedEvent. * - * @param type The type of file the search event is for. + * @param type The type of result the search event is for. */ public SearchStartedEvent(Type type) { this.type = type; } - /** - * Get the type of file the search is being performed for. + * Get the type of result the search is being performed for. * - * @return The type of files being searched for. + * @return The type of results being searched for. */ public Type getType() { return type; @@ -105,7 +104,9 @@ public final class DiscoveryEventUtils { } /** - * @return the instances + * Get the list of AbstractFiles for the instances list. + * + * @return The list of AbstractFiles for the instances list. */ public List getInstances() { return Collections.unmodifiableList(instances); @@ -121,7 +122,7 @@ public final class DiscoveryEventUtils { private final List searchFilters; private final DiscoveryAttributes.AttributeType groupingAttribute; private final Group.GroupSortingAlgorithm groupSort; - private final ResultsSorter.SortingMethod fileSortMethod; + private final ResultsSorter.SortingMethod sortMethod; /** * Construct a new SearchCompleteEvent, @@ -132,16 +133,16 @@ public final class DiscoveryEventUtils { * search. * @param groupingAttribute The grouping attribute used by the search. * @param groupSort The sorting algorithm used for groups. - * @param fileSortMethod The sorting method used for files. + * @param sortMethod The sorting method used for results. */ public SearchCompleteEvent(Map groupMap, List searchfilters, DiscoveryAttributes.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort, - ResultsSorter.SortingMethod fileSortMethod) { + ResultsSorter.SortingMethod sortMethod) { this.groupMap = groupMap; this.searchFilters = searchfilters; this.groupingAttribute = groupingAttribute; this.groupSort = groupSort; - this.fileSortMethod = fileSortMethod; + this.sortMethod = sortMethod; } /** @@ -154,7 +155,7 @@ public final class DiscoveryEventUtils { } /** - * Get the file filters used by the search. + * Get the filters used by the search. * * @return The search filters which were used by the search. */ @@ -181,12 +182,12 @@ public final class DiscoveryEventUtils { } /** - * Get the sorting method used for files. + * Get the sorting method used for results. * - * @return The sorting method used for files. + * @return The sorting method used for results. */ - public ResultsSorter.SortingMethod getFileSort() { - return fileSortMethod; + public ResultsSorter.SortingMethod getResultSort() { + return sortMethod; } } @@ -204,9 +205,9 @@ public final class DiscoveryEventUtils { /** * Construct a new PageRetrievedEvent. * - * @param resultType The type of files which exist in the page. + * @param resultType The type of results which exist in the page. * @param page The number of the page which was retrieved. - * @param results The list of files in the page retrieved. + * @param results The list of results in the page retrieved. */ public PageRetrievedEvent(Type resultType, int page, List results) { this.results = results; @@ -215,9 +216,9 @@ public final class DiscoveryEventUtils { } /** - * Get the list of files in the page retrieved. + * Get the list of results in the page retrieved. * - * @return The list of files in the page retrieved. + * @return The list of results in the page retrieved. */ public List getSearchResults() { return Collections.unmodifiableList(results); @@ -233,9 +234,9 @@ public final class DiscoveryEventUtils { } /** - * Get the type of files which exist in the page. + * Get the type of results which exist in the page. * - * @return The type of files which exist in the page. + * @return The type of results which exist in the page. */ public Type getType() { return resultType; @@ -256,7 +257,7 @@ public final class DiscoveryEventUtils { } /** - * Event to signal that a search has been cancelled + * Event to signal that a search has been cancelled. */ public static final class SearchCancelledEvent { @@ -280,7 +281,7 @@ public final class DiscoveryEventUtils { private final List searchfilters; private final DiscoveryAttributes.AttributeType groupingAttribute; private final Group.GroupSortingAlgorithm groupSort; - private final ResultsSorter.SortingMethod fileSortMethod; + private final ResultsSorter.SortingMethod sortMethod; /** * Construct a new GroupSelectedEvent. @@ -289,29 +290,30 @@ public final class DiscoveryEventUtils { * search. * @param groupingAttribute The grouping attribute used by the search. * @param groupSort The sorting algorithm used for groups. - * @param fileSortMethod The sorting method used for files. + * @param sortMethod The sorting method used for results. * @param groupKey The key associated with the group which was * selected. - * @param groupSize The number of files in the group which was + * @param groupSize The number of results in the group which was * selected. - * @param resultType The type of files which exist in the group. + * @param resultType The type of results which exist in the + * group. */ public GroupSelectedEvent(List searchfilters, DiscoveryAttributes.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort, - ResultsSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, Type resultType) { + ResultsSorter.SortingMethod sortMethod, GroupKey groupKey, int groupSize, Type resultType) { this.searchfilters = searchfilters; this.groupingAttribute = groupingAttribute; this.groupSort = groupSort; - this.fileSortMethod = fileSortMethod; + this.sortMethod = sortMethod; this.groupKey = groupKey; this.groupSize = groupSize; this.resultType = resultType; } /** - * Get the type of files which exist in the group. + * Get the type of results which exist in the group. * - * @return The type of files which exist in the group. + * @return The type of results which exist in the group. */ public Type getResultType() { return resultType; @@ -329,9 +331,9 @@ public final class DiscoveryEventUtils { } /** - * Get the number of files in the group which was selected. + * Get the number of results in the group which was selected. * - * @return The number of files in the group which was selected. + * @return The number of results in the group which was selected. */ public int getGroupSize() { return groupSize; @@ -347,16 +349,16 @@ public final class DiscoveryEventUtils { } /** - * Get the sorting method used for files in the group. + * Get the sorting method used for results in the group. * - * @return The sorting method used for files. + * @return The sorting method used for results. */ - public ResultsSorter.SortingMethod getFileSort() { - return fileSortMethod; + public ResultsSorter.SortingMethod getResultSort() { + return sortMethod; } /** - * Get the file filters which were used by the search + * Get the result filters which were used by the search. * * @return The search filters which were used by the search. */ diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryException.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryException.java index 8616351c21..13a4f87fa0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryException.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryException.java @@ -19,7 +19,7 @@ package org.sleuthkit.autopsy.discovery.search; /** - * Exception type used for FileSearch. + * Exception type used for Discovery search. */ final public class DiscoveryException extends Exception { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java index 03427268fa..9fe4fbf946 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DiscoveryKeyUtils.java @@ -49,7 +49,7 @@ public class DiscoveryKeyUtils { private final String keyString; private final Group.GroupSortingAlgorithm groupSortingType; private final DiscoveryAttributes.AttributeType groupAttributeType; - private final ResultsSorter.SortingMethod fileSortingMethod; + private final ResultsSorter.SortingMethod sortingMethod; private final List filters; private final SleuthkitCase sleuthkitCase; private final CentralRepository centralRepository; @@ -58,21 +58,21 @@ public class DiscoveryKeyUtils { * Construct a new SearchKey with all information that defines a search. * * @param userName The name of the user performing the search. - * @param filters The FileFilters being used for the search. + * @param filters The Filters being used for the search. * @param groupAttributeType The AttributeType to group by. * @param groupSortingType The algorithm to sort the groups by. - * @param fileSortingMethod The method to sort the files by. + * @param sortingMethod The method to sort the results by. * @param sleuthkitCase The SleuthkitCase being searched. * @param centralRepository The Central Repository being searched. */ SearchKey(String userName, List filters, DiscoveryAttributes.AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, - ResultsSorter.SortingMethod fileSortingMethod, + ResultsSorter.SortingMethod sortingMethod, SleuthkitCase sleuthkitCase, CentralRepository centralRepository) { this.groupAttributeType = groupAttributeType; this.groupSortingType = groupSortingType; - this.fileSortingMethod = fileSortingMethod; + this.sortingMethod = sortingMethod; this.filters = filters; StringBuilder searchStringBuilder = new StringBuilder(); @@ -80,7 +80,7 @@ public class DiscoveryKeyUtils { for (AbstractFilter filter : filters) { searchStringBuilder.append(filter.toString()); } - searchStringBuilder.append(groupAttributeType).append(groupSortingType).append(fileSortingMethod); + searchStringBuilder.append(groupAttributeType).append(groupSortingType).append(sortingMethod); keyString = searchStringBuilder.toString(); this.sleuthkitCase = sleuthkitCase; this.centralRepository = centralRepository; @@ -89,13 +89,19 @@ public class DiscoveryKeyUtils { /** * Construct a SearchKey without a SleuthkitCase or CentralRepositry * instance. + * + * @param userName The name of the user performing the search. + * @param filters The Filters being used for the search. + * @param groupAttributeType The AttributeType to group by. + * @param groupSortingType The algorithm to sort the groups by. + * @param sortingMethod The method to sort the results by. */ SearchKey(String userName, List filters, DiscoveryAttributes.AttributeType groupAttributeType, Group.GroupSortingAlgorithm groupSortingType, - ResultsSorter.SortingMethod fileSortingMethod) { + ResultsSorter.SortingMethod sortingMethod) { this(userName, filters, groupAttributeType, groupSortingType, - fileSortingMethod, null, null); + sortingMethod, null, null); } @Override @@ -166,18 +172,28 @@ public class DiscoveryKeyUtils { } /** - * Get the fileSorting + * Get the SortingMethod for this key. * - * @return + * @return The SortingMethod for this key. */ ResultsSorter.SortingMethod getFileSortingMethod() { - return fileSortingMethod; + return sortingMethod; } + /** + * Get the case database for this key. + * + * @return The case database for this key. + */ SleuthkitCase getSleuthkitCase() { return this.sleuthkitCase; } + /** + * Get the central repository for this key. + * + * @return The central repository for this key. + */ CentralRepository getCentralRepository() { return this.centralRepository; } @@ -199,7 +215,7 @@ public class DiscoveryKeyUtils { /** * Subclasses must implement equals(). * - * @param otherKey + * @param otherKey The GroupKey to compare to this key. * * @return true if the keys are equal, false otherwise */ @@ -209,7 +225,7 @@ public class DiscoveryKeyUtils { /** * Subclasses must implement hashCode(). * - * @return the hash code + * @return The hash code for the GroupKey. */ @Override abstract public int hashCode(); @@ -219,9 +235,9 @@ public class DiscoveryKeyUtils { * case where two different GroupKey subclasses are compared against * each other. Use a lexicographic comparison on the class names. * - * @param otherGroupKey The other group key + * @param otherGroupKey The other group key. * - * @return result of alphabetical comparison on the class name + * @return Result of alphabetical comparison on the class name. */ int compareClassNames(GroupKey otherGroupKey) { return this.getClass().getName().compareTo(otherGroupKey.getClass().getName()); @@ -234,12 +250,17 @@ public class DiscoveryKeyUtils { } /** - * Key representing a file size group + * Key representing a file size group. */ static class FileSizeGroupKey extends GroupKey { private final SearchData.FileSize fileSize; + /** + * Construct a new FileSizeGroupKey. + * + * @param file The file to create the group key for. + */ FileSizeGroupKey(Result file) { ResultFile resultFile = (ResultFile) file; if (resultFile.getFileType() == SearchData.Type.VIDEO) { @@ -284,7 +305,9 @@ public class DiscoveryKeyUtils { } /** - * @return the fileSize + * The size of the file. + * + * @return The size of the file. */ SearchData.FileSize getFileSize() { return fileSize; @@ -292,12 +315,17 @@ public class DiscoveryKeyUtils { } /** - * Key representing a file type group + * Key representing a file type group. */ static class FileTypeGroupKey extends GroupKey { private final SearchData.Type fileType; + /** + * Construct a new FileTypeGroupKey. + * + * @param file The file to create the group key for. + */ FileTypeGroupKey(Result file) { fileType = ((ResultFile) file).getFileType(); } @@ -337,7 +365,9 @@ public class DiscoveryKeyUtils { } /** - * @return the fileType + * Get the type of file the group exists for. + * + * @return The type of file the group exists for. */ SearchData.Type getFileType() { return fileType; @@ -345,18 +375,22 @@ public class DiscoveryKeyUtils { } /** - * Key representing a keyword list group + * Key representing a keyword list group. */ static class KeywordListGroupKey extends GroupKey { private final List keywordListNames; private final String keywordListNamesString; + /** + * Construct a new KeywordListGroupKey. + * + * @param file The file to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None"}) KeywordListGroupKey(ResultFile file) { keywordListNames = file.getKeywordListNames(); - if (keywordListNames.isEmpty()) { keywordListNamesString = Bundle.DiscoveryKeyUtils_KeywordListGroupKey_noKeywords(); } else { @@ -411,14 +445,20 @@ public class DiscoveryKeyUtils { } /** - * @return the keywordListNames + * Get the list of keywords this group is for. + * + * @return The list of keywords this group is for. */ List getKeywordListNames() { return Collections.unmodifiableList(keywordListNames); } /** - * @return the keywordListNamesString + * Get the string which represents the keyword names represented by this + * group key. + * + * @return The string which represents the keyword names represented by + * this group key. */ String getKeywordListNamesString() { return keywordListNamesString; @@ -426,13 +466,18 @@ public class DiscoveryKeyUtils { } /** - * Key representing a file tag group + * Key representing a file tag group. */ static class FileTagGroupKey extends GroupKey { private final List tagNames; private final String tagNamesString; + /** + * Construct a new FileTagGroupKey. + * + * @param file The file to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.FileTagGroupKey.noSets=None"}) FileTagGroupKey(ResultFile file) { @@ -477,11 +522,9 @@ public class DiscoveryKeyUtils { if (otherKey == this) { return true; } - if (!(otherKey instanceof FileTagGroupKey)) { return false; } - FileTagGroupKey otherFileTagGroupKey = (FileTagGroupKey) otherKey; return getTagNamesString().equals(otherFileTagGroupKey.getTagNamesString()); } @@ -492,14 +535,20 @@ public class DiscoveryKeyUtils { } /** - * @return the tagNames + * Get the list of tag names which are represented by this group. + * + * @return The list of tag names which are represented by this group. */ List getTagNames() { return Collections.unmodifiableList(tagNames); } /** - * @return the tagNamesString + * Get the String representation of the tags which are represented by + * this group. + * + * @return The String representation of the tags which are represented + * by this group. */ String getTagNamesString() { return tagNamesString; @@ -507,13 +556,18 @@ public class DiscoveryKeyUtils { } /** - * Key representing a parent path group + * Key representing a parent path group. */ static class ParentPathGroupKey extends GroupKey { private String parentPath; private Long parentID; + /** + * Construct a new ParentPathGroupKey. + * + * @param file The file to create the group key for. + */ ParentPathGroupKey(ResultFile file) { Content parent; try { @@ -600,14 +654,18 @@ public class DiscoveryKeyUtils { } /** - * @return the parentPath + * Get the parent path this group is for. + * + * @return The parent path this group is for as a String. */ String getParentPath() { return parentPath; } /** - * @return the parentID + * Get the object ID of the parent object. + * + * @return The object ID of the parent object. */ Long getParentID() { return parentID; @@ -615,13 +673,18 @@ public class DiscoveryKeyUtils { } /** - * Key representing a data source group + * Key representing a data source group. */ static class DataSourceGroupKey extends GroupKey { private final long dataSourceID; private String displayName; + /** + * Construct a new DataSourceGroupKey. + * + * @param result The Result to create the group key for. + */ @NbBundle.Messages({ "# {0} - Data source name", "# {1} - Data source ID", @@ -676,7 +739,9 @@ public class DiscoveryKeyUtils { } /** - * @return the dataSourceID + * Get the object ID of the data source. + * + * @return The object ID of the data source. */ long getDataSourceID() { return dataSourceID; @@ -689,6 +754,9 @@ public class DiscoveryKeyUtils { */ static class NoGroupingGroupKey extends GroupKey { + /** + * Constructor for dummy group which puts all files together. + */ NoGroupingGroupKey() { // Nothing to save - all files will get the same GroupKey } @@ -726,14 +794,19 @@ public class DiscoveryKeyUtils { } /** - * Key representing a central repository frequency group + * Key representing a central repository frequency group. */ static class FrequencyGroupKey extends GroupKey { private final SearchData.Frequency frequency; - FrequencyGroupKey(Result file) { - frequency = file.getFrequency(); + /** + * Construct a new FrequencyGroupKey. + * + * @param result The Result to create the group key for. + */ + FrequencyGroupKey(Result result) { + frequency = result.getFrequency(); } @Override @@ -771,7 +844,9 @@ public class DiscoveryKeyUtils { } /** - * @return the frequency + * Get the frequency which the group is for. + * + * @return The frequency which the group is for. */ SearchData.Frequency getFrequency() { return frequency; @@ -779,13 +854,18 @@ public class DiscoveryKeyUtils { } /** - * Key representing a hash hits group + * Key representing a hash hits group. */ static class HashHitsGroupKey extends GroupKey { private final List hashSetNames; private final String hashSetNamesString; + /** + * Construct a new HashHitsGroupKey. + * + * @param file The file to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None"}) HashHitsGroupKey(ResultFile file) { @@ -845,14 +925,18 @@ public class DiscoveryKeyUtils { } /** - * @return the hashSetNames + * Get the list of hash set names the group is for. + * + * @return The list of hash set names the group is for. */ List getHashSetNames() { return Collections.unmodifiableList(hashSetNames); } /** - * @return the hashSetNamesString + * Get the String representation of the list of hash set names. + * + * @return The String representation of the list of hash set names. */ String getHashSetNamesString() { return hashSetNamesString; @@ -860,13 +944,18 @@ public class DiscoveryKeyUtils { } /** - * Key representing a interesting item set group + * Key representing a interesting item set group. */ static class InterestingItemGroupKey extends GroupKey { private final List interestingItemSetNames; private final String interestingItemSetNamesString; + /** + * Construct a new InterestingItemGroupKey. + * + * @param file The file to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None"}) InterestingItemGroupKey(ResultFile file) { @@ -926,14 +1015,20 @@ public class DiscoveryKeyUtils { } /** - * @return the interestingItemSetNames + * Get the list of interesting item set names the group is for. + * + * @return The list of interesting item set names the group is for. */ List getInterestingItemSetNames() { return Collections.unmodifiableList(interestingItemSetNames); } /** - * @return the interestingItemSetNamesString + * Get the String representation of the interesting item set names the + * group is for. + * + * @return The String representation of the interesting item set names + * the group is for. */ String getInterestingItemSetNamesString() { return interestingItemSetNamesString; @@ -948,6 +1043,11 @@ public class DiscoveryKeyUtils { private final Long epochDate; private final String dateNameString; + /** + * Construct a new MostRecentActivityDateGroupKey. + * + * @param result The Result to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.MostRecentActivityDateGroupKey.noDate=No Date Available"}) MostRecentActivityDateGroupKey(Result result) { @@ -1018,7 +1118,7 @@ public class DiscoveryKeyUtils { /** * Get the name which identifies this group. * - * @return The dateNameString + * @return The dateNameString. */ String getDateNameString() { return dateNameString; @@ -1033,6 +1133,11 @@ public class DiscoveryKeyUtils { private final Long epochDate; private final String dateNameString; + /** + * Construct a new FirstActivityDateGroupKey. + * + * @param result The Result to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.FirstActivityDateGroupKey.noDate=No Date Available"}) FirstActivityDateGroupKey(Result result) { @@ -1103,21 +1208,26 @@ public class DiscoveryKeyUtils { /** * Get the name which identifies this group. * - * @return The dateNameString + * @return The dateNameString. */ String getDateNameString() { return dateNameString; } } - + /** * Key representing the number of visits. */ static class NumberOfVisitsGroupKey extends GroupKey { - + private final String displayName; private final Long visits; - + + /** + * Construct a new NumberOfVisitsGroupKey. + * + * @param result The Result to create the group key for. + */ @NbBundle.Messages({ "# {0} - totalVisits", "DiscoveryKeyUtils.NumberOfVisitsGroupKey.displayName={0} visits", @@ -1135,21 +1245,26 @@ public class DiscoveryKeyUtils { visits = -1L; } } - + @Override String getDisplayName() { return displayName; } - + @Override public int hashCode() { return Objects.hash(displayName); } - + + /** + * Get the number of visits this group is for. + * + * @return The number of visits this group is for. + */ Long getVisits() { return visits; } - + @Override public boolean equals(Object otherKey) { if (otherKey == this) { @@ -1163,7 +1278,7 @@ public class DiscoveryKeyUtils { NumberOfVisitsGroupKey visitsKey = (NumberOfVisitsGroupKey) otherKey; return visits.equals(visitsKey.getVisits()); } - + @Override public int compareTo(GroupKey otherGroupKey) { if (otherGroupKey instanceof NumberOfVisitsGroupKey) { @@ -1176,18 +1291,22 @@ public class DiscoveryKeyUtils { } /** - * Key representing an object detected group + * Key representing an object detected group. */ static class ObjectDetectedGroupKey extends GroupKey { private final List objectDetectedNames; private final String objectDetectedNamesString; + /** + * Construct a new ObjectDetectedGroupKey. + * + * @param file The file to create the group key for. + */ @NbBundle.Messages({ "DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None"}) ObjectDetectedGroupKey(ResultFile file) { objectDetectedNames = file.getObjectDetectedNames(); - if (objectDetectedNames.isEmpty()) { objectDetectedNamesString = Bundle.DiscoveryKeyUtils_ObjectDetectedGroupKey_noSets(); } else { @@ -1242,14 +1361,20 @@ public class DiscoveryKeyUtils { } /** - * @return the objectDetectedNames + * Get the list of object detected names for this group. + * + * @return The list of object detected names for this group. */ List getObjectDetectedNames() { return Collections.unmodifiableList(objectDetectedNames); } /** - * @return the objectDetectedNamesString + * Get the String representation of the object detected names for this + * group. + * + * @return The String representation of the object detected names for + * this group. */ String getObjectDetectedNamesString() { return objectDetectedNamesString; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearch.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearch.java index be1b04ed1b..c616ba12a8 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearch.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearch.java @@ -32,34 +32,45 @@ import org.sleuthkit.datamodel.SleuthkitCase; * Main class to perform the domain search. */ public class DomainSearch { - + private final DomainSearchCache searchCache; private final DomainSearchThumbnailCache thumbnailCache; - + + /** + * Construct a new DomainSearch object. + */ public DomainSearch() { this(new DomainSearchCache(), new DomainSearchThumbnailCache()); } - + + /** + * Construct a new DomainSearch object with an existing DomainSearchCache + * and DomainSearchThumbnailCache. + * + * @param cache The DomainSearchCache to use for this DomainSearch. + * @param thumbnailCache The DomainSearchThumnailCache to use for this + * DomainSearch. + */ DomainSearch(DomainSearchCache cache, DomainSearchThumbnailCache thumbnailCache) { this.searchCache = cache; this.thumbnailCache = thumbnailCache; } - + /** * Run the domain search to get the group keys and sizes. Clears cache of * search results, caching new results for access at later time. * * @param userName The name of the user performing the search. - * @param filters The filters to apply - * @param groupAttributeType The attribute to use for grouping - * @param groupSortingType The method to use to sort the groups + * @param filters The filters to apply. + * @param groupAttributeType The attribute to use for grouping. + * @param groupSortingType The method to use to sort the groups. * @param domainSortingMethod The method to use to sort the domains within - * the groups - * @param caseDb The case database + * the groups. + * @param caseDb The case database. * @param centralRepoDb The central repository database. Can be null * if not needed. * - * @return A LinkedHashMap grouped and sorted according to the parameters + * @return A LinkedHashMap grouped and sorted according to the parameters. * * @throws DiscoveryException */ @@ -69,9 +80,9 @@ public class DomainSearch { Group.GroupSortingAlgorithm groupSortingType, ResultsSorter.SortingMethod domainSortingMethod, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { - + final Map> searchResults = searchCache.get( - userName, filters, groupAttributeType, groupSortingType, + userName, filters, groupAttributeType, groupSortingType, domainSortingMethod, caseDb, centralRepoDb); // Transform the cached results into a map of group key to group size. @@ -88,20 +99,20 @@ public class DomainSearch { * was not cached perform a search caching the groups. * * @param userName The name of the user performing the search. - * @param filters The filters to apply - * @param groupAttributeType The attribute to use for grouping - * @param groupSortingType The method to use to sort the groups + * @param filters The filters to apply. + * @param groupAttributeType The attribute to use for grouping. + * @param groupSortingType The method to use to sort the groups. * @param domainSortingMethod The method to use to sort the Domains within - * the groups + * the groups. * @param groupKey The key which uniquely identifies the group to - * get entries from - * @param startingEntry The first entry to return - * @param numberOfEntries The number of entries to return - * @param caseDb The case database + * get entries from. + * @param startingEntry The first entry to return. + * @param numberOfEntries The number of entries to return. + * @param caseDb The case database. * @param centralRepoDb The central repository database. Can be null * if not needed. * - * @return A LinkedHashMap grouped and sorted according to the parameters + * @return A LinkedHashMap grouped and sorted according to the parameters. * * @throws DiscoveryException */ @@ -112,9 +123,9 @@ public class DomainSearch { ResultsSorter.SortingMethod domainSortingMethod, GroupKey groupKey, int startingEntry, int numberOfEntries, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { - + final Map> searchResults = searchCache.get( - userName, filters, groupAttributeType, groupSortingType, + userName, filters, groupAttributeType, groupSortingType, domainSortingMethod, caseDb, centralRepoDb); final List domainsInGroup = searchResults.get(groupKey); @@ -131,11 +142,12 @@ public class DomainSearch { * Get a thumbnail representation of a domain name. See * DomainSearchThumbnailRequest for more details. * - * @param thumbnailRequest Thumbnail request for domain + * @param thumbnailRequest Thumbnail request for domain. + * * @return An Image instance or null if no thumbnail is available. * * @throws DiscoveryException If there is an error with Discovery related - * processing + * processing. */ public Image getThumbnail(DomainSearchThumbnailRequest thumbnailRequest) throws DiscoveryException { return thumbnailCache.get(thumbnailRequest); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsCache.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsCache.java index d3bb153176..41cfcc7e9b 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsCache.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsCache.java @@ -40,10 +40,11 @@ public class DomainSearchArtifactsCache { * is new, the results will be automatically loaded. * * @param request Artifact request, specifies type, Case, and domain name. - * @return A list of matching artifacts + * + * @return A list of matching artifacts. * * @throws DiscoveryException Any error that occurs during the loading - * process. + * process. */ public List get(DomainSearchArtifactsRequest request) throws DiscoveryException { try { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsRequest.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsRequest.java index 13f607eb6c..7391858981 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsRequest.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchArtifactsRequest.java @@ -31,6 +31,13 @@ public class DomainSearchArtifactsRequest { private final String domain; private final ARTIFACT_TYPE artifactType; + /** + * Construct a new DomainSearchArtifactsRequest object. + * + * @param sleuthkitCase The case database for the search. + * @param domain The domain that artifacts are being requested for. + * @param artifactType The type of artifact being requested. + */ public DomainSearchArtifactsRequest(SleuthkitCase sleuthkitCase, String domain, ARTIFACT_TYPE artifactType) { this.sleuthkitCase = sleuthkitCase; @@ -38,14 +45,29 @@ public class DomainSearchArtifactsRequest { this.artifactType = artifactType; } + /** + * Get the case database for the search. + * + * @return The case database for the search. + */ public SleuthkitCase getSleuthkitCase() { return sleuthkitCase; } + /** + * Get the domain that artifacts are being requested for. + * + * @return The domain that artifacts are being requested for. + */ public String getDomain() { return domain; } + /** + * Get the type of artifact being requested. + * + * @return The type of artifact being requested. + */ public ARTIFACT_TYPE getArtifactType() { return artifactType; } @@ -55,11 +77,9 @@ public class DomainSearchArtifactsRequest { if (other == this) { return true; } - if (!(other instanceof DomainSearchArtifactsRequest)) { return false; } - DomainSearchArtifactsRequest otherRequest = (DomainSearchArtifactsRequest) other; return this.sleuthkitCase == otherRequest.getSleuthkitCase() && this.domain.equals(otherRequest.getDomain()) diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCache.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCache.java index e7f46821a9..306a66b287 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCache.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCache.java @@ -44,6 +44,21 @@ class DomainSearchCache { /** * Get domain search results matching the given parameters. If no results * are found, the cache will automatically load them. + * + * + * @param userName The name of the user performing the search. + * @param filters The filters to apply. + * @param groupAttributeType The attribute to use for grouping. + * @param groupSortingType The method to use to sort the groups. + * @param fileSortingMethod The method to use to sort the domains within + * the groups. + * @param caseDb The case database. + * @param centralRepoDb The central repository database. Can be null if + * not needed. + * + * @return Domain search results matching the given parameters. + * + * @throws DiscoveryException */ Map> get(String userName, List filters, @@ -51,11 +66,9 @@ class DomainSearchCache { Group.GroupSortingAlgorithm groupSortingType, ResultsSorter.SortingMethod domainSortingMethod, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { - try { final SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, domainSortingMethod, caseDb, centralRepoDb); - return cache.get(searchKey); } catch (ExecutionException ex) { throw new DiscoveryException("Error fetching results from cache", ex.getCause()); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCacheLoader.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCacheLoader.java index 99101cf053..a1f795864d 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCacheLoader.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchCacheLoader.java @@ -47,17 +47,17 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Loads domain search results for cache misses. This loader is a Guava cache loader, - * which will be used in tandem with the DomainSearchCache, which is backed by a - * Guava LoadingCache. + * Loads domain search results for cache misses. This loader is a Guava cache + * loader, which will be used in tandem with the DomainSearchCache, which is + * backed by a Guava LoadingCache. */ class DomainSearchCacheLoader extends CacheLoader>> { - + @Override public Map> load(SearchKey key) throws DiscoveryException, SQLException, TskCoreException { List domainResults = getResultDomainsFromDatabase(key); - + // Apply secondary in memory filters for (AbstractFilter filter : key.getFilters()) { if (filter.useAlternateFilter()) { @@ -76,95 +76,93 @@ class DomainSearchCacheLoader extends CacheLoader getResultDomainsFromDatabase(SearchKey key) throws TskCoreException, SQLException, DiscoveryException { - + // Filters chosen in the UI are aggregated into SQL statements to be used in // the queries that follow. final Pair filterClauses = createWhereAndHavingClause(key.getFilters()); final String whereClause = filterClauses.getLeft(); final String havingClause = filterClauses.getRight(); - + // You may think of each row of this result as a TSK_DOMAIN attribute, where the parent // artifact type is within the (optional) filter and the parent artifact // had a date time attribute that was within the (optional) filter. With this // table in hand, we can simply group by domain and apply aggregate functions // to get, for example, # of downloads, # of visits in last 60, etc. - final String domainsTable = - "SELECT LOWER(MAX(value_text)) AS domain," + - " MAX(value_int64) AS date," + - " artifact_id AS parent_artifact_id," + - " MAX(artifact_type_id) AS parent_artifact_type_id " + - - "FROM blackboard_attributes " + - "WHERE " + whereClause + " " + - - "GROUP BY artifact_id " + - "HAVING " + havingClause; - + final String domainsTable + = "SELECT LOWER(MAX(value_text)) AS domain," + + " MAX(value_int64) AS date," + + " artifact_id AS parent_artifact_id," + + " MAX(artifact_type_id) AS parent_artifact_type_id " + + "FROM blackboard_attributes " + + "WHERE " + whereClause + " " + + "GROUP BY artifact_id " + + "HAVING " + havingClause; + // Needed to populate the visitsInLast60 data. final Instant currentTime = Instant.now(); final Instant sixtyDaysAgo = currentTime.minus(60, ChronoUnit.DAYS); - + // Check the group attribute, if by data source then the GROUP BY clause // should group by data source id before grouping by domain. - final AttributeType groupAttribute = key.getGroupAttributeType(); - final String groupByClause = (groupAttribute instanceof DataSourceAttribute) ? - "data_source_obj_id, domain" : "domain"; - + final AttributeType groupAttribute = key.getGroupAttributeType(); + final String groupByClause = (groupAttribute instanceof DataSourceAttribute) + ? "data_source_obj_id, domain" : "domain"; + final Optional dataSourceFilter = key.getFilters().stream() .filter(filter -> filter instanceof DataSourceFilter) .findFirst(); - + String dataSourceWhereClause = null; if (dataSourceFilter.isPresent()) { dataSourceWhereClause = dataSourceFilter.get().getWhereClause(); } - + // This query just processes the domains table, performing additional // groupings and applying aggregate functions to calculate discovery data. - final String domainsQuery = - /*SELECT */" domain," + - " MIN(date) AS activity_start," + - " MAX(date) AS activity_end," + - " SUM(CASE " + - " WHEN artifact_type_id = " + TSK_WEB_DOWNLOAD.getTypeID() + " THEN 1 " + - " ELSE 0 " + - " END) AS fileDownloads," + - " SUM(CASE " + - " WHEN artifact_type_id = " + TSK_WEB_HISTORY.getTypeID() + " THEN 1 " + - " ELSE 0 " + - " END) AS totalVisits," + - " SUM(CASE " + - " WHEN artifact_type_id = " + TSK_WEB_HISTORY.getTypeID() + " AND" + - " date BETWEEN " + sixtyDaysAgo.getEpochSecond() + " AND " + currentTime.getEpochSecond() + " THEN 1 " + - " ELSE 0 " + - " END) AS last60," + - " data_source_obj_id AS dataSource " + - - "FROM blackboard_artifacts" + - " JOIN (" + domainsTable + ") AS domains_table" + - " ON artifact_id = parent_artifact_id " + - - // Add the data source where clause here if present. - ((dataSourceWhereClause != null) ? "WHERE " + dataSourceWhereClause + " " : "") + - - "GROUP BY " + groupByClause; - + final String domainsQuery + = /* + * SELECT + */ " domain," + + " MIN(date) AS activity_start," + + " MAX(date) AS activity_end," + + " SUM(CASE " + + " WHEN artifact_type_id = " + TSK_WEB_DOWNLOAD.getTypeID() + " THEN 1 " + + " ELSE 0 " + + " END) AS fileDownloads," + + " SUM(CASE " + + " WHEN artifact_type_id = " + TSK_WEB_HISTORY.getTypeID() + " THEN 1 " + + " ELSE 0 " + + " END) AS totalVisits," + + " SUM(CASE " + + " WHEN artifact_type_id = " + TSK_WEB_HISTORY.getTypeID() + " AND" + + " date BETWEEN " + sixtyDaysAgo.getEpochSecond() + " AND " + currentTime.getEpochSecond() + " THEN 1 " + + " ELSE 0 " + + " END) AS last60," + + " data_source_obj_id AS dataSource " + + "FROM blackboard_artifacts" + + " JOIN (" + domainsTable + ") AS domains_table" + + " ON artifact_id = parent_artifact_id " + + // Add the data source where clause here if present. + ((dataSourceWhereClause != null) ? "WHERE " + dataSourceWhereClause + " " : "") + + "GROUP BY " + groupByClause; + final SleuthkitCase caseDb = key.getSleuthkitCase(); - final CaseDbAccessManager dbManager = caseDb.getCaseDbAccessManager(); - + final CaseDbAccessManager dbManager = caseDb.getCaseDbAccessManager(); + final DomainCallback domainCallback = new DomainCallback(caseDb); dbManager.select(domainsQuery, domainCallback); - + if (domainCallback.getSQLException() != null) { throw domainCallback.getSQLException(); } - + if (domainCallback.getTskCoreException() != null) { throw domainCallback.getTskCoreException(); } @@ -180,49 +178,51 @@ class DomainSearchCacheLoader extends CacheLoader createWhereAndHavingClause(List filters) { + Pair createWhereAndHavingClause(List filters) { final StringJoiner whereClause = new StringJoiner(" OR "); - final StringJoiner havingClause = new StringJoiner(" AND "); - + final StringJoiner havingClause = new StringJoiner(" AND "); + String artifactTypeFilter = null; boolean hasDateTimeFilter = false; - - for (AbstractFilter filter : filters) { + + for (AbstractFilter filter : filters) { if (filter instanceof ArtifactTypeFilter) { artifactTypeFilter = filter.getWhereClause(); } else if (!(filter instanceof DataSourceFilter) && !filter.useAlternateFilter()) { if (filter instanceof ArtifactDateRangeFilter) { hasDateTimeFilter = true; } - + whereClause.add("(" + filter.getWhereClause() + ")"); havingClause.add("SUM(CASE WHEN " + filter.getWhereClause() + " THEN 1 ELSE 0 END) > 0"); } } - + if (!hasDateTimeFilter) { whereClause.add(ArtifactDateRangeFilter.createAttributeTypeClause()); } - - String domainAttributeFilter = "attribute_type_id = " + TSK_DOMAIN.getTypeID() + - " AND value_text <> ''"; - + + String domainAttributeFilter = "attribute_type_id = " + TSK_DOMAIN.getTypeID() + + " AND value_text <> ''"; + whereClause.add("(" + domainAttributeFilter + ")"); havingClause.add("SUM(CASE WHEN " + domainAttributeFilter + " THEN 1 ELSE 0 END) > 0"); - + return Pair.of( whereClause.toString() + ((artifactTypeFilter != null) ? " AND (" + artifactTypeFilter + ")" : ""), havingClause.toString() ); } - + /** - * Callback to handle the result set of the domain query. This callback - * is responsible for mapping result set rows into ResultDomain objects - * for display. + * Callback to handle the result set of the domain query. This callback is + * responsible for mapping result set rows into ResultDomain objects for + * display. */ private class DomainCallback implements CaseDbAccessQueryCallback { @@ -230,17 +230,22 @@ class DomainSearchCacheLoader extends CacheLoader(); this.skc = skc; } - + @Override public void process(ResultSet resultSet) { try { resultSet.setFetchSize(500); - + while (resultSet.next()) { String domain = resultSet.getString("domain"); Long activityStart = resultSet.getLong("activity_start"); @@ -259,15 +264,15 @@ class DomainSearchCacheLoader extends CacheLoader getResultDomains() { return Collections.unmodifiableList(this.resultDomains); } - + + /** + * Get the SQLEception in an exception occurred. + * + * @return The SQLEception in an exception occurred. + */ private SQLException getSQLException() { return this.sqlCause; } - + + /** + * Get the TskCoreException if a SQL exception occurred. + * + * @return The TskCoreException if a tsk core exception occurred. + */ private TskCoreException getTskCoreException() { return this.coreCause; } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailCache.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailCache.java index d13a87bcef..4662c45b7b 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailCache.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailCache.java @@ -27,7 +27,7 @@ import java.util.concurrent.ExecutionException; * Caches thumbnail requests. */ public class DomainSearchThumbnailCache { - + private static final int MAXIMUM_CACHE_SIZE = 500; private static final LoadingCache cache = CacheBuilder.newBuilder() @@ -37,11 +37,14 @@ public class DomainSearchThumbnailCache { /** * Get a thumbnail for the requested domain. If the request is new, the * thumbnail will be automatically loaded. - * - * @param request Requested domain to thumbnail - * @return The thumbnail Image instance, or null if no thumbnail is available - * - * @throws DiscoveryException If any error occurs during thumbnail generation. + * + * @param request Requested domain to thumbnail. + * + * @return The thumbnail Image instance, or null if no thumbnail is + * available. + * + * @throws DiscoveryException If any error occurs during thumbnail + * generation. */ public Image get(DomainSearchThumbnailRequest request) throws DiscoveryException { try { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailLoader.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailLoader.java index 2923c35b4e..9dac2c2064 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailLoader.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailLoader.java @@ -45,33 +45,38 @@ import org.openide.util.ImageUtilities; * loaded from the DomainSearchArtifactsCache and then further analyzed. */ public class DomainSearchThumbnailLoader extends CacheLoader { - - private static final String UNSUPPORTED_IMAGE = "org/sleuthkit/autopsy/images/image-extraction-not-supported.png"; + private static final String UNSUPPORTED_IMAGE = "org/sleuthkit/autopsy/images/image-extraction-not-supported.png"; private static final String JPG_EXTENSION = "jpg"; private static final String JPG_MIME_TYPE = "image/jpeg"; private final DomainSearchArtifactsCache artifactsCache; - + + /** + * Construct a new DomainSearchThumbnailLoader. + */ public DomainSearchThumbnailLoader() { this(new DomainSearchArtifactsCache()); } + /** + * Construct a new DomainSearchThumbnailLoader with an existing + * DomainSearchArtifactsCache. + * + * @param artifactsCache The DomainSearchArtifactsCache to use for this + * DomainSearchThumnailLoader. + */ DomainSearchThumbnailLoader(DomainSearchArtifactsCache artifactsCache) { this.artifactsCache = artifactsCache; } @Override public Image load(DomainSearchThumbnailRequest thumbnailRequest) throws TskCoreException, DiscoveryException { - final SleuthkitCase caseDb = thumbnailRequest.getSleuthkitCase(); - final DomainSearchArtifactsRequest webDownloadsRequest = new DomainSearchArtifactsRequest( caseDb, thumbnailRequest.getDomain(), TSK_WEB_DOWNLOAD); - final List webDownloads = artifactsCache.get(webDownloadsRequest); final List webDownloadPictures = getJpegsFromWebDownload(caseDb, webDownloads); Collections.sort(webDownloadPictures, (file1, file2) -> Long.compare(file1.getCrtime(), file2.getCrtime())); - for (int i = webDownloadPictures.size() - 1; i >= 0; i--) { // Get the most recent image, according to creation time. final AbstractFile mostRecent = webDownloadPictures.get(i); @@ -81,47 +86,53 @@ public class DomainSearchThumbnailLoader extends CacheLoader webCacheArtifacts = artifactsCache.get(webCacheRequest); final List webCachePictures = getJpegsFromWebCache(caseDb, webCacheArtifacts); Collections.sort(webCachePictures, (file1, file2) -> Long.compare(file1.getSize(), file2.getSize())); - for (int i = webCachePictures.size() - 1; i >= 0; i--) { // Get the largest image, according to file size. final AbstractFile largest = webCachePictures.get(i); - final Image candidateThumbnail = ImageUtils.getThumbnail(largest, thumbnailRequest.getIconSize()); if (candidateThumbnail != ImageUtils.getDefaultThumbnail()) { return candidateThumbnail; } } - return ImageUtilities.loadImage(UNSUPPORTED_IMAGE, false); } /** * Finds all JPEG source files from TSK_WEB_DOWNLOAD instances. + * + * @param caseDb The case database being searched. + * @param artifacts The list of artifacts to get jpegs from. + * + * @return The list of AbstractFiles representing jpegs which were + * associated with the artifacts. + * + * @throws TskCoreException */ private List getJpegsFromWebDownload(SleuthkitCase caseDb, List artifacts) throws TskCoreException { final List jpegs = new ArrayList<>(); - for (BlackboardArtifact artifact : artifacts) { final Content sourceContent = caseDb.getContentById(artifact.getObjectID()); addIfJpeg(jpegs, sourceContent); } - return jpegs; } /** * Finds all JPEG source files from TSK_WEB_CACHE instances. + * + * @param caseDb The case database being searched. + * @param artifacts The list of artifacts to get jpegs from. + * + * @return The list of AbstractFiles representing jpegs which were + * associated with the artifacts. */ private List getJpegsFromWebCache(SleuthkitCase caseDb, List artifacts) throws TskCoreException { final BlackboardAttribute.Type TSK_PATH_ID = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH_ID); - final List jpegs = new ArrayList<>(); for (BlackboardArtifact artifact : artifacts) { final BlackboardAttribute tskPathId = artifact.getAttribute(TSK_PATH_ID); @@ -130,12 +141,15 @@ public class DomainSearchThumbnailLoader extends CacheLoader files, Content sourceContent) { if ((sourceContent instanceof AbstractFile) && !(sourceContent instanceof DataSource)) { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailRequest.java b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailRequest.java index ca2bbcdc5a..45ce299e61 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailRequest.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/DomainSearchThumbnailRequest.java @@ -22,34 +22,57 @@ import java.util.Objects; import org.sleuthkit.datamodel.SleuthkitCase; /** - * Requests a thumbnail to be generated for a given Case, domain and - * size. IconSize should be a value obtained from ImageUtils. + * Requests a thumbnail to be generated for a given Case, domain and size. + * IconSize should be a value obtained from ImageUtils. */ public class DomainSearchThumbnailRequest { - + private final SleuthkitCase sleuthkitCase; private final String domain; private final int iconSize; - - public DomainSearchThumbnailRequest(SleuthkitCase sleuthkitCase, + + /** + * Construct a new DomainSearchThumbnailRequest. + * + * @param sleuthkitCase The case database for this thumbnail request. + * @param domain The domain name for this thumbnail request. + * @param iconSize The size of icon that this thumbnail request should + * retrieve. + */ + public DomainSearchThumbnailRequest(SleuthkitCase sleuthkitCase, String domain, int iconSize) { this.sleuthkitCase = sleuthkitCase; this.domain = domain; this.iconSize = iconSize; } + /** + * Get the case database for this thumbnail request. + * + * @return The case database for this thumbnail request. + */ public SleuthkitCase getSleuthkitCase() { return sleuthkitCase; } + /** + * Get the domain name for this thumbnail request. + * + * @return The domain name for this thumbnail request. + */ public String getDomain() { return domain; } + /** + * Get the size of icon that this thumbnail request should retrieve. + * + * @return The size of icon that this thumbnail request should retrieve. + */ public int getIconSize() { return iconSize; } - + @Override public boolean equals(Object other) { if (other == this) { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java b/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java index 8bd72e649a..688c854338 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/Group.java @@ -24,7 +24,7 @@ import java.util.List; import org.openide.util.NbBundle.Messages; /** - * Class for storing files that belong to a particular group. + * Class for storing results that belong to a particular group. */ public class Group implements Comparable { @@ -34,7 +34,7 @@ public class Group implements Comparable { private final String displayName; /** - * Create a FileGroup object with its first file. + * Create a Group object with its first result. * * @param groupSortingType The method for sorting the group * @param groupKey The GroupKey for this group @@ -49,13 +49,13 @@ public class Group implements Comparable { /** * Add a Result to the group. Will not be sorted at this time. * - * @param result The Result to add to the FileGroup + * @param result The Result to add to the Group. */ 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()); + ResultFile existingCopy = (ResultFile) results.get(results.indexOf(result)); //get the copy of this which exists in the list + existingCopy.addDuplicate(((ResultFile) result).getFirstInstance()); } else { //Domains and non files are not being deduped currently results.add(result); @@ -81,9 +81,9 @@ public class Group implements Comparable { } /** - * Sort all the files in the group + * Sort all the results in the group */ - public void sortFiles(ResultsSorter sorter) { + public void sortResults(ResultsSorter sorter) { Collections.sort(results, sorter); } @@ -91,10 +91,10 @@ public class Group implements Comparable { * Compare this group to another group for sorting. Uses the algorithm * specified in groupSortingType. * - * @param otherGroup the group to compare this one to + * @param otherGroup The group to compare this one to. * * @return -1 if this group should be displayed before the other group, 1 - * otherwise + * otherwise. */ @Override public int compareTo(Group otherGroup) { @@ -109,12 +109,12 @@ public class Group implements Comparable { } /** - * Compare two groups based on the group key + * Compare two groups based on the group key. * - * @param group1 - * @param group2 + * @param group1 The first group to be compared. + * @param group2 The second group to be compared. * - * @return -1 if group1 should be displayed before group2, 1 otherwise + * @return -1 if group1 should be displayed before group2, 1 otherwise. */ private static int compareGroupsByGroupKey(Group group1, Group group2) { return group1.getGroupKey().compareTo(group2.getGroupKey()); @@ -124,10 +124,10 @@ public class Group implements Comparable { * Compare two groups based on the group size. Falls back on the group key * if the groups are the same size. * - * @param group1 - * @param group2 + * @param group1 The first group to be compared. + * @param group2 The second group to be compared. * - * @return -1 if group1 should be displayed before group2, 1 otherwise + * @return -1 if group1 should be displayed before group2, 1 otherwise. */ private static int compareGroupsBySize(Group group1, Group group2) { if (group1.getResults().size() != group2.getResults().size()) { @@ -166,9 +166,9 @@ public class Group implements Comparable { } /** - * Get the list of ResultFile objects in the group + * Get the list of Result objects in the group. * - * @return List of ResultFile objects + * @return The list of Result objects. */ public List getResults() { return Collections.unmodifiableList(results); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java index 65964c2d61..64a3c751c6 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultDomain.java @@ -26,16 +26,17 @@ import org.sleuthkit.datamodel.TskData; * Container for domains that holds all necessary data for grouping and sorting. */ public class ResultDomain extends Result { + private final String domain; private final Long activityStart; private final Long activityEnd; private final Long totalVisits; private final Long visitsInLast60; private final Long filesDownloaded; - + private final Content dataSource; private final long dataSourceId; - + /** * Create a ResultDomain from a String. * @@ -51,30 +52,61 @@ public class ResultDomain extends Result { this.totalVisits = totalVisits; this.visitsInLast60 = visitsInLast60; this.filesDownloaded = filesDownloaded; - + this.setFrequency(SearchData.Frequency.UNKNOWN); } - + + /** + * Get the domain represented as a String. + * + * @return The String representation of the domain this result is for. + */ public String getDomain() { return this.domain; } + /** + * Get the date of first activity for this domain. + * + * @return The date of first activity for this domain. + */ public Long getActivityStart() { return activityStart; } + /** + * Get the date of most recent activity for this domain. + * + * @return The date of most recent activity for this domain. + */ public Long getActivityEnd() { return activityEnd; } - + + /** + * Get the total number of visits that this domain has had. + * + * @return The total number of visits that this domain has had. + */ public Long getTotalVisits() { return totalVisits; } + /** + * Get the number of visits that this domain has had in the last 60 days. + * + * @return The number of visits that this domain has had in the last 60 + * days. + */ public Long getVisitsInLast60() { return visitsInLast60; } + /** + * Get the number of files downloaded associated with this domain. + * + * @return The number of files downloaded associated with this domain. + */ public Long getFilesDownloaded() { return filesDownloaded; } @@ -98,12 +130,12 @@ public class ResultDomain extends Result { public SearchData.Type getType() { return SearchData.Type.DOMAIN; } - + @Override public String toString() { return "[domain=" + this.domain + ", data_source=" + this.dataSourceId + ", start=" - + this.activityStart + ", end=" + this.activityEnd + ", totalVisits=" + this.totalVisits + ", visitsLast60=" - + this.visitsInLast60 + ", downloads=" + this.filesDownloaded + ", frequency=" + + this.activityStart + ", end=" + this.activityEnd + ", totalVisits=" + this.totalVisits + ", visitsLast60=" + + this.visitsInLast60 + ", downloads=" + this.filesDownloaded + ", frequency=" + this.getFrequency() + "]"; } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java index 8c5ed6cfb5..b63d86a7f9 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/ResultsSorter.java @@ -27,7 +27,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.datamodel.TskCoreException; /** - * Class used to sort ResultFiles using the supplied method. + * Class used to sort Results using the supplied method. */ public class ResultsSorter implements Comparator { @@ -35,14 +35,14 @@ public class ResultsSorter implements Comparator { /** * Set up the sorter using the supplied sorting method. The sorting is - * defined by a list of ResultFile comparators. These comparators will be - * run in order until one returns a non-zero result. + * defined by a list of Result comparators. These comparators will be run in + * order until one returns a non-zero result. * - * @param method The method that should be used to sort the files + * @param method The method that should be used to sort the results. */ public ResultsSorter(SortingMethod method) { - // Set up the primary comparators that should applied to the files + // Set up the primary comparators that should applied to the results switch (method) { case BY_DATA_SOURCE: comparators.add(getDataSourceComparator()); @@ -75,7 +75,7 @@ public class ResultsSorter implements Comparator { } // Add the default comparator to the end. This will ensure a consistent sort - // order regardless of the order the files were added to the list. + // order regardless of the order the results were added to the list. comparators.add(getDefaultComparator()); } @@ -90,36 +90,37 @@ public class ResultsSorter implements Comparator { } } - // The files are the same + // The results are the same return result; } /** - * Compare files using data source ID. Will order smallest to largest. + * Compare results using data source ID. Will order smallest to largest. * - * @return -1 if file1 has the lower data source ID, 0 if equal, 1 otherwise + * @return -1 if result1 has the lower data source ID, 0 if equal, 1 + * otherwise. */ private static Comparator getDataSourceComparator() { return (Result result1, Result result2) -> Long.compare(result1.getDataSourceObjectId(), result2.getDataSourceObjectId()); } /** - * Compare files using their FileType enum. Orders based on the ranking in - * the FileType enum. + * Compare results using their Type enum. Orders based on the ranking in the + * Type enum. * - * @return -1 if file1 has the lower FileType value, 0 if equal, 1 otherwise + * @return -1 if result1 has the lower Type value, 0 if equal, 1 otherwise. */ private static Comparator getTypeComparator() { return (Result result1, Result result2) -> Integer.compare(result1.getType().getRanking(), result2.getType().getRanking()); } - + /** * Compare files using a concatenated version of keyword list names. * Alphabetical by the list names with files with no keyword list hits going * last. * - * @return -1 if file1 has the earliest combined keyword list name, 0 if - * equal, 1 otherwise + * @return -1 if result1 has the earliest combined keyword list name, 0 if + * equal, 1 otherwise. */ private static Comparator getKeywordListNameComparator() { return (Result result1, Result result2) -> { @@ -147,8 +148,8 @@ public class ResultsSorter implements Comparator { /** * Compare files based on parent path. Order alphabetically. * - * @return -1 if file1's path comes first alphabetically, 0 if equal, 1 - * otherwise + * @return -1 if result1's path comes first alphabetically, 0 if equal, 1 + * otherwise. */ private static Comparator getParentPathComparator() { @@ -178,10 +179,11 @@ public class ResultsSorter implements Comparator { } /** - * Compare files based on number of occurrences in the central repository. + * Compare results based on number of occurrences in the central repository. * Order from most rare to least rare Frequency enum. * - * @return -1 if file1's rarity is lower than file2, 0 if equal, 1 otherwise + * @return -1 if result1's rarity is lower than result2, 0 if equal, 1 + * otherwise. */ private static Comparator getFrequencyComparator() { return (Result result1, Result result2) -> Integer.compare(result1.getFrequency().getRanking(), result2.getFrequency().getRanking()); @@ -190,8 +192,8 @@ public class ResultsSorter implements Comparator { /** * Compare files based on MIME type. Order is alphabetical. * - * @return -1 if file1's MIME type comes before file2's, 0 if equal, 1 - * otherwise + * @return -1 if result1's MIME type comes before result2's, 0 if equal, 1 + * otherwise. */ private static Comparator getMIMETypeComparator() { return (Result result1, Result result2) -> { @@ -205,7 +207,7 @@ public class ResultsSorter implements Comparator { /** * Compare files based on size. Order large to small. * - * @return -1 if file1 is larger than file2, 0 if equal, 1 otherwise + * @return -1 if result1 is larger than result2, 0 if equal, 1 otherwise. */ private static Comparator getFileSizeComparator() { return (Result result1, Result result2) -> { @@ -219,7 +221,7 @@ public class ResultsSorter implements Comparator { /** * Compare files based on file name. Order alphabetically. * - * @return -1 if file1 comes before file2, 0 if equal, 1 otherwise + * @return -1 if result1 comes before result2, 0 if equal, 1 otherwise. */ private static Comparator getFileNameComparator() { return (Result result1, Result result2) -> { @@ -232,6 +234,8 @@ public class ResultsSorter implements Comparator { /** * Sorts domain names in lexographical order, ignoring case. + * + * @return -1 if domain1 comes before domain2, 0 if equal, 1 otherwise. */ private static Comparator getDomainNameComparator() { return (Result domain1, Result domain2) -> { @@ -244,16 +248,18 @@ public class ResultsSorter implements Comparator { return compareStrings(first.getDomain().toLowerCase(), second.getDomain().toLowerCase()); }; } - + /** - * Sorts results by most recent date time + * Sorts results by most recent date time. + * + * @return -1 if domain1 comes before domain2, 0 if equal, 1 otherwise. */ private static Comparator getMostRecentDateTimeComparator() { return (Result result1, Result result2) -> { - if(result1.getType() != SearchData.Type.DOMAIN) { + if (result1.getType() != SearchData.Type.DOMAIN) { return 0; } - + ResultDomain first = (ResultDomain) result1; ResultDomain second = (ResultDomain) result2; return Long.compare(second.getActivityEnd(), first.getActivityEnd()); @@ -266,7 +272,7 @@ public class ResultsSorter implements Comparator { * include something like the object ID to ensure a consistent sorting when * the rest of the compared fields are the same. * - * @return -1 if file1 comes before file2, 0 if equal, 1 otherwise + * @return -1 if file1 comes before file2, 0 if equal, 1 otherwise. */ private static Comparator getDefaultComparator() { return (Result result1, Result result2) -> { @@ -292,7 +298,7 @@ public class ResultsSorter implements Comparator { * @param s1 * @param s2 * - * @return -1 if s1 comes before s2, 0 if equal, 1 otherwise + * @return -1 if s1 comes before s2, 0 if equal, 1 otherwise. */ private static int compareStrings(String s1, String s2) { String string1 = s1 == null ? "" : s1; @@ -334,6 +340,13 @@ public class ResultsSorter implements Comparator { private final String displayName; private final List requiredAttributes; + /** + * Construct a new SortingMethod enum value. + * + * @param attributes The list of DiscoveryAttributes required by this + * enum value. + * @param displayName The display name for this enum value. + */ SortingMethod(List attributes, String displayName) { this.requiredAttributes = attributes; this.displayName = displayName; @@ -344,23 +357,28 @@ public class ResultsSorter implements Comparator { return displayName; } + /** + * Get the list of DiscoveryAttributes required by this enum value. + * + * @return The list of DiscoveryAttributes required by this enum value. + */ public List getRequiredAttributes() { return Collections.unmodifiableList(requiredAttributes); } /** - * Get the list of enums that are valid for ordering files. + * Get the list of enum values that are valid for ordering files. * - * @return Enums that can be used to ordering files. + * @return Enum values that can be used to ordering files. */ public static List getOptionsForOrderingFiles() { return Arrays.asList(BY_FILE_SIZE, BY_FULL_PATH, BY_FILE_NAME, BY_DATA_SOURCE); } /** - * Get the list of enums that are valid for ordering files. + * Get the list of enum values that are valid for ordering files. * - * @return Enums that can be used to ordering files. + * @return Enum values that can be used to ordering files. */ public static List getOptionsForOrderingDomains() { return Arrays.asList(BY_DOMAIN_NAME, BY_DATA_SOURCE); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java index 5effd4b65d..909cfb1acd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchData.java @@ -39,7 +39,7 @@ public final class SearchData { private static final Set DOMAIN_ARTIFACT_TYPES = EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY); /** - * Enum representing how often the file occurs in the Central Repository. + * Enum representing how often the result occurs in the Central Repository. */ @NbBundle.Messages({ "SearchData.Frequency.unique.displayName=Unique (1)", @@ -60,6 +60,13 @@ public final class SearchData { private final String displayName; private final int maxOccur; + /** + * Construct a new frequency enum value. + * + * @param ranking The rank for sorting. + * @param maxOccur The max occurrences this enum value is for. + * @param displayName The display name for this enum value. + */ Frequency(int ranking, int maxOccur, String displayName) { this.ranking = ranking; this.maxOccur = maxOccur; @@ -69,7 +76,7 @@ public final class SearchData { /** * Get the rank for sorting. * - * @return the rank (lower should be displayed first) + * @return The rank (lower should be displayed first). */ public int getRanking() { return ranking; @@ -78,9 +85,9 @@ public final class SearchData { /** * Get the enum matching the given occurrence count. * - * @param count Number of times a file is in the Central Repository. + * @param count Number of times a result is in the Central Repository. * - * @return the corresponding enum + * @return The corresponding enum. */ public static Frequency fromCount(long count) { if (count <= UNIQUE.getMaxOccur()) { @@ -119,7 +126,9 @@ public final class SearchData { } /** - * @return the maxOccur + * Get the maximum number of occurrences this enum value is for. + * + * @return The maximum number of occurrences this enum value is for. */ public int getMaxOccur() { return maxOccur; @@ -127,7 +136,7 @@ public final class SearchData { } /** - * Enum representing the file size + * Enum representing the file size. */ @NbBundle.Messages({ "SearchData.FileSize.XXLARGE.displayName=XXLarge", @@ -169,6 +178,16 @@ public final class SearchData { private final String displaySize; final static long NO_MAXIMUM = -1; + /** + * Construct a new FileSize enum value. + * + * @param ranking The rank for sorting. + * @param minB The minimum size included in this enum value. + * @param maxB The maximum size included in this enum value. + * @param displayName The display name for this enum value. + * @param displaySize The size to display in association with this enum + * value. + */ FileSize(int ranking, long minB, long maxB, String displayName, String displaySize) { this.ranking = ranking; this.minBytes = minB; @@ -185,9 +204,9 @@ public final class SearchData { * Get the enum corresponding to the given file size for image files. * The file size must be strictly greater than minBytes. * - * @param size the file size + * @param size The file size. * - * @return the enum whose range contains the file size + * @return The enum whose range contains the file size. */ public static FileSize fromImageSize(long size) { if (size > XXLARGE_IMAGE.getMinBytes()) { @@ -209,9 +228,9 @@ public final class SearchData { * Get the enum corresponding to the given file size for video files. * The file size must be strictly greater than minBytes. * - * @param size the file size + * @param size The file size. * - * @return the enum whose range contains the file size + * @return The enum whose range contains the file size. */ public static FileSize fromVideoSize(long size) { if (size > XXLARGE_VIDEO.getMinBytes()) { @@ -232,7 +251,7 @@ public final class SearchData { /** * Get the upper limit of the range. * - * @return the maximum file size that will fit in this range. + * @return The maximum file size that will fit in this range. */ public long getMaxBytes() { return maxBytes; @@ -241,7 +260,7 @@ public final class SearchData { /** * Get the lower limit of the range. * - * @return the maximum file size that is not part of this range + * @return The maximum file size that is not part of this range. */ public long getMinBytes() { return minBytes; @@ -250,7 +269,7 @@ public final class SearchData { /** * Get the rank for sorting. * - * @return the rank (lower should be displayed first) + * @return The rank (lower should be displayed first). */ public int getRanking() { return ranking; @@ -261,6 +280,11 @@ public final class SearchData { return sizeGroup + displaySize; } + /** + * Get the name of the size group. For example Small. + * + * @return The name of the size group. For example Small. + */ public String getSizeGroup() { return sizeGroup; } @@ -313,6 +337,13 @@ public final class SearchData { .add("application/pdf", //NON-NLS "application/xhtml+xml").build(); //NON-NLS + /** + * Get the list of document types for which image extraction is not + * supported. + * + * @return The list of document types for which image extraction is not + * supported. + */ public static Collection getDocTypesWithoutImageExtraction() { return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES); } @@ -333,17 +364,26 @@ public final class SearchData { IMAGE(0, Bundle.SearchData_FileType_Image_displayName(), FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes(), new ArrayList<>()), AUDIO(1, Bundle.SearchData_FileType_Audio_displayName(), FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes(), new ArrayList<>()), VIDEO(2, Bundle.SearchData_FileType_Video_displayName(), FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes(), new ArrayList<>()), - EXECUTABLE(3, Bundle.SearchData_FileType_Executables_displayName(), FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes(),new ArrayList<>()), + EXECUTABLE(3, Bundle.SearchData_FileType_Executables_displayName(), FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes(), new ArrayList<>()), DOCUMENT(4, Bundle.SearchData_FileType_Documents_displayName(), DOCUMENT_MIME_TYPES, new ArrayList<>()), DOMAIN(6, Bundle.SearchData_AttributeType_Domain_displayName(), new ArrayList<>(), DOMAIN_ARTIFACT_TYPES), OTHER(5, Bundle.SearchData_FileType_Other_displayName(), new ArrayList<>(), new ArrayList<>()); - private final int ranking; // For ordering in the UI private final String displayName; private final Collection mediaTypes; private final Collection artifactTypes; + /** + * Construct a new Type enum value. + * + * @param value Integer value for comparison. + * @param displayName The display name for this type. + * @param mediaTypes The list of mime types this type is defined by + * if it is file type. + * @param artifactTypes The list of artifact types this type is defined + * by if it is an attribute type. + */ Type(int value, String displayName, Collection mediaTypes, Collection artifactTypes) { this.ranking = value; this.displayName = displayName; @@ -359,7 +399,12 @@ public final class SearchData { public Collection getMediaTypes() { return Collections.unmodifiableCollection(mediaTypes); } - + + /** + * Get the BlackboardArtifact types matching this category. + * + * @return Collection of BlackboardArtifact.ARTIFACT_TYPE objects. + */ public Collection getArtifactTypes() { return Collections.unmodifiableCollection(artifactTypes); } @@ -395,6 +440,12 @@ public final class SearchData { private final int ranking; private final String displayName; + /** + * Construct a new Score enum value. + * + * @param ranking The rank for sorting. + * @param displayName The display name for this enum value. + */ Score(int ranking, String displayName) { this.ranking = ranking; this.displayName = displayName; @@ -403,7 +454,7 @@ public final class SearchData { /** * Get the rank for sorting. * - * @return the rank (lower should be displayed first) + * @return The rank (lower should be displayed first). */ public int getRanking() { return ranking; @@ -412,7 +463,7 @@ public final class SearchData { /** * Get the list of enums that are valid for filtering. * - * @return enums that can be used to filter + * @return Enums that can be used to filter. */ public static List getOptionsForFiltering() { return Arrays.asList(NOTABLE, INTERESTING); @@ -424,6 +475,9 @@ public final class SearchData { } } + /** + * Private constructor for SearchData class. + */ private SearchData() { // Class should not be instantiated } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java index 82ed314d6d..27a2b42342 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchFiltering.java @@ -43,19 +43,19 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; /** - * Run various filters to return a subset of files from the current case. + * Run various filters to return a subset of Results from the current case. */ public class SearchFiltering { /** * Run the given filters to get a list of matching files. * - * @param filters The filters to run - * @param caseDb The case database - * @param crDb The central repo. Can be null as long as no filters need - * it. + * @param filters The filters to run. + * @param caseDb The case database. + * @param centralRepoDb The central repo. Can be null as long as no filters + * need it. * - * @return + * @return List of Results from the search performed. */ static List runQueries(List filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException { if (caseDb == null) { @@ -89,10 +89,10 @@ public class SearchFiltering { * @param filters The filters to run. * @param combinedQuery The query to get results files for. * @param caseDb The case database. - * @param crDb The central repo. Can be null as long as no filters + * @param centralRepoDb The central repo. Can be null as long as no filters * need it. * - * @return An ArrayList of ResultFiles returned by the query. + * @return An ArrayList of Results returned by the query. * * @throws TskCoreException * @throws DiscoveryException @@ -124,36 +124,42 @@ public class SearchFiltering { } return resultList; } - + /** * A filter to specify date range for artifacts, start and end times should * be in epoch seconds. */ public static class ArtifactDateRangeFilter extends AbstractFilter { - + private final Long startDate; private final Long endDate; - + // Attributes to search for date - private static List dateAttributes = - Arrays.asList( - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED - ); - + private static List dateAttributes + = Arrays.asList( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED + ); + + /** + * Construct a new ArtifactDateRangeFilter. + * + * @param startDate The first date to include results for in the search. + * @param endDate The last date to include results for in the search. + */ public ArtifactDateRangeFilter(Long startDate, Long endDate) { this.startDate = startDate; this.endDate = endDate; } - + /** - * Create a SQL clause containing the date time attribute types - * to search. + * Create a SQL clause containing the date time attribute types to + * search. */ static String createAttributeTypeClause() { StringJoiner joiner = new StringJoiner(","); - for(BlackboardAttribute.ATTRIBUTE_TYPE type : dateAttributes) { + for (BlackboardAttribute.ATTRIBUTE_TYPE type : dateAttributes) { joiner.add("\'" + type.getTypeID() + "\'"); } return "attribute_type_id IN (" + joiner.toString() + ")"; @@ -161,8 +167,8 @@ public class SearchFiltering { @Override public String getWhereClause() { - return createAttributeTypeClause() + - " AND (value_int64 BETWEEN " + startDate + " AND " + endDate + ")"; + return createAttributeTypeClause() + + " AND (value_int64 BETWEEN " + startDate + " AND " + endDate + ")"; } @Override @@ -170,14 +176,20 @@ public class SearchFiltering { return "ArtifactDateRangeFilter Stub"; } } - + /** - * A filter to specify artifact types + * A filter to specify artifact types. */ public static class ArtifactTypeFilter extends AbstractFilter { - + private final List types; - + + /** + * Construct a new ArtifactTypeFilter. + * + * @param types The list of BlackboardArtifact types to include in + * results from. + */ public ArtifactTypeFilter(List types) { this.types = types; } @@ -185,10 +197,10 @@ public class SearchFiltering { @Override public String getWhereClause() { StringJoiner joiner = new StringJoiner(","); - for(ARTIFACT_TYPE type : types) { + for (ARTIFACT_TYPE type : types) { joiner.add("\'" + type.getTypeID() + "\'"); } - + return "artifact_type_id IN (" + joiner + ")"; } @@ -196,20 +208,20 @@ public class SearchFiltering { public String getDesc() { return "ArtifactTypeFilter Stub"; } - + } /** - * A filter for specifying the file size + * A filter for specifying the file size. */ public static class SizeFilter extends AbstractFilter { private final List fileSizes; /** - * Create the SizeFilter + * Create the SizeFilter. * - * @param fileSizes the file sizes that should match + * @param fileSizes The file sizes that should match. */ public SizeFilter(List fileSizes) { this.fileSizes = fileSizes; @@ -251,7 +263,7 @@ public class SearchFiltering { /** * A utility class for the ParentFilter to store the search string and - * whether it is a full path or a substring. + * whether it is a full path or a sub-string. */ public static class ParentSearchTerm { @@ -260,11 +272,11 @@ public class SearchFiltering { private final boolean included; /** - * Create the ParentSearchTerm object + * Create the ParentSearchTerm object. * - * @param searchStr The string to search for in the file path + * @param searchStr The string to search for in the file path. * @param isFullPath True if the path should exactly match the given - * string, false to do a substring search + * string, false to do a sub-string search. * @param isIncluded True if the results must include the path, false if * the path should be excluded from the results. */ @@ -275,9 +287,9 @@ public class SearchFiltering { } /** - * Get the SQL term to search for + * Get the SQL term to search for. * - * @return The SQL for a where clause to search for a matching path + * @return The SQL for a where clause to search for a matching path. */ public String getSQLForTerm() { // TODO - these should really be prepared statements @@ -318,21 +330,31 @@ public class SearchFiltering { } /** - * @return the fullPath + * Is the search string the full path of the of the parent or is it a + * sub-string in the parent path? + * + * @return True if the search string is the full path of the parent, + * false if it is a sub-string. */ public boolean isFullPath() { return fullPath; } /** - * @return the included + * Should the search string be included in the path, or excluded from + * the path? + * + * @return True if the search string should be included, false if it + * should be excluded. */ public boolean isIncluded() { return included; } /** - * @return the searchStr + * Get the string being searched for by this filter. + * + * @return The string being searched for by this filter. */ public String getSearchStr() { return searchStr; @@ -340,16 +362,16 @@ public class SearchFiltering { } /** - * A filter for specifying parent path (either full path or substring) + * A filter for specifying parent path (either full path or substring). */ public static class ParentFilter extends AbstractFilter { private final List parentSearchTerms; /** - * Create the ParentFilter + * Create the ParentFilter. * - * @param parentSearchTerms Full paths or substrings to filter on + * @param parentSearchTerms Full paths or substrings to filter on. */ public ParentFilter(List parentSearchTerms) { this.parentSearchTerms = parentSearchTerms; @@ -417,16 +439,16 @@ public class SearchFiltering { } /** - * A filter for specifying data sources + * A filter for specifying data sources. */ public static class DataSourceFilter extends AbstractFilter { private final List dataSources; /** - * Create the DataSourceFilter + * Create the DataSourceFilter. * - * @param dataSources the data sources to filter on + * @param dataSources The data sources to filter on. */ public DataSourceFilter(List dataSources) { this.dataSources = dataSources; @@ -475,9 +497,9 @@ public class SearchFiltering { private final List listNames; /** - * Create the KeywordListFilter + * Create the KeywordListFilter. * - * @param listNames + * @param listNames The list of keywords for this filter. */ public KeywordListFilter(List listNames) { this.listNames = listNames; @@ -511,7 +533,7 @@ public class SearchFiltering { private final List categories; /** - * Create the FileTypeFilter + * Create the FileTypeFilter. * * @param categories List of file types to filter on */ @@ -520,9 +542,9 @@ public class SearchFiltering { } /** - * Create the FileTypeFilter + * Create the FileTypeFilter. * - * @param category the file type to filter on + * @param category The file type to filter on. */ public FileTypeFilter(Type category) { this.categories = new ArrayList<>(); @@ -570,9 +592,9 @@ public class SearchFiltering { private final List frequencies; /** - * Create the FrequencyFilter + * Create the FrequencyFilter. * - * @param frequencies List of frequencies that will pass the filter + * @param frequencies List of frequencies that will pass the filter. */ public FrequencyFilter(List frequencies) { this.frequencies = frequencies; @@ -640,9 +662,9 @@ public class SearchFiltering { private final List setNames; /** - * Create the HashSetFilter + * Create the HashSetFilter. * - * @param setNames + * @param setNames The hash set names for this filter. */ public HashSetFilter(List setNames) { this.setNames = setNames; @@ -678,9 +700,9 @@ public class SearchFiltering { private final List setNames; /** - * Create the InterestingFileSetFilter + * Create the InterestingFileSetFilter. * - * @param setNames + * @param setNames The interesting file set names for this filter. */ public InterestingFileSetFilter(List setNames) { this.setNames = setNames; @@ -716,9 +738,9 @@ public class SearchFiltering { private final List typeNames; /** - * Create the ObjectDetectionFilter + * Create the ObjectDetectionFilter. * - * @param typeNames + * @param typeNames The type names for this filter. */ public ObjectDetectionFilter(List typeNames) { this.typeNames = typeNames; @@ -747,16 +769,16 @@ public class SearchFiltering { /** * A filter for specifying the score. A file must have one of the given - * scores to pass + * scores to pass. */ public static class ScoreFilter extends AbstractFilter { private final List scores; /** - * Create the ObjectDetectionFilter + * Create the ScoreFilter. * - * @param typeNames + * @param scores The list of scores for this filter. */ public ScoreFilter(List scores) { this.scores = scores; @@ -831,9 +853,9 @@ public class SearchFiltering { private final List tagNames; /** - * Create the TagsFilter + * Create the TagsFilter. * - * @param tagNames + * @param tagNames The list of tag names for this filter. */ public TagsFilter(List tagNames) { this.tagNames = tagNames; @@ -975,6 +997,13 @@ public class SearchFiltering { } } + /** + * Concatenate the set names into a "," separated list. + * + * @param setNames The List of setNames to concatenate. + * + * @return The concatenated list for display. + */ @NbBundle.Messages({ "FileSearchFiltering.concatenateSetNamesForDisplay.comma=, ",}) private static String concatenateSetNamesForDisplay(List setNames) { @@ -992,9 +1021,9 @@ public class SearchFiltering { * Concatenate the set names into an "OR" separated list. This does not do * any SQL-escaping. * - * @param setNames + * @param setNames The List of setNames to concatenate. * - * @return the list to use in the SQL query + * @return The concatenated list to use in the SQL query. */ private static String concatenateNamesForSQL(List setNames) { String result = ""; // NON-NLS @@ -1007,6 +1036,9 @@ public class SearchFiltering { return result; } + /** + * Private constructor for SearchFiltering class. + */ 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 f427d97d28..8d07b03e22 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SearchResults.java @@ -76,7 +76,7 @@ class SearchResults { for (Result result : results) { // Add the file to the appropriate group, creating it if necessary GroupKey groupKey = attrType.getGroupKey(result); - + if (!groupMap.containsKey(groupKey)) { groupMap.put(groupKey, new Group(groupSortingType, groupKey)); } @@ -92,7 +92,7 @@ class SearchResults { // First sortGroupsAndFiles the files for (Group group : groupMap.values()) { - group.sortFiles(fileSorter); + group.sortResults(fileSorter); } // Now put the groups in a list and sortGroupsAndFiles them diff --git a/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java b/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java index 60e7e171ca..c258801f70 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/search/SummaryHelpers.java @@ -59,6 +59,13 @@ class SummaryHelpers { // Class should not be instantiated } + /** + * Get the default text summary for the document. + * + * @param file The file to summarize. + * + * @return The TextSummary object which is a default summary for the file. + */ static TextSummary getDefaultSummary(AbstractFile file) { Image image = null; int countOfImages = 0; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java index d3770ef5ac..3e4ab45592 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java @@ -70,7 +70,8 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel { /** * Check if this filter is configured to valid settings. * - * @return If the settings are invalid returns the error that has occurred, otherwise returns empty string. + * @return If the settings are invalid returns the error that has occurred, + * otherwise returns empty string. */ abstract String checkForError(); @@ -93,8 +94,8 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel { /** * Get the AbstractFilter which is represented by this Panel. * - * @return The AbstractFilter for the selected settings, null if the settings - * are not in use. + * @return The AbstractFilter for the selected settings, null if the + * settings are not in use. */ abstract AbstractFilter getFilter(); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java index 298789bf3b..6e8137a6ed 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java @@ -70,7 +70,6 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li secondColumnPanel.setLayout(new GridBagLayout()); } - /** * Get the type of results this filters panel is for. * @@ -127,7 +126,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li secondColumnY += constraints.gridheight; } } - + /** * Add the panels representing the two columns to the specified JSplitPane. * @@ -279,42 +278,56 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li } /** - * @return the lastSortingMethod + * Get the most recently used sorting method. + * + * @return The most recently used sorting method. */ SortingMethod getLastSortingMethod() { return lastSortingMethod; } /** - * @param lastSortingMethod the lastSortingMethod to set + * Set the most recently used sorting method. + * + * @param lastSortingMethod The most recently used sorting method. */ final void setLastSortingMethod(SortingMethod lastSortingMethod) { this.lastSortingMethod = lastSortingMethod; } /** - * @return the lastGroupingAttributeType + * Get the most recently used grouping attribute. + * + * @return The most recently used grouping attribute. */ GroupingAttributeType getLastGroupingAttributeType() { return lastGroupingAttributeType; } /** - * @param lastGroupingAttributeType the lastGroupingAttributeType to set + * Set the most recently used grouping attribute. + * + * @param lastGroupingAttributeType The most recently used grouping + * attribute. */ final void setLastGroupingAttributeType(GroupingAttributeType lastGroupingAttributeType) { this.lastGroupingAttributeType = lastGroupingAttributeType; } /** - * @return the lastGroupSortingAlg + * Get the most recently used group sorting algorithm. + * + * @return The most recently used group sorting algorithm. */ Group.GroupSortingAlgorithm getLastGroupSortingAlg() { return lastGroupSortingAlg; } /** - * @param lastGroupSortingAlg the lastGroupSortingAlg to set + * Set the group sorting algorithm that was used most recently. + * + * @param lastGroupSortingAlg The most recently used group sorting + * algorithm. */ final void setLastGroupSortingAlg(Group.GroupSortingAlgorithm lastGroupSortingAlg) { this.lastGroupSortingAlg = lastGroupSortingAlg; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form index e24e6f6a3b..522cd9b43e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.form @@ -6,9 +6,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java index 9b7525bbd1..783fd1616f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryDialog.java @@ -318,7 +318,6 @@ final class DiscoveryDialog extends javax.swing.JDialog { setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setMinimumSize(new java.awt.Dimension(600, 300)); - setPreferredSize(new java.awt.Dimension(1000, 650)); imagesButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/pictures-icon.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(imagesButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.imagesButton.text")); // NOI18N diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java index 07b01c976b..1a36ab8bce 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DiscoveryTopComponent.java @@ -81,7 +81,7 @@ public final class DiscoveryTopComponent extends TopComponent { }); rightSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { @Override - public void propertyChange(PropertyChangeEvent evt) { + public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)) { //Only change the saved location when it was a manual change by the user and not the animation or the window opening initially if ((animator == null || !animator.isRunning()) && evt.getNewValue() instanceof Integer @@ -91,7 +91,7 @@ public final class DiscoveryTopComponent extends TopComponent { } } } - }); + }); } /** diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java index cf3209146d..bce5577054 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DomainFilterPanel.java @@ -98,7 +98,6 @@ public class DomainFilterPanel extends AbstractFiltersPanel { } - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JSplitPane domainFiltersSplitPane; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java index b1791c3ff3..b40d77ef63 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/GroupListPanel.java @@ -88,7 +88,7 @@ final class GroupListPanel extends javax.swing.JPanel { searchfilters = searchCompleteEvent.getFilters(); groupingAttribute = searchCompleteEvent.getGroupingAttr(); groupSort = searchCompleteEvent.getGroupSort(); - resultSortMethod = searchCompleteEvent.getFileSort(); + resultSortMethod = searchCompleteEvent.getResultSort(); groupKeyList.setListData(groupMap.keySet().toArray(new GroupKey[groupMap.keySet().size()])); SwingUtilities.invokeLater(() -> { if (groupKeyList.getModel().getSize() > 0) { diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java index 2931a962dd..33228a6a9b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/OpenDiscoveryAction.java @@ -38,8 +38,7 @@ import org.sleuthkit.autopsy.casemodule.Case; */ @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.newpackage.OpenDiscoveryAction") @ActionReferences(value = { - @ActionReference(path = "Menu/Tools", position = 105) - , + @ActionReference(path = "Menu/Tools", position = 105), @ActionReference(path = "Toolbars/Case", position = 105)}) @ActionRegistration(displayName = "#CTL_OpenDiscoveryAction", lazy = false) @NbBundle.Messages({"CTL_OpenDiscoveryAction=Discovery"}) @@ -68,7 +67,7 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P final DiscoveryDialog discDialog = DiscoveryDialog.getDiscoveryDialogInstance(); discDialog.cancelSearch(); DiscoveryUiUtils.displayErrorMessage(discDialog); - discDialog.setVisible(true); + discDialog.setVisible(true); }); } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java index 52325da82a..2c9a4d4f41 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ResultsPanel.java @@ -127,7 +127,7 @@ final class ResultsPanel extends javax.swing.JPanel { }); //JIRA-TODO 6307 Add listener for domainSummaryViewer when 6782, 6773, and the other details area related stories are done } - + SearchData.Type getActiveType() { return resultType; } @@ -294,7 +294,7 @@ final class ResultsPanel extends javax.swing.JPanel { // Do nothing, case has been closed. return; } - + for (Result result : results) { DomainThumbnailWorker domainWorker = new DomainThumbnailWorker( currentCase, (ResultDomain) result); @@ -315,7 +315,7 @@ final class ResultsPanel extends javax.swing.JPanel { searchFilters = groupSelectedEvent.getFilters(); groupingAttribute = groupSelectedEvent.getGroupingAttr(); groupSort = groupSelectedEvent.getGroupSort(); - fileSortMethod = groupSelectedEvent.getFileSort(); + fileSortMethod = groupSelectedEvent.getResultSort(); selectedGroupKey = groupSelectedEvent.getGroupKey(); resultType = groupSelectedEvent.getResultType(); groupSize = groupSelectedEvent.getGroupSize(); @@ -839,7 +839,7 @@ final class ResultsPanel extends javax.swing.JPanel { domainWrapper.getResultDomain().getDomain(), ImageUtils.ICON_SIZE_LARGE ); - + Image thumbnail = domainSearch.getThumbnail(request); domainWrapper.setThumbnail(thumbnail); return null;