6711 move attributes out of file search class

This commit is contained in:
William Schaefer 2020-08-20 13:37:12 -04:00
parent 98e790c4e6
commit 1b73edee7d
13 changed files with 721 additions and 689 deletions

View File

@ -1,5 +1,3 @@
AttributeSearchData.AttributeType.Domain.displayName=Domain
AttributeSearchData.AttributeType.Other.displayName=Other
DiscoveryKeyUtils.FileTagGroupKey.noSets=None DiscoveryKeyUtils.FileTagGroupKey.noSets=None
DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files
FileGroup.groupSortingAlgorithm.groupName.text=Group Name FileGroup.groupSortingAlgorithm.groupName.text=Group Name
@ -26,39 +24,6 @@ FileSearch.HashHitsGroupKey.noHashHits=None
FileSearch.InterestingItemGroupKey.noSets=None FileSearch.InterestingItemGroupKey.noSets=None
FileSearch.KeywordListGroupKey.noKeywords=None FileSearch.KeywordListGroupKey.noKeywords=None
FileSearch.ObjectDetectedGroupKey.noSets=None FileSearch.ObjectDetectedGroupKey.noSets=None
FileSearchData.FileSize.100kbto1mb=: 100KB-1MB
FileSearchData.FileSize.100mbto1gb=: 100MB-1GB
FileSearchData.FileSize.10PlusGb=: 10GB+
FileSearchData.FileSize.16kbto100kb=: 16-100KB
FileSearchData.FileSize.1gbto5gb=: 1-5GB
FileSearchData.FileSize.1mbto50mb=: 1-50MB
FileSearchData.FileSize.200PlusMb=: 200MB+
FileSearchData.FileSize.500kbto100mb=: 500KB-100MB
FileSearchData.FileSize.50mbto200mb=: 50-200MB
FileSearchData.FileSize.5gbto10gb=: 5-10GB
FileSearchData.FileSize.LARGE.displayName=Large
FileSearchData.FileSize.MEDIUM.displayName=Medium
FileSearchData.FileSize.SMALL.displayName=Small
FileSearchData.FileSize.upTo16kb=: 0-16KB
FileSearchData.FileSize.upTo500kb=: 0-500KB
FileSearchData.FileSize.XLARGE.displayName=XLarge
FileSearchData.FileSize.XSMALL.displayName=XSmall
FileSearchData.FileSize.XXLARGE.displayName=XXLarge
FileSearchData.FileType.Audio.displayName=Audio
FileSearchData.FileType.Documents.displayName=Documents
FileSearchData.FileType.Executables.displayName=Executables
FileSearchData.FileType.Image.displayName=Image
FileSearchData.FileType.Other.displayName=Other/Unknown
FileSearchData.FileType.Video.displayName=Video
FileSearchData.Frequency.common.displayName=Common (11 - 100)
FileSearchData.Frequency.known.displayName=Known (NSRL)
FileSearchData.Frequency.rare.displayName=Rare (2-10)
FileSearchData.Frequency.unique.displayName=Unique (1)
FileSearchData.Frequency.unknown.displayName=Unknown
FileSearchData.Frequency.verycommon.displayName=Very Common (100+)
FileSearchData.Score.interesting.displayName=Interesting
FileSearchData.Score.notable.displayName=Notable
FileSearchData.Score.unknown.displayName=Unknown
FileSearchFiltering.concatenateSetNamesForDisplay.comma=, FileSearchFiltering.concatenateSetNamesForDisplay.comma=,
# {0} - filters # {0} - filters
FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0} FileSearchFiltering.HashSetFilter.desc=Hash set hits in set(s): {0}
@ -79,6 +44,40 @@ ResultFile.score.interestingResult.description=At least one instance of the file
ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable. ResultFile.score.notableFile.description=At least one instance of the file was recognized as notable.
ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag. ResultFile.score.notableTaggedFile.description=At least one instance of the file is tagged with a notable tag.
ResultFile.score.taggedFile.description=At least one instance of the file has been tagged. ResultFile.score.taggedFile.description=At least one instance of the file has been tagged.
SearchData.AttributeType.Domain.displayName=Domains
SearchData.FileSize.100kbto1mb=: 100KB-1MB
SearchData.FileSize.100mbto1gb=: 100MB-1GB
SearchData.FileSize.10PlusGb=: 10GB+
SearchData.FileSize.16kbto100kb=: 16-100KB
SearchData.FileSize.1gbto5gb=: 1-5GB
SearchData.FileSize.1mbto50mb=: 1-50MB
SearchData.FileSize.200PlusMb=: 200MB+
SearchData.FileSize.500kbto100mb=: 500KB-100MB
SearchData.FileSize.50mbto200mb=: 50-200MB
SearchData.FileSize.5gbto10gb=: 5-10GB
SearchData.FileSize.LARGE.displayName=Large
SearchData.FileSize.MEDIUM.displayName=Medium
SearchData.FileSize.SMALL.displayName=Small
SearchData.FileSize.upTo16kb=: 0-16KB
SearchData.FileSize.upTo500kb=: 0-500KB
SearchData.FileSize.XLARGE.displayName=XLarge
SearchData.FileSize.XSMALL.displayName=XSmall
SearchData.FileSize.XXLARGE.displayName=XXLarge
SearchData.FileType.Audio.displayName=Audio
SearchData.FileType.Documents.displayName=Documents
SearchData.FileType.Executables.displayName=Executables
SearchData.FileType.Image.displayName=Image
SearchData.FileType.Other.displayName=Other/Unknown
SearchData.FileType.Video.displayName=Video
SearchData.Frequency.common.displayName=Common (11 - 100)
SearchData.Frequency.known.displayName=Known (NSRL)
SearchData.Frequency.rare.displayName=Rare (2-10)
SearchData.Frequency.unique.displayName=Unique (1)
SearchData.Frequency.unknown.displayName=Unknown
SearchData.Frequency.verycommon.displayName=Very Common (100+)
SearchData.Score.interesting.displayName=Interesting
SearchData.Score.notable.displayName=Notable
SearchData.Score.unknown.displayName=Unknown
# {0} - Data source name # {0} - Data source name
# {1} - Data source ID # {1} - Data source ID
SearchFiltering.DataSourceFilter.datasource={0}({1}) SearchFiltering.DataSourceFilter.datasource={0}({1})

View File

@ -0,0 +1,653 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.discovery.search;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.CaseDbAccessManager;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
*
* @author wschaefer
*/
public class DiscoveryAttributes {
private final static Logger logger = Logger.getLogger(DiscoveryAttributes.class.getName());
/**
* Base class for the grouping attributes.
*/
public abstract static class AttributeType {
/**
* For a given file, return the key for the group it belongs to for this
* attribute type.
*
* @param file the result file to be grouped
*
* @return the key for the group this file goes in
*/
public abstract DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file);
/**
* Add any extra data to the ResultFile object from this attribute.
*
* @param files The list of files to enhance
* @param caseDb The case database
* @param centralRepoDb The central repository database. Can be null if
* not needed.
*
* @throws DiscoveryException
*/
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
// Default is to do nothing
}
}
/**
* Attribute for grouping/sorting by file size
*/
public static class FileSizeAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileSizeGroupKey(file);
}
}
/**
* Attribute for grouping/sorting by parent path
*/
public static class ParentPathAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.ParentPathGroupKey(file);
}
}
/**
* Default attribute used to make one group
*/
static class NoGroupingAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.NoGroupingGroupKey();
}
}
/**
* Attribute for grouping/sorting by data source
*/
static class DataSourceAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.DataSourceGroupKey(file);
}
}
/**
* Attribute for grouping/sorting by file type
*/
static class FileTypeAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileTypeGroupKey(file);
}
}
/**
* Attribute for grouping/sorting by keyword lists
*/
static class KeywordListAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.KeywordListGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, keyword list name) for all files in the list of files that have
// keyword list hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up keyword list attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the keyword list names to the list of ResultFile
* objects.
*/
private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add keyword list names to
*/
SetKeywordListNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String keywordListName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addKeywordListName(keywordListName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get keyword list names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by frequency in the central repository
*/
static class FrequencyAttribute extends AttributeType {
static final int BATCH_SIZE = 50; // Number of hashes to look up at one time
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FrequencyGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
if (centralRepoDb == null) {
for (ResultFile file : files) {
if (file.getFrequency() == SearchData.Frequency.UNKNOWN && file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
file.setFrequency(SearchData.Frequency.KNOWN);
}
}
} else {
processResultFilesForCR(files, centralRepoDb);
}
}
/**
* Private helper method for adding Frequency attribute when CR is
* enabled.
*
* @param files The list of ResultFiles to caluclate frequency
* for.
* @param centralRepoDb The central repository currently in use.
*/
private void processResultFilesForCR(List<ResultFile> files,
CentralRepository centralRepoDb) {
List<ResultFile> currentFiles = new ArrayList<>();
Set<String> hashesToLookUp = new HashSet<>();
for (ResultFile file : files) {
if (file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
file.setFrequency(SearchData.Frequency.KNOWN);
}
if (file.getFrequency() == SearchData.Frequency.UNKNOWN
&& file.getFirstInstance().getMd5Hash() != null
&& !file.getFirstInstance().getMd5Hash().isEmpty()) {
hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
currentFiles.add(file);
}
if (hashesToLookUp.size() >= BATCH_SIZE) {
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
hashesToLookUp.clear();
currentFiles.clear();
}
}
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
}
}
/**
* Callback to use with findInterCaseValuesByCount which generates a list of
* values for common property search
*/
private static class FrequencyCallback implements InstanceTableCallback {
private final List<ResultFile> files;
private FrequencyCallback(List<ResultFile> files) {
this.files = new ArrayList<>(files);
}
@Override
public void process(ResultSet resultSet) {
try {
while (resultSet.next()) {
String hash = resultSet.getString(1);
int count = resultSet.getInt(2);
for (Iterator<ResultFile> iterator = files.iterator(); iterator.hasNext();) {
ResultFile file = iterator.next();
if (file.getFirstInstance().getMd5Hash().equalsIgnoreCase(hash)) {
file.setFrequency(SearchData.Frequency.fromCount(count));
iterator.remove();
}
}
}
// The files left had no matching entries in the CR, so mark them as unique
for (ResultFile file : files) {
file.setFrequency(SearchData.Frequency.UNIQUE);
}
} catch (SQLException ex) {
logger.log(Level.WARNING, "Error getting frequency counts from Central Repository", ex); // NON-NLS
}
}
}
/**
* Attribute for grouping/sorting by hash set lists
*/
static class HashHitsAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.HashHitsGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, hash set name) for all files in the list of files that have
// hash set hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
HashSetNamesCallback callback = new HashSetNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up hash set attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the hash set names to the list of ResultFile objects.
*/
private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add hash set names to
*/
HashSetNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String hashSetName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addHashSetName(hashSetName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get hash set names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by interesting item set lists
*/
static class InterestingItemAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.InterestingItemGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, interesting item set name) for all files in the list of files that have
// interesting file set hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up interesting file set attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the interesting file set names to the list of
* ResultFile objects.
*/
private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add interesting file set
* names to
*/
InterestingFileSetNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String setName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addInterestingSetName(setName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get interesting file set names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by objects detected
*/
static class ObjectDetectedAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, object type name) for all files in the list of files that have
// objects detected
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up object detected attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the object type names to the list of ResultFile
* objects.
*/
private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add object detected names to
*/
ObjectDetectedNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String setName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addObjectDetectedName(setName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get object detected names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by tag name
*/
static class FileTagAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileTagGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
try {
for (ResultFile resultFile : files) {
List<ContentTag> contentTags = caseDb.getContentTagsByContent(resultFile.getFirstInstance());
for (ContentTag tag : contentTags) {
resultFile.addTagName(tag.getName().getDisplayName());
}
}
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up file tag attributes", ex); // NON-NLS
}
}
}
/**
* Enum for the attribute types that can be used for grouping.
*/
@NbBundle.Messages({
"DiscoveryAttributes.GroupingAttributeType.fileType.displayName=File Type",
"DiscoveryAttributes.GroupingAttributeType.frequency.displayName=Past Occurrences",
"DiscoveryAttributes.GroupingAttributeType.keywordList.displayName=Keyword",
"DiscoveryAttributes.GroupingAttributeType.size.displayName=File Size",
"DiscoveryAttributes.GroupingAttributeType.datasource.displayName=Data Source",
"DiscoveryAttributes.GroupingAttributeType.parent.displayName=Parent Folder",
"DiscoveryAttributes.GroupingAttributeType.hash.displayName=Hash Set",
"DiscoveryAttributes.GroupingAttributeType.interestingItem.displayName=Interesting Item",
"DiscoveryAttributes.GroupingAttributeType.tag.displayName=Tag",
"DiscoveryAttributes.GroupingAttributeType.object.displayName=Object Detected",
"DiscoveryAttributes.GroupingAttributeType.none.displayName=None"})
public enum GroupingAttributeType {
FILE_SIZE(new FileSizeAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_size_displayName()),
FREQUENCY(new FrequencyAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_frequency_displayName()),
KEYWORD_LIST_NAME(new KeywordListAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_keywordList_displayName()),
DATA_SOURCE(new DataSourceAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_datasource_displayName()),
PARENT_PATH(new ParentPathAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_parent_displayName()),
HASH_LIST_NAME(new HashHitsAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_hash_displayName()),
INTERESTING_ITEM_SET(new InterestingItemAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_interestingItem_displayName()),
FILE_TAG(new FileTagAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_tag_displayName()),
OBJECT_DETECTED(new ObjectDetectedAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_object_displayName()),
NO_GROUPING(new NoGroupingAttribute(), Bundle.DiscoveryAttributes_GroupingAttributeType_none_displayName());
private final AttributeType attributeType;
private final String displayName;
GroupingAttributeType(AttributeType attributeType, String displayName) {
this.attributeType = attributeType;
this.displayName = displayName;
}
@Override
public String toString() {
return displayName;
}
public AttributeType getAttributeType() {
return attributeType;
}
/**
* Get the list of enums that are valid for grouping images.
*
* @return enums that can be used to group images
*/
public static List<GroupingAttributeType> getOptionsForGrouping() {
return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET);
}
}
/**
* 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
*/
private static void computeFrequency(Set<String> hashesToLookUp, List<ResultFile> currentFiles, CentralRepository centralRepoDb) {
if (hashesToLookUp.isEmpty()) {
return;
}
String hashes = String.join("','", hashesToLookUp);
hashes = "'" + hashes + "'";
try {
CorrelationAttributeInstance.Type attributeType = centralRepoDb.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(attributeType);
String selectClause = " value, COUNT(value) FROM "
+ "(SELECT DISTINCT case_id, value FROM " + tableName
+ " WHERE value IN ("
+ hashes
+ ")) AS foo GROUP BY value";
FrequencyCallback callback = new FrequencyCallback(currentFiles);
centralRepoDb.processSelectClause(selectClause, callback);
} catch (CentralRepoException ex) {
logger.log(Level.WARNING, "Error getting frequency counts from Central Repository", ex); // NON-NLS
}
}
private static String createSetNameClause(List<ResultFile> files,
int artifactTypeID, int setNameAttrID) throws DiscoveryException {
// Concatenate the object IDs in the list of files
String objIdList = ""; // NON-NLS
for (ResultFile file : files) {
if (!objIdList.isEmpty()) {
objIdList += ","; // NON-NLS
}
objIdList += "\'" + file.getFirstInstance().getId() + "\'"; // NON-NLS
}
// Get pairs of (object ID, set name) for all files in the list of files that have
// the given artifact type.
return "blackboard_artifacts.obj_id AS object_id, blackboard_attributes.value_text AS set_name "
+ "FROM blackboard_artifacts "
+ "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id "
+ "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' "
+ "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' "
+ "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS
}
private DiscoveryAttributes() {
// Class should not be instantiated
}
}

View File

@ -119,7 +119,7 @@ public final class DiscoveryEventUtils {
private final Map<GroupKey, Integer> groupMap; private final Map<GroupKey, Integer> groupMap;
private final List<AbstractFilter> searchFilters; private final List<AbstractFilter> searchFilters;
private final FileSearch.AttributeType groupingAttribute; private final DiscoveryAttributes.AttributeType groupingAttribute;
private final Group.GroupSortingAlgorithm groupSort; private final Group.GroupSortingAlgorithm groupSort;
private final FileSorter.SortingMethod fileSortMethod; private final FileSorter.SortingMethod fileSortMethod;
@ -135,7 +135,7 @@ public final class DiscoveryEventUtils {
* @param fileSortMethod The sorting method used for files. * @param fileSortMethod The sorting method used for files.
*/ */
public SearchCompleteEvent(Map<GroupKey, Integer> groupMap, List<AbstractFilter> searchfilters, public SearchCompleteEvent(Map<GroupKey, Integer> groupMap, List<AbstractFilter> searchfilters,
FileSearch.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort, DiscoveryAttributes.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort,
FileSorter.SortingMethod fileSortMethod) { FileSorter.SortingMethod fileSortMethod) {
this.groupMap = groupMap; this.groupMap = groupMap;
this.searchFilters = searchfilters; this.searchFilters = searchfilters;
@ -167,7 +167,7 @@ public final class DiscoveryEventUtils {
* *
* @return The grouping attribute used by the search. * @return The grouping attribute used by the search.
*/ */
public FileSearch.AttributeType getGroupingAttr() { public DiscoveryAttributes.AttributeType getGroupingAttr() {
return groupingAttribute; return groupingAttribute;
} }
@ -278,7 +278,7 @@ public final class DiscoveryEventUtils {
private final GroupKey groupKey; private final GroupKey groupKey;
private final int groupSize; private final int groupSize;
private final List<AbstractFilter> searchfilters; private final List<AbstractFilter> searchfilters;
private final FileSearch.AttributeType groupingAttribute; private final DiscoveryAttributes.AttributeType groupingAttribute;
private final Group.GroupSortingAlgorithm groupSort; private final Group.GroupSortingAlgorithm groupSort;
private final FileSorter.SortingMethod fileSortMethod; private final FileSorter.SortingMethod fileSortMethod;
@ -297,7 +297,7 @@ public final class DiscoveryEventUtils {
* @param resultType The type of files which exist in the group. * @param resultType The type of files which exist in the group.
*/ */
public GroupSelectedEvent(List<AbstractFilter> searchfilters, public GroupSelectedEvent(List<AbstractFilter> searchfilters,
FileSearch.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort, DiscoveryAttributes.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort,
FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, Type resultType) { FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, Type resultType) {
this.searchfilters = searchfilters; this.searchfilters = searchfilters;
this.groupingAttribute = groupingAttribute; this.groupingAttribute = groupingAttribute;
@ -369,7 +369,7 @@ public final class DiscoveryEventUtils {
* *
* @return The grouping attribute used by the search. * @return The grouping attribute used by the search.
*/ */
public FileSearch.AttributeType getGroupingAttr() { public DiscoveryAttributes.AttributeType getGroupingAttr() {
return groupingAttribute; return groupingAttribute;
} }

View File

@ -52,7 +52,7 @@ public class DiscoveryKeyUtils {
* @param fileSortingMethod The method to sort the files by. * @param fileSortingMethod The method to sort the files by.
*/ */
SearchKey(String userName, List<AbstractFilter> filters, SearchKey(String userName, List<AbstractFilter> filters,
FileSearch.AttributeType groupAttributeType, DiscoveryAttributes.AttributeType groupAttributeType,
Group.GroupSortingAlgorithm groupSortingType, Group.GroupSortingAlgorithm groupSortingType,
FileSorter.SortingMethod fileSortingMethod) { FileSorter.SortingMethod fileSortingMethod) {
StringBuilder searchStringBuilder = new StringBuilder(); StringBuilder searchStringBuilder = new StringBuilder();

View File

@ -21,35 +21,18 @@ package org.sleuthkit.autopsy.discovery.search;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import java.io.IOException; import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil;
import org.sleuthkit.autopsy.centralrepository.datamodel.InstanceTableCallback;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.discovery.search.SearchData.Frequency;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.CaseDbAccessManager;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes.AttributeType;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.SearchKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.SearchKey;
import org.sleuthkit.autopsy.textsummarizer.TextSummarizer; import org.sleuthkit.autopsy.textsummarizer.TextSummarizer;
@ -322,615 +305,9 @@ public class FileSearch {
} }
} }
/**
* 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
*/
private static void computeFrequency(Set<String> hashesToLookUp, List<ResultFile> currentFiles, CentralRepository centralRepoDb) {
if (hashesToLookUp.isEmpty()) {
return;
}
String hashes = String.join("','", hashesToLookUp);
hashes = "'" + hashes + "'";
try {
CorrelationAttributeInstance.Type attributeType = centralRepoDb.getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID);
String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(attributeType);
String selectClause = " value, COUNT(value) FROM "
+ "(SELECT DISTINCT case_id, value FROM " + tableName
+ " WHERE value IN ("
+ hashes
+ ")) AS foo GROUP BY value";
FrequencyCallback callback = new FrequencyCallback(currentFiles);
centralRepoDb.processSelectClause(selectClause, callback);
} catch (CentralRepoException ex) {
logger.log(Level.WARNING, "Error getting frequency counts from Central Repository", ex); // NON-NLS
}
}
private static String createSetNameClause(List<ResultFile> files,
int artifactTypeID, int setNameAttrID) throws DiscoveryException {
// Concatenate the object IDs in the list of files
String objIdList = ""; // NON-NLS
for (ResultFile file : files) {
if (!objIdList.isEmpty()) {
objIdList += ","; // NON-NLS
}
objIdList += "\'" + file.getFirstInstance().getId() + "\'"; // NON-NLS
}
// Get pairs of (object ID, set name) for all files in the list of files that have
// the given artifact type.
return "blackboard_artifacts.obj_id AS object_id, blackboard_attributes.value_text AS set_name "
+ "FROM blackboard_artifacts "
+ "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id "
+ "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' "
+ "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' "
+ "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS
}
private FileSearch() { private FileSearch() {
// Class should not be instantiated // Class should not be instantiated
} }
/**
* Base class for the grouping attributes.
*/
public abstract static class AttributeType {
/**
* For a given file, return the key for the group it belongs to for this
* attribute type.
*
* @param file the result file to be grouped
*
* @return the key for the group this file goes in
*/
public abstract GroupKey getGroupKey(ResultFile file);
/**
* Add any extra data to the ResultFile object from this attribute.
*
* @param files The list of files to enhance
* @param caseDb The case database
* @param centralRepoDb The central repository database. Can be null if
* not needed.
*
* @throws DiscoveryException
*/
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
// Default is to do nothing
}
}
/**
* Attribute for grouping/sorting by file size
*/
public static class FileSizeAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileSizeGroupKey(file);
}
}
/**
* Attribute for grouping/sorting by parent path
*/
public static class ParentPathAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.ParentPathGroupKey(file);
}
}
/**
* Default attribute used to make one group
*/
static class NoGroupingAttribute extends FileSearch.AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.NoGroupingGroupKey();
}
}
/**
* Attribute for grouping/sorting by data source
*/
static class DataSourceAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.DataSourceGroupKey(file);
}
}
/**
* Attribute for grouping/sorting by file type
*/
static class FileTypeAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileTypeGroupKey(file);
}
}
/**
* Attribute for grouping/sorting by keyword lists
*/
static class KeywordListAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.KeywordListGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, keyword list name) for all files in the list of files that have
// keyword list hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up keyword list attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the keyword list names to the list of ResultFile
* objects.
*/
private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add keyword list names to
*/
SetKeywordListNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String keywordListName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addKeywordListName(keywordListName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get keyword list names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by frequency in the central repository
*/
static class FrequencyAttribute extends AttributeType {
static final int BATCH_SIZE = 50; // Number of hashes to look up at one time
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FrequencyGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
if (centralRepoDb == null) {
for (ResultFile file : files) {
if (file.getFrequency() == Frequency.UNKNOWN && file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
file.setFrequency(Frequency.KNOWN);
}
}
} else {
processResultFilesForCR(files, centralRepoDb);
}
}
/**
* Private helper method for adding Frequency attribute when CR is
* enabled.
*
* @param files The list of ResultFiles to caluclate frequency
* for.
* @param centralRepoDb The central repository currently in use.
*/
private void processResultFilesForCR(List<ResultFile> files,
CentralRepository centralRepoDb) {
List<ResultFile> currentFiles = new ArrayList<>();
Set<String> hashesToLookUp = new HashSet<>();
for (ResultFile file : files) {
if (file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
file.setFrequency(Frequency.KNOWN);
}
if (file.getFrequency() == Frequency.UNKNOWN
&& file.getFirstInstance().getMd5Hash() != null
&& !file.getFirstInstance().getMd5Hash().isEmpty()) {
hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
currentFiles.add(file);
}
if (hashesToLookUp.size() >= BATCH_SIZE) {
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
hashesToLookUp.clear();
currentFiles.clear();
}
}
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
}
}
/**
* Callback to use with findInterCaseValuesByCount which generates a list of
* values for common property search
*/
private static class FrequencyCallback implements InstanceTableCallback {
private final List<ResultFile> files;
private FrequencyCallback(List<ResultFile> files) {
this.files = new ArrayList<>(files);
}
@Override
public void process(ResultSet resultSet) {
try {
while (resultSet.next()) {
String hash = resultSet.getString(1);
int count = resultSet.getInt(2);
for (Iterator<ResultFile> iterator = files.iterator(); iterator.hasNext();) {
ResultFile file = iterator.next();
if (file.getFirstInstance().getMd5Hash().equalsIgnoreCase(hash)) {
file.setFrequency(Frequency.fromCount(count));
iterator.remove();
}
}
}
// The files left had no matching entries in the CR, so mark them as unique
for (ResultFile file : files) {
file.setFrequency(Frequency.UNIQUE);
}
} catch (SQLException ex) {
logger.log(Level.WARNING, "Error getting frequency counts from Central Repository", ex); // NON-NLS
}
}
}
/**
* Attribute for grouping/sorting by hash set lists
*/
static class HashHitsAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.HashHitsGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, hash set name) for all files in the list of files that have
// hash set hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
HashSetNamesCallback callback = new HashSetNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up hash set attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the hash set names to the list of ResultFile objects.
*/
private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add hash set names to
*/
HashSetNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String hashSetName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addHashSetName(hashSetName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get hash set names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by interesting item set lists
*/
static class InterestingItemAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.InterestingItemGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, interesting item set name) for all files in the list of files that have
// interesting file set hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up interesting file set attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the interesting file set names to the list of
* ResultFile objects.
*/
private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add interesting file set
* names to
*/
InterestingFileSetNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String setName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addInterestingSetName(setName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get interesting file set names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by objects detected
*/
static class ObjectDetectedAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, object type name) for all files in the list of files that have
// objects detected
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(files);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up object detected attributes", ex); // NON-NLS
}
}
/**
* Callback to process the results of the CaseDbAccessManager select
* query. Will add the object type names to the list of ResultFile
* objects.
*/
private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add object detected names to
*/
ObjectDetectedNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
}
@Override
public void process(ResultSet rs) {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
tempMap.put(file.getFirstInstance().getId(), file);
}
while (rs.next()) {
try {
Long objId = rs.getLong("object_id"); // NON-NLS
String setName = rs.getString("set_name"); // NON-NLS
tempMap.get(objId).addObjectDetectedName(setName);
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Unable to get object_id or set_name from result set", ex); // NON-NLS
}
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to get object detected names", ex); // NON-NLS
}
}
}
}
/**
* Attribute for grouping/sorting by tag name
*/
static class FileTagAttribute extends AttributeType {
@Override
public GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileTagGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
try {
for (ResultFile resultFile : files) {
List<ContentTag> contentTags = caseDb.getContentTagsByContent(resultFile.getFirstInstance());
for (ContentTag tag : contentTags) {
resultFile.addTagName(tag.getName().getDisplayName());
}
}
} catch (TskCoreException ex) {
throw new DiscoveryException("Error looking up file tag attributes", ex); // NON-NLS
}
}
}
/**
* Enum for the attribute types that can be used for grouping.
*/
@NbBundle.Messages({
"FileSearch.GroupingAttributeType.fileType.displayName=File Type",
"FileSearch.GroupingAttributeType.frequency.displayName=Past Occurrences",
"FileSearch.GroupingAttributeType.keywordList.displayName=Keyword",
"FileSearch.GroupingAttributeType.size.displayName=File Size",
"FileSearch.GroupingAttributeType.datasource.displayName=Data Source",
"FileSearch.GroupingAttributeType.parent.displayName=Parent Folder",
"FileSearch.GroupingAttributeType.hash.displayName=Hash Set",
"FileSearch.GroupingAttributeType.interestingItem.displayName=Interesting Item",
"FileSearch.GroupingAttributeType.tag.displayName=Tag",
"FileSearch.GroupingAttributeType.object.displayName=Object Detected",
"FileSearch.GroupingAttributeType.none.displayName=None"})
public enum GroupingAttributeType {
FILE_SIZE(new FileSizeAttribute(), Bundle.FileSearch_GroupingAttributeType_size_displayName()),
FREQUENCY(new FrequencyAttribute(), Bundle.FileSearch_GroupingAttributeType_frequency_displayName()),
KEYWORD_LIST_NAME(new KeywordListAttribute(), Bundle.FileSearch_GroupingAttributeType_keywordList_displayName()),
DATA_SOURCE(new DataSourceAttribute(), Bundle.FileSearch_GroupingAttributeType_datasource_displayName()),
PARENT_PATH(new ParentPathAttribute(), Bundle.FileSearch_GroupingAttributeType_parent_displayName()),
HASH_LIST_NAME(new HashHitsAttribute(), Bundle.FileSearch_GroupingAttributeType_hash_displayName()),
INTERESTING_ITEM_SET(new InterestingItemAttribute(), Bundle.FileSearch_GroupingAttributeType_interestingItem_displayName()),
FILE_TAG(new FileTagAttribute(), Bundle.FileSearch_GroupingAttributeType_tag_displayName()),
OBJECT_DETECTED(new ObjectDetectedAttribute(), Bundle.FileSearch_GroupingAttributeType_object_displayName()),
NO_GROUPING(new NoGroupingAttribute(), Bundle.FileSearch_GroupingAttributeType_none_displayName());
private final AttributeType attributeType;
private final String displayName;
GroupingAttributeType(AttributeType attributeType, String displayName) {
this.attributeType = attributeType;
this.displayName = displayName;
}
@Override
public String toString() {
return displayName;
}
public AttributeType getAttributeType() {
return attributeType;
}
/**
* Get the list of enums that are valid for grouping images.
*
* @return enums that can be used to group images
*/
public static List<GroupingAttributeType> getOptionsForGrouping() {
return Arrays.asList(FILE_SIZE, FREQUENCY, PARENT_PATH, OBJECT_DETECTED, HASH_LIST_NAME, INTERESTING_ITEM_SET);
}
}
} }

View File

@ -254,19 +254,19 @@ public class FileSorter implements Comparator<ResultFile> {
Bundle.FileSorter_SortingMethod_datasource_displayName()), // Sort in increasing order of data source ID Bundle.FileSorter_SortingMethod_datasource_displayName()), // Sort in increasing order of data source ID
BY_FILE_SIZE(new ArrayList<>(), BY_FILE_SIZE(new ArrayList<>(),
Bundle.FileSorter_SortingMethod_filesize_displayName()), // Sort in decreasing order of size Bundle.FileSorter_SortingMethod_filesize_displayName()), // Sort in decreasing order of size
BY_FILE_TYPE(Arrays.asList(new FileSearch.FileTypeAttribute()), BY_FILE_TYPE(Arrays.asList(new DiscoveryAttributes.FileTypeAttribute()),
Bundle.FileSorter_SortingMethod_filetype_displayName()), // Sort in order of file type (defined in FileType enum), with secondary sort on MIME type Bundle.FileSorter_SortingMethod_filetype_displayName()), // Sort in order of file type (defined in FileType enum), with secondary sort on MIME type
BY_FREQUENCY(Arrays.asList(new FileSearch.FrequencyAttribute()), BY_FREQUENCY(Arrays.asList(new DiscoveryAttributes.FrequencyAttribute()),
Bundle.FileSorter_SortingMethod_frequency_displayName()), // Sort by decreasing rarity in the central repository Bundle.FileSorter_SortingMethod_frequency_displayName()), // Sort by decreasing rarity in the central repository
BY_KEYWORD_LIST_NAMES(Arrays.asList(new FileSearch.KeywordListAttribute()), BY_KEYWORD_LIST_NAMES(Arrays.asList(new DiscoveryAttributes.KeywordListAttribute()),
Bundle.FileSorter_SortingMethod_keywordlist_displayName()), // Sort alphabetically by list of keyword list names found Bundle.FileSorter_SortingMethod_keywordlist_displayName()), // Sort alphabetically by list of keyword list names found
BY_FULL_PATH(new ArrayList<>(), BY_FULL_PATH(new ArrayList<>(),
Bundle.FileSorter_SortingMethod_fullPath_displayName()); // Sort alphabetically by path Bundle.FileSorter_SortingMethod_fullPath_displayName()); // Sort alphabetically by path
private final String displayName; private final String displayName;
private final List<FileSearch.AttributeType> requiredAttributes; private final List<DiscoveryAttributes.AttributeType> requiredAttributes;
SortingMethod(List<FileSearch.AttributeType> attributes, String displayName) { SortingMethod(List<DiscoveryAttributes.AttributeType> attributes, String displayName) {
this.requiredAttributes = attributes; this.requiredAttributes = attributes;
this.displayName = displayName; this.displayName = displayName;
} }
@ -276,7 +276,7 @@ public class FileSorter implements Comparator<ResultFile> {
return displayName; return displayName;
} }
public List<FileSearch.AttributeType> getRequiredAttributes() { public List<DiscoveryAttributes.AttributeType> getRequiredAttributes() {
return Collections.unmodifiableList(requiredAttributes); return Collections.unmodifiableList(requiredAttributes);
} }

View File

@ -524,7 +524,7 @@ public class SearchFiltering {
} }
// Set the frequency for each file // Set the frequency for each file
FileSearch.FrequencyAttribute freqAttr = new FileSearch.FrequencyAttribute(); DiscoveryAttributes.FrequencyAttribute freqAttr = new DiscoveryAttributes.FrequencyAttribute();
freqAttr.addAttributeToResultFiles(currentResults, caseDb, centralRepoDb); freqAttr.addAttributeToResultFiles(currentResults, caseDb, centralRepoDb);
// If the frequency matches the filter, add the file to the results // If the frequency matches the filter, add the file to the results

View File

@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
class SearchResults { class SearchResults {
private final Group.GroupSortingAlgorithm groupSortingType; private final Group.GroupSortingAlgorithm groupSortingType;
private final FileSearch.AttributeType attrType; private final DiscoveryAttributes.AttributeType attrType;
private final FileSorter fileSorter; private final FileSorter fileSorter;
private final Map<GroupKey, Group> groupMap = new HashMap<>(); private final Map<GroupKey, Group> groupMap = new HashMap<>();
@ -50,7 +50,7 @@ class SearchResults {
* @param fileSortingMethod The method that should be used to * @param fileSortingMethod The method that should be used to
* sortGroupsAndFiles the files in each group. * sortGroupsAndFiles the files in each group.
*/ */
SearchResults(Group.GroupSortingAlgorithm groupSortingType, FileSearch.AttributeType attrType, SearchResults(Group.GroupSortingAlgorithm groupSortingType, DiscoveryAttributes.AttributeType attrType,
FileSorter.SortingMethod fileSortingMethod) { FileSorter.SortingMethod fileSortingMethod) {
this.groupSortingType = groupSortingType; this.groupSortingType = groupSortingType;
this.attrType = attrType; this.attrType = attrType;
@ -63,7 +63,7 @@ class SearchResults {
*/ */
SearchResults() { SearchResults() {
this.groupSortingType = Group.GroupSortingAlgorithm.BY_GROUP_NAME; this.groupSortingType = Group.GroupSortingAlgorithm.BY_GROUP_NAME;
this.attrType = new FileSearch.FileSizeAttribute(); this.attrType = new DiscoveryAttributes.FileSizeAttribute();
this.fileSorter = new FileSorter(FileSorter.SortingMethod.BY_FILE_NAME); this.fileSorter = new FileSorter(FileSorter.SortingMethod.BY_FILE_NAME);
} }

View File

@ -37,13 +37,13 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes;
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
import org.sleuthkit.autopsy.discovery.search.Group; import org.sleuthkit.autopsy.discovery.search.Group;
import org.sleuthkit.autopsy.discovery.search.Group.GroupSortingAlgorithm; import org.sleuthkit.autopsy.discovery.search.Group.GroupSortingAlgorithm;
import static org.sleuthkit.autopsy.discovery.search.Group.GroupSortingAlgorithm.BY_GROUP_SIZE; import static org.sleuthkit.autopsy.discovery.search.Group.GroupSortingAlgorithm.BY_GROUP_SIZE;
import org.sleuthkit.autopsy.discovery.search.FileSearch; import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes.GroupingAttributeType;
import org.sleuthkit.autopsy.discovery.search.FileSearch.GroupingAttributeType; import static org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes.GroupingAttributeType.PARENT_PATH;
import static org.sleuthkit.autopsy.discovery.search.FileSearch.GroupingAttributeType.PARENT_PATH;
import org.sleuthkit.autopsy.discovery.search.FileSorter; import org.sleuthkit.autopsy.discovery.search.FileSorter;
import org.sleuthkit.autopsy.discovery.search.FileSorter.SortingMethod; import org.sleuthkit.autopsy.discovery.search.FileSorter.SortingMethod;
import static org.sleuthkit.autopsy.discovery.search.FileSorter.SortingMethod.BY_FILE_NAME; import static org.sleuthkit.autopsy.discovery.search.FileSorter.SortingMethod.BY_FILE_NAME;
@ -169,7 +169,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
private void updateComboBoxes() { private void updateComboBoxes() {
groupByCombobox.removeAllItems(); groupByCombobox.removeAllItems();
// Set up the grouping attributes // Set up the grouping attributes
for (FileSearch.GroupingAttributeType groupingType : FileSearch.GroupingAttributeType.getOptionsForGrouping()) { for (DiscoveryAttributes.GroupingAttributeType groupingType : DiscoveryAttributes.GroupingAttributeType.getOptionsForGrouping()) {
addTypeToGroupByComboBox(groupingType); addTypeToGroupByComboBox(groupingType);
} }
groupByCombobox.setSelectedItem(PARENT_PATH); groupByCombobox.setSelectedItem(PARENT_PATH);
@ -554,7 +554,7 @@ final class DiscoveryDialog extends javax.swing.JDialog {
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.SearchStartedEvent(type)); DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.SearchStartedEvent(type));
// Get the grouping attribute and group sorting method // Get the grouping attribute and group sorting method
FileSearch.AttributeType groupingAttr = groupByCombobox.getItemAt(groupByCombobox.getSelectedIndex()).getAttributeType(); DiscoveryAttributes.AttributeType groupingAttr = groupByCombobox.getItemAt(groupByCombobox.getSelectedIndex()).getAttributeType();
Group.GroupSortingAlgorithm groupSortAlgorithm = groupSortingComboBox.getItemAt(groupSortingComboBox.getSelectedIndex()); Group.GroupSortingAlgorithm groupSortAlgorithm = groupSortingComboBox.getItemAt(groupSortingComboBox.getSelectedIndex());
// Get the file sorting method // Get the file sorting method

View File

@ -29,10 +29,10 @@ import javax.swing.JList;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes;
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.autopsy.discovery.search.Group; import org.sleuthkit.autopsy.discovery.search.Group;
import org.sleuthkit.autopsy.discovery.search.FileSearch;
import org.sleuthkit.autopsy.discovery.search.SearchData.Type; import org.sleuthkit.autopsy.discovery.search.SearchData.Type;
import org.sleuthkit.autopsy.discovery.search.FileSorter; import org.sleuthkit.autopsy.discovery.search.FileSorter;
@ -45,7 +45,7 @@ final class GroupListPanel extends javax.swing.JPanel {
private Type type = null; private Type type = null;
private Map<GroupKey, Integer> groupMap = null; private Map<GroupKey, Integer> groupMap = null;
private List<AbstractFilter> searchfilters; private List<AbstractFilter> searchfilters;
private FileSearch.AttributeType groupingAttribute; private DiscoveryAttributes.AttributeType groupingAttribute;
private Group.GroupSortingAlgorithm groupSort; private Group.GroupSortingAlgorithm groupSort;
private FileSorter.SortingMethod fileSortMethod; private FileSorter.SortingMethod fileSortMethod;
private GroupKey selectedGroupKey; private GroupKey selectedGroupKey;
@ -210,7 +210,7 @@ final class GroupListPanel extends javax.swing.JPanel {
String valueString = newValue.toString(); String valueString = newValue.toString();
setToolTipText(valueString); setToolTipText(valueString);
//if paths would be longer than 37 characters shorten them to be 37 characters //if paths would be longer than 37 characters shorten them to be 37 characters
if (groupingAttribute instanceof FileSearch.ParentPathAttribute && valueString.length() > 37) { if (groupingAttribute instanceof DiscoveryAttributes.ParentPathAttribute && valueString.length() > 37) {
valueString = valueString.substring(0, 16) + " ... " + valueString.substring(valueString.length() - 16); valueString = valueString.substring(0, 16) + " ... " + valueString.substring(valueString.length() - 16);
} }
newValue = valueString + " (" + groupMap.get(newValue) + ")"; newValue = valueString + " (" + groupMap.get(newValue) + ")";

View File

@ -26,6 +26,7 @@ import javax.swing.SwingWorker;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes;
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.autopsy.discovery.search.Group; import org.sleuthkit.autopsy.discovery.search.Group;
@ -43,7 +44,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
private final static Logger logger = Logger.getLogger(PageWorker.class.getName()); private final static Logger logger = Logger.getLogger(PageWorker.class.getName());
private static final String USER_NAME_PROPERTY = "user.name"; //NON-NLS private static final String USER_NAME_PROPERTY = "user.name"; //NON-NLS
private final List<AbstractFilter> searchfilters; private final List<AbstractFilter> searchfilters;
private final FileSearch.AttributeType groupingAttribute; private final DiscoveryAttributes.AttributeType groupingAttribute;
private final Group.GroupSortingAlgorithm groupSort; private final Group.GroupSortingAlgorithm groupSort;
private final FileSorter.SortingMethod fileSortMethod; private final FileSorter.SortingMethod fileSortMethod;
private final GroupKey groupKey; private final GroupKey groupKey;
@ -69,7 +70,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
* @param resultType The type of files which exist in the group. * @param resultType The type of files which exist in the group.
* @param centralRepo The central repository to be used. * @param centralRepo The central repository to be used.
*/ */
PageWorker(List<AbstractFilter> searchfilters, FileSearch.AttributeType groupingAttribute, PageWorker(List<AbstractFilter> searchfilters, DiscoveryAttributes.AttributeType groupingAttribute,
Group.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, Group.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod, GroupKey groupKey,
int startingEntry, int pageSize, SearchData.Type resultType, CentralRepository centralRepo) { int startingEntry, int pageSize, SearchData.Type resultType, CentralRepository centralRepo) {
this.searchfilters = searchfilters; this.searchfilters = searchfilters;

View File

@ -38,6 +38,7 @@ import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes;
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.autopsy.discovery.search.Group; import org.sleuthkit.autopsy.discovery.search.Group;
@ -59,7 +60,7 @@ final class ResultsPanel extends javax.swing.JPanel {
private final ImageThumbnailViewer imageThumbnailViewer; private final ImageThumbnailViewer imageThumbnailViewer;
private final DocumentPreviewViewer documentPreviewViewer; private final DocumentPreviewViewer documentPreviewViewer;
private List<AbstractFilter> searchFilters; private List<AbstractFilter> searchFilters;
private FileSearch.AttributeType groupingAttribute; private DiscoveryAttributes.AttributeType groupingAttribute;
private Group.GroupSortingAlgorithm groupSort; private Group.GroupSortingAlgorithm groupSort;
private FileSorter.SortingMethod fileSortMethod; private FileSorter.SortingMethod fileSortMethod;
private GroupKey selectedGroupKey; private GroupKey selectedGroupKey;

View File

@ -27,6 +27,7 @@ import java.util.logging.Level;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.discovery.search.DiscoveryAttributes;
import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils; import org.sleuthkit.autopsy.discovery.search.DiscoveryEventUtils;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.autopsy.discovery.search.Group; import org.sleuthkit.autopsy.discovery.search.Group;
@ -42,7 +43,7 @@ final class SearchWorker extends SwingWorker<Void, Void> {
private final static Logger logger = Logger.getLogger(SearchWorker.class.getName()); private final static Logger logger = Logger.getLogger(SearchWorker.class.getName());
private static final String USER_NAME_PROPERTY = "user.name"; //NON-NLS private static final String USER_NAME_PROPERTY = "user.name"; //NON-NLS
private final List<AbstractFilter> filters; private final List<AbstractFilter> filters;
private final FileSearch.AttributeType groupingAttr; private final DiscoveryAttributes.AttributeType groupingAttr;
private final FileSorter.SortingMethod fileSort; private final FileSorter.SortingMethod fileSort;
private final Group.GroupSortingAlgorithm groupSortAlgorithm; private final Group.GroupSortingAlgorithm groupSortAlgorithm;
private final CentralRepository centralRepoDb; private final CentralRepository centralRepoDb;
@ -58,7 +59,7 @@ final class SearchWorker extends SwingWorker<Void, Void> {
* @param groupSort The Algorithm to sort groups by. * @param groupSort The Algorithm to sort groups by.
* @param fileSortMethod The SortingMethod to use for files. * @param fileSortMethod The SortingMethod to use for files.
*/ */
SearchWorker(CentralRepository centralRepo, List<AbstractFilter> searchfilters, FileSearch.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod) { SearchWorker(CentralRepository centralRepo, List<AbstractFilter> searchfilters, DiscoveryAttributes.AttributeType groupingAttribute, Group.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod) {
centralRepoDb = centralRepo; centralRepoDb = centralRepo;
filters = searchfilters; filters = searchfilters;
groupingAttr = groupingAttribute; groupingAttr = groupingAttribute;