6711 add ResultDomain object

This commit is contained in:
William Schaefer 2020-08-20 16:07:34 -04:00
parent 1b73edee7d
commit e9b80d09a1
15 changed files with 369 additions and 240 deletions

View File

@ -61,7 +61,7 @@ public abstract class AbstractFilter {
*
* @throws DiscoveryException
*/
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
public List<Result> applyAlternateFilter(List<Result> currentResults, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
return new ArrayList<>();
}

View File

@ -52,19 +52,19 @@ public class DiscoveryAttributes {
*
* @return the key for the group this file goes in
*/
public abstract DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file);
public abstract DiscoveryKeyUtils.GroupKey getGroupKey(Result file);
/**
* Add any extra data to the ResultFile object from this attribute.
*
* @param files The list of files to enhance
* @param files The list of results to enhance
* @param caseDb The case database
* @param centralRepoDb The central repository database. Can be null if
* not needed.
*
* @throws DiscoveryException
*/
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
// Default is to do nothing
}
}
@ -75,8 +75,8 @@ public class DiscoveryAttributes {
public static class FileSizeAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileSizeGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.FileSizeGroupKey((ResultFile) file);
}
}
@ -86,8 +86,8 @@ public class DiscoveryAttributes {
public static class ParentPathAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.ParentPathGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.ParentPathGroupKey((ResultFile) file);
}
}
@ -97,7 +97,7 @@ public class DiscoveryAttributes {
static class NoGroupingAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
return new DiscoveryKeyUtils.NoGroupingGroupKey();
}
}
@ -108,8 +108,8 @@ public class DiscoveryAttributes {
static class DataSourceAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.DataSourceGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
return new DiscoveryKeyUtils.DataSourceGroupKey(result);
}
}
@ -119,7 +119,7 @@ public class DiscoveryAttributes {
static class FileTypeAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.FileTypeGroupKey(file);
}
}
@ -130,20 +130,20 @@ public class DiscoveryAttributes {
static class KeywordListAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.KeywordListGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.KeywordListGroupKey((ResultFile) file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, keyword list name) for all files in the list of files that have
// keyword list hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(files);
SetKeywordListNamesCallback callback = new SetKeywordListNamesCallback(results);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
@ -158,14 +158,14 @@ public class DiscoveryAttributes {
*/
private static class SetKeywordListNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
List<Result> resultFiles;
/**
* Create the callback.
*
* @param resultFiles List of files to add keyword list names to
*/
SetKeywordListNamesCallback(List<ResultFile> resultFiles) {
SetKeywordListNamesCallback(List<Result> resultFiles) {
this.resultFiles = resultFiles;
}
@ -174,7 +174,11 @@ public class DiscoveryAttributes {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
for (Result result : resultFiles) {
if (result.getType() == SearchData.Type.DOMAIN) {
break;
}
ResultFile file = (ResultFile) result;
tempMap.put(file.getFirstInstance().getId(), file);
}
@ -204,21 +208,21 @@ public class DiscoveryAttributes {
static final int BATCH_SIZE = 50; // Number of hashes to look up at one time
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.FrequencyGroupKey(file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
if (centralRepoDb == null) {
for (ResultFile file : files) {
if (file.getFrequency() == SearchData.Frequency.UNKNOWN && file.getFirstInstance().getKnown() == TskData.FileKnown.KNOWN) {
file.setFrequency(SearchData.Frequency.KNOWN);
for (Result result : results) {
if (result.getFrequency() == SearchData.Frequency.UNKNOWN && result.getKnown() == TskData.FileKnown.KNOWN) {
result.setFrequency(SearchData.Frequency.KNOWN);
}
}
} else {
processResultFilesForCR(files, centralRepoDb);
processResultFilesForCR(results, centralRepoDb);
}
}
@ -230,20 +234,23 @@ public class DiscoveryAttributes {
* for.
* @param centralRepoDb The central repository currently in use.
*/
private void processResultFilesForCR(List<ResultFile> files,
private void processResultFilesForCR(List<Result> results,
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);
for (Result result : results) {
if (result.getKnown() == TskData.FileKnown.KNOWN) {
result.setFrequency(SearchData.Frequency.KNOWN);
}
if (result.getType() != SearchData.Type.DOMAIN) {
ResultFile file = (ResultFile) result;
if (file.getFrequency() == SearchData.Frequency.UNKNOWN
&& file.getFirstInstance().getMd5Hash() != null
&& !file.getFirstInstance().getMd5Hash().isEmpty()) {
hashesToLookUp.add(file.getFirstInstance().getMd5Hash());
currentFiles.add(file);
}
}
if (hashesToLookUp.size() >= BATCH_SIZE) {
computeFrequency(hashesToLookUp, currentFiles, centralRepoDb);
@ -299,20 +306,23 @@ public class DiscoveryAttributes {
static class HashHitsAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.HashHitsGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result result) {
if (result.getType() == SearchData.Type.DOMAIN) {
return null;
}
return new DiscoveryKeyUtils.HashHitsGroupKey((ResultFile) result);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, hash set name) for all files in the list of files that have
// hash set hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
HashSetNamesCallback callback = new HashSetNamesCallback(files);
HashSetNamesCallback callback = new HashSetNamesCallback(results);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
@ -326,15 +336,15 @@ public class DiscoveryAttributes {
*/
private static class HashSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
List<Result> results;
/**
* Create the callback.
*
* @param resultFiles List of files to add hash set names to
*/
HashSetNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
HashSetNamesCallback(List<Result> results) {
this.results = results;
}
@Override
@ -342,7 +352,11 @@ public class DiscoveryAttributes {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
for (Result result : results) {
if (result.getType() == SearchData.Type.DOMAIN) {
return;
}
ResultFile file = (ResultFile) result;
tempMap.put(file.getFirstInstance().getId(), file);
}
@ -370,20 +384,20 @@ public class DiscoveryAttributes {
static class InterestingItemAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.InterestingItemGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.InterestingItemGroupKey((ResultFile) file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, interesting item set name) for all files in the list of files that have
// interesting file set hits.
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(files);
InterestingFileSetNamesCallback callback = new InterestingFileSetNamesCallback(results);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
@ -398,7 +412,7 @@ public class DiscoveryAttributes {
*/
private static class InterestingFileSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
List<Result> results;
/**
* Create the callback.
@ -406,8 +420,8 @@ public class DiscoveryAttributes {
* @param resultFiles List of files to add interesting file set
* names to
*/
InterestingFileSetNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
InterestingFileSetNamesCallback(List<Result> results) {
this.results = results;
}
@Override
@ -415,7 +429,11 @@ public class DiscoveryAttributes {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
for (Result result : results) {
if (result.getType() == SearchData.Type.DOMAIN) {
return;
}
ResultFile file = (ResultFile) result;
tempMap.put(file.getFirstInstance().getId(), file);
}
@ -443,20 +461,20 @@ public class DiscoveryAttributes {
static class ObjectDetectedAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.ObjectDetectedGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.ObjectDetectedGroupKey((ResultFile) file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// Get pairs of (object ID, object type name) for all files in the list of files that have
// objects detected
String selectQuery = createSetNameClause(files, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
String selectQuery = createSetNameClause(results, BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID(),
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION.getTypeID());
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(files);
ObjectDetectedNamesCallback callback = new ObjectDetectedNamesCallback(results);
try {
caseDb.getCaseDbAccessManager().select(selectQuery, callback);
} catch (TskCoreException ex) {
@ -471,15 +489,15 @@ public class DiscoveryAttributes {
*/
private static class ObjectDetectedNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
List<ResultFile> resultFiles;
List<Result> results;
/**
* Create the callback.
*
* @param resultFiles List of files to add object detected names to
*/
ObjectDetectedNamesCallback(List<ResultFile> resultFiles) {
this.resultFiles = resultFiles;
ObjectDetectedNamesCallback(List<Result> results) {
this.results = results;
}
@Override
@ -487,7 +505,11 @@ public class DiscoveryAttributes {
try {
// Create a temporary map of object ID to ResultFile
Map<Long, ResultFile> tempMap = new HashMap<>();
for (ResultFile file : resultFiles) {
for (Result result : results) {
if (result.getType() == SearchData.Type.DOMAIN) {
return;
}
ResultFile file = (ResultFile) result;
tempMap.put(file.getFirstInstance().getId(), file);
}
@ -515,20 +537,24 @@ public class DiscoveryAttributes {
static class FileTagAttribute extends AttributeType {
@Override
public DiscoveryKeyUtils.GroupKey getGroupKey(ResultFile file) {
return new DiscoveryKeyUtils.FileTagGroupKey(file);
public DiscoveryKeyUtils.GroupKey getGroupKey(Result file) {
return new DiscoveryKeyUtils.FileTagGroupKey((ResultFile) file);
}
@Override
public void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
public void addAttributeToResultFiles(List<Result> results, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
try {
for (ResultFile resultFile : files) {
List<ContentTag> contentTags = caseDb.getContentTagsByContent(resultFile.getFirstInstance());
for (Result result : results) {
if (result.getType() == SearchData.Type.DOMAIN) {
return;
}
ResultFile file = (ResultFile) result;
List<ContentTag> contentTags = caseDb.getContentTagsByContent(file.getFirstInstance());
for (ContentTag tag : contentTags) {
resultFile.addTagName(tag.getName().getDisplayName());
result.addTagName(tag.getName().getDisplayName());
}
}
} catch (TskCoreException ex) {
@ -625,12 +651,16 @@ public class DiscoveryAttributes {
}
private static String createSetNameClause(List<ResultFile> files,
private static String createSetNameClause(List<Result> results,
int artifactTypeID, int setNameAttrID) throws DiscoveryException {
// Concatenate the object IDs in the list of files
String objIdList = ""; // NON-NLS
for (ResultFile file : files) {
for (Result result : results) {
if (result.getType() == SearchData.Type.DOMAIN) {
break;
}
ResultFile file = (ResultFile) result;
if (!objIdList.isEmpty()) {
objIdList += ","; // NON-NLS
}
@ -644,7 +674,8 @@ public class DiscoveryAttributes {
+ "INNER JOIN blackboard_attributes ON blackboard_artifacts.artifact_id=blackboard_attributes.artifact_id "
+ "WHERE blackboard_attributes.artifact_type_id=\'" + artifactTypeID + "\' "
+ "AND blackboard_attributes.attribute_type_id=\'" + setNameAttrID + "\' "
+ "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS
+ "AND blackboard_artifacts.obj_id IN (" + objIdList
+ ") "; // NON-NLS
}
private DiscoveryAttributes() {

View File

@ -197,7 +197,7 @@ public final class DiscoveryEventUtils {
*/
public static final class PageRetrievedEvent {
private final List<ResultFile> results;
private final List<Result> results;
private final int page;
private final Type resultType;
@ -208,7 +208,7 @@ public final class DiscoveryEventUtils {
* @param page The number of the page which was retrieved.
* @param results The list of files in the page retrieved.
*/
public PageRetrievedEvent(Type resultType, int page, List<ResultFile> results) {
public PageRetrievedEvent(Type resultType, int page, List<Result> results) {
this.results = results;
this.page = page;
this.resultType = resultType;
@ -219,7 +219,7 @@ public final class DiscoveryEventUtils {
*
* @return The list of files in the page retrieved.
*/
public List<ResultFile> getSearchResults() {
public List<Result> getSearchResults() {
return Collections.unmodifiableList(results);
}

View File

@ -155,11 +155,12 @@ public class DiscoveryKeyUtils {
private final SearchData.FileSize fileSize;
FileSizeGroupKey(ResultFile file) {
if (file.getFileType() == SearchData.Type.VIDEO) {
fileSize = SearchData.FileSize.fromVideoSize(file.getFirstInstance().getSize());
FileSizeGroupKey(Result file) {
ResultFile resultFile = (ResultFile) file;
if (resultFile.getFileType() == SearchData.Type.VIDEO) {
fileSize = SearchData.FileSize.fromVideoSize(resultFile.getFirstInstance().getSize());
} else {
fileSize = SearchData.FileSize.fromImageSize(file.getFirstInstance().getSize());
fileSize = SearchData.FileSize.fromImageSize(resultFile.getFirstInstance().getSize());
}
}
@ -212,8 +213,8 @@ public class DiscoveryKeyUtils {
private final SearchData.Type fileType;
FileTypeGroupKey(ResultFile file) {
fileType = file.getFileType();
FileTypeGroupKey(Result file) {
fileType = ((ResultFile) file).getFileType();
}
@Override
@ -539,19 +540,19 @@ public class DiscoveryKeyUtils {
@NbBundle.Messages({
"# {0} - Data source name",
"# {1} - Data source ID",
"FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
"DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})",
"# {0} - Data source ID",
"FileSearch.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
DataSourceGroupKey(ResultFile file) {
dataSourceID = file.getFirstInstance().getDataSourceObjectId();
"DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})"})
DataSourceGroupKey(Result result) {
//get the id first so that it can be used when logging if necessary
dataSourceID = result.getDataSourceObjectId();
try {
// The data source should be cached so this won't actually be a database query.
Content ds = file.getFirstInstance().getDataSource();
displayName = Bundle.FileSearch_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
Content ds = result.getDataSource();
displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_datasourceAndID(ds.getName(), ds.getId());
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error looking up data source with ID " + dataSourceID, ex); // NON-NLS
displayName = Bundle.FileSearch_DataSourceGroupKey_idOnly(dataSourceID);
displayName = Bundle.DiscoveryKeyUtils_DataSourceGroupKey_idOnly(dataSourceID);
}
}
@ -646,7 +647,7 @@ public class DiscoveryKeyUtils {
private final SearchData.Frequency frequency;
FrequencyGroupKey(ResultFile file) {
FrequencyGroupKey(Result file) {
frequency = file.getFrequency();
}

View File

@ -45,7 +45,7 @@ public class FileSearch {
private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
private static final int MAXIMUM_CACHE_SIZE = 10;
private static final Cache<SearchKey, Map<GroupKey, List<ResultFile>>> searchCache = CacheBuilder.newBuilder()
private static final Cache<SearchKey, Map<GroupKey, List<Result>>> searchCache = CacheBuilder.newBuilder()
.maximumSize(MAXIMUM_CACHE_SIZE)
.build();
@ -82,18 +82,18 @@ public class FileSearch {
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
// Run the queries for each filter
List<ResultFile> resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
List<Result> results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
// Add the data to resultFiles for any attributes needed for sorting and grouping
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb);
// Collect everything in the search results
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
searchResults.add(resultFiles);
searchResults.add(results);
// Sort and group the results
searchResults.sortGroupsAndFiles();
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
Map<GroupKey, List<Result>> resultHashMap = searchResults.toLinkedHashMap();
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
synchronized (searchCache) {
searchCache.put(searchKey, resultHashMap);
@ -125,7 +125,7 @@ public class FileSearch {
Group.GroupSortingAlgorithm groupSortingType,
FileSorter.SortingMethod fileSortingMethod,
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
Map<GroupKey, List<ResultFile>> searchResults = runFileSearch(userName, filters,
Map<GroupKey, List<Result>> searchResults = runFileSearch(userName, filters,
groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
LinkedHashMap<GroupKey, Integer> groupSizes = new LinkedHashMap<>();
for (GroupKey groupKey : searchResults.keySet()) {
@ -156,7 +156,7 @@ public class FileSearch {
*
* @throws DiscoveryException
*/
public static List<ResultFile> getFilesInGroup(String userName,
public static List<Result> getFilesInGroup(String userName,
List<AbstractFilter> filters,
AttributeType groupAttributeType,
Group.GroupSortingAlgorithm groupSortingType,
@ -166,16 +166,16 @@ public class FileSearch {
int numberOfEntries,
SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
//the group should be in the cache at this point
List<ResultFile> filesInGroup = null;
List<Result> filesInGroup = null;
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
Map<GroupKey, List<ResultFile>> resultsMap;
Map<GroupKey, List<Result>> resultsMap;
synchronized (searchCache) {
resultsMap = searchCache.getIfPresent(searchKey);
}
if (resultsMap != null) {
filesInGroup = resultsMap.get(groupKey);
}
List<ResultFile> page = new ArrayList<>();
List<Result> page = new ArrayList<>();
if (filesInGroup == null) {
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey);
runFileSearch(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
@ -252,7 +252,7 @@ public class FileSearch {
*
* @throws DiscoveryException
*/
private static Map<GroupKey, List<ResultFile>> runFileSearch(String userName,
private static Map<GroupKey, List<Result>> runFileSearch(String userName,
List<AbstractFilter> filters,
AttributeType groupAttributeType,
Group.GroupSortingAlgorithm groupSortingType,
@ -268,15 +268,15 @@ public class FileSearch {
attributesNeededForGroupingOrSorting.addAll(fileSortingMethod.getRequiredAttributes());
// Run the queries for each filter
List<ResultFile> resultFiles = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
List<Result> results = SearchFiltering.runQueries(filters, caseDb, centralRepoDb);
// Add the data to resultFiles for any attributes needed for sorting and grouping
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
addAttributes(attributesNeededForGroupingOrSorting, results, caseDb, centralRepoDb);
// Collect everything in the search results
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
searchResults.add(resultFiles);
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
searchResults.add(results);
Map<GroupKey, List<Result>> resultHashMap = searchResults.toLinkedHashMap();
SearchKey searchKey = new SearchKey(userName, filters, groupAttributeType, groupSortingType, fileSortingMethod);
synchronized (searchCache) {
searchCache.put(searchKey, resultHashMap);
@ -298,10 +298,10 @@ public class FileSearch {
*
* @throws DiscoveryException
*/
private static void addAttributes(List<AttributeType> attrs, List<ResultFile> resultFiles, SleuthkitCase caseDb, CentralRepository centralRepoDb)
private static void addAttributes(List<AttributeType> attrs, List<Result> results, SleuthkitCase caseDb, CentralRepository centralRepoDb)
throws DiscoveryException {
for (AttributeType attr : attrs) {
attr.addAttributeToResultFiles(resultFiles, caseDb, centralRepoDb);
attr.addAttributeToResultFiles(results, caseDb, centralRepoDb);
}
}

View File

@ -29,9 +29,9 @@ import org.sleuthkit.datamodel.TskCoreException;
/**
* Class used to sort ResultFiles using the supplied method.
*/
public class FileSorter implements Comparator<ResultFile> {
public class FileSorter implements Comparator<Result> {
private final List<Comparator<ResultFile>> comparators = new ArrayList<>();
private final List<Comparator<Result>> comparators = new ArrayList<>();
/**
* Set up the sorter using the supplied sorting method. The sorting is
@ -51,7 +51,7 @@ public class FileSorter implements Comparator<ResultFile> {
comparators.add(getFileSizeComparator());
break;
case BY_FILE_TYPE:
comparators.add(getFileTypeComparator());
comparators.add(getTypeComparator());
comparators.add(getMIMETypeComparator());
break;
case BY_FREQUENCY:
@ -77,11 +77,11 @@ public class FileSorter implements Comparator<ResultFile> {
}
@Override
public int compare(ResultFile file1, ResultFile file2) {
public int compare(Result result1, Result result2) {
int result = 0;
for (Comparator<ResultFile> comp : comparators) {
result = comp.compare(file1, file2);
for (Comparator<Result> comp : comparators) {
result = comp.compare(result1, result2);
if (result != 0) {
return result;
}
@ -96,8 +96,8 @@ public class FileSorter implements Comparator<ResultFile> {
*
* @return -1 if file1 has the lower data source ID, 0 if equal, 1 otherwise
*/
private static Comparator<ResultFile> getDataSourceComparator() {
return (ResultFile file1, ResultFile file2) -> Long.compare(file1.getFirstInstance().getDataSourceObjectId(), file2.getFirstInstance().getDataSourceObjectId());
private static Comparator<Result> getDataSourceComparator() {
return (Result result1, Result result2) -> Long.compare(result1.getDataSourceObjectId(), result2.getDataSourceObjectId());
}
/**
@ -106,8 +106,8 @@ public class FileSorter implements Comparator<ResultFile> {
*
* @return -1 if file1 has the lower FileType value, 0 if equal, 1 otherwise
*/
private static Comparator<ResultFile> getFileTypeComparator() {
return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFileType().getRanking(), file2.getFileType().getRanking());
private static Comparator<Result> getTypeComparator() {
return (Result result1, Result result2) -> Integer.compare(result1.getType().getRanking(), result2.getType().getRanking());
}
/**
@ -118,9 +118,14 @@ public class FileSorter implements Comparator<ResultFile> {
* @return -1 if file1 has the earliest combined keyword list name, 0 if
* equal, 1 otherwise
*/
private static Comparator<ResultFile> getKeywordListNameComparator() {
return (ResultFile file1, ResultFile file2) -> {
private static Comparator<Result> getKeywordListNameComparator() {
return (Result result1, Result result2) -> {
// Put empty lists at the bottom
if (result1.getType() == SearchData.Type.DOMAIN) {
return 0;
}
ResultFile file1 = (ResultFile) result1;
ResultFile file2 = (ResultFile) result2;
if (file1.getKeywordListNames().isEmpty()) {
if (file2.getKeywordListNames().isEmpty()) {
return 0;
@ -142,11 +147,16 @@ public class FileSorter implements Comparator<ResultFile> {
* @return -1 if file1's path comes first alphabetically, 0 if equal, 1
* otherwise
*/
private static Comparator<ResultFile> getParentPathComparator() {
private static Comparator<Result> getParentPathComparator() {
return new Comparator<ResultFile>() {
return new Comparator<Result>() {
@Override
public int compare(ResultFile file1, ResultFile file2) {
public int compare(Result result1, Result result2) {
if (result1.getType() == SearchData.Type.DOMAIN) {
return 0;
}
ResultFile file1 = (ResultFile) result1;
ResultFile file2 = (ResultFile) result2;
String file1ParentPath;
try {
file1ParentPath = file1.getFirstInstance().getParent().getUniquePath();
@ -170,8 +180,8 @@ public class FileSorter implements Comparator<ResultFile> {
*
* @return -1 if file1's rarity is lower than file2, 0 if equal, 1 otherwise
*/
private static Comparator<ResultFile> getFrequencyComparator() {
return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFrequency().getRanking(), file2.getFrequency().getRanking());
private static Comparator<Result> getFrequencyComparator() {
return (Result result1, Result result2) -> Integer.compare(result1.getFrequency().getRanking(), result2.getFrequency().getRanking());
}
/**
@ -180,8 +190,13 @@ public class FileSorter implements Comparator<ResultFile> {
* @return -1 if file1's MIME type comes before file2's, 0 if equal, 1
* otherwise
*/
private static Comparator<ResultFile> getMIMETypeComparator() {
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getFirstInstance().getMIMEType(), file2.getFirstInstance().getMIMEType());
private static Comparator<Result> getMIMETypeComparator() {
return (Result result1, Result result2) -> {
if (result1.getType() == SearchData.Type.DOMAIN) {
return 0;
}
return compareStrings(((ResultFile) result1).getFirstInstance().getMIMEType(), ((ResultFile) result2).getFirstInstance().getMIMEType());
};
}
/**
@ -189,9 +204,13 @@ public class FileSorter implements Comparator<ResultFile> {
*
* @return -1 if file1 is larger than file2, 0 if equal, 1 otherwise
*/
private static Comparator<ResultFile> getFileSizeComparator() {
return (ResultFile file1, ResultFile file2) -> -1 * Long.compare(file1.getFirstInstance().getSize(), file2.getFirstInstance().getSize()) // Sort large to small
;
private static Comparator<Result> getFileSizeComparator() {
return (Result result1, Result result2) -> {
if (result1.getType() == SearchData.Type.DOMAIN) {
return 0;
}
return -1 * Long.compare(((ResultFile) result1).getFirstInstance().getSize(), ((ResultFile) result2).getFirstInstance().getSize()); // Sort large to small
};
}
/**
@ -199,8 +218,13 @@ public class FileSorter implements Comparator<ResultFile> {
*
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
*/
private static Comparator<ResultFile> getFileNameComparator() {
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getFirstInstance().getName().toLowerCase(), file2.getFirstInstance().getName().toLowerCase());
private static Comparator<Result> getFileNameComparator() {
return (Result result1, Result result2) -> {
if (result1.getType() == SearchData.Type.DOMAIN) {
return 0;
}
return compareStrings(((ResultFile) result1).getFirstInstance().getName().toLowerCase(), (((ResultFile) result2).getFirstInstance().getName().toLowerCase()));
};
}
/**
@ -211,14 +235,21 @@ public class FileSorter implements Comparator<ResultFile> {
*
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
*/
private static Comparator<ResultFile> getDefaultComparator() {
return (ResultFile file1, ResultFile file2) -> {
private static Comparator<Result> getDefaultComparator() {
return (Result result1, Result result2) -> {
// Compare file names and then object ID (to ensure a consistent sort)
if (result1.getType() == SearchData.Type.DOMAIN) {
return getFrequencyComparator().compare(result1, result2);
} else {
ResultFile file1 = (ResultFile) result1;
ResultFile file2 = (ResultFile) result2;
int result = getFileNameComparator().compare(file1, file2);
if (result == 0) {
return Long.compare(file1.getFirstInstance().getId(), file2.getFirstInstance().getId());
}
return result;
}
};
}
@ -234,6 +265,7 @@ public class FileSorter implements Comparator<ResultFile> {
String string1 = s1 == null ? "" : s1;
String string2 = s2 == null ? "" : s2;
return string1.compareTo(string2);
}
/**

View File

@ -30,7 +30,7 @@ public class Group implements Comparable<Group> {
private final Group.GroupSortingAlgorithm groupSortingType;
private final DiscoveryKeyUtils.GroupKey groupKey;
private final List<ResultFile> files;
private final List<Result> results;
private final String displayName;
/**
@ -42,21 +42,23 @@ public class Group implements Comparable<Group> {
public Group(Group.GroupSortingAlgorithm groupSortingType, DiscoveryKeyUtils.GroupKey groupKey) {
this.groupSortingType = groupSortingType;
this.groupKey = groupKey;
files = new ArrayList<>();
results = new ArrayList<>();
this.displayName = groupKey.getDisplayName();
}
/**
* Add a ResultFile to the group. Will not be sorted at this time.
* Add a Result to the group. Will not be sorted at this time.
*
* @param file The ResultFile to add to the FileGroup
* @param result The Result to add to the FileGroup
*/
void addFile(ResultFile file) {
if (files.contains(file)) {
ResultFile existingCopy = files.get(files.indexOf(file)); //get the copy of this which exists in the list
existingCopy.addDuplicate(file.getFirstInstance());
void addResult(Result result) {
if (result.getType() != SearchData.Type.DOMAIN && results.contains(result)) {
//dedupe files and show instances
ResultFile existingCopy = (ResultFile)results.get(results.indexOf(result)); //get the copy of this which exists in the list
existingCopy.addDuplicate(((ResultFile)result).getFirstInstance());
} else {
files.add(file);
//Domains and non files are not being deduped currently
results.add(result);
}
}
@ -82,7 +84,7 @@ public class Group implements Comparable<Group> {
* Sort all the files in the group
*/
public void sortFiles(FileSorter sorter) {
Collections.sort(files, sorter);
Collections.sort(results, sorter);
}
/**
@ -128,8 +130,8 @@ public class Group implements Comparable<Group> {
* @return -1 if group1 should be displayed before group2, 1 otherwise
*/
private static int compareGroupsBySize(Group group1, Group group2) {
if (group1.getFiles().size() != group2.getFiles().size()) {
return -1 * Long.compare(group1.getFiles().size(), group2.getFiles().size()); // High to low
if (group1.getResults().size() != group2.getResults().size()) {
return -1 * Long.compare(group1.getResults().size(), group2.getResults().size()); // High to low
} else {
// If the groups have the same size, fall through to the BY_GROUP_NAME sorting
return compareGroupsByGroupKey(group1, group2);
@ -168,8 +170,8 @@ public class Group implements Comparable<Group> {
*
* @return List of ResultFile objects
*/
public List<ResultFile> getFiles() {
return Collections.unmodifiableList(files);
public List<Result> getResults() {
return Collections.unmodifiableList(results);
}
}

View File

@ -18,9 +18,67 @@
*/
package org.sleuthkit.autopsy.discovery.search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Interface implemented by all types of results.
*/
public interface Result {
public abstract class Result {
private SearchData.Frequency frequency;
private final List<String> tagNames = new ArrayList<>();
public abstract long getDataSourceObjectId();
/**
* Get the frequency of this result in the central repository.
*
* @return The Frequency enum.
*/
public SearchData.Frequency getFrequency() {
return frequency;
}
public abstract TskData.FileKnown getKnown();
/**
* Set the frequency of this result in the central repository.
*
* @param frequency The frequency of the result as an enum.
*/
final public void setFrequency(SearchData.Frequency frequency) {
this.frequency = frequency;
}
public abstract Content getDataSource() throws TskCoreException;
public abstract SearchData.Type getType();
/**
* Add a tag name that matched this file.
*
* @param tagName
*/
public void addTagName(String tagName) {
if (!tagNames.contains(tagName)) {
tagNames.add(tagName);
}
// Sort the list so the getTagNames() will be consistent regardless of the order added
Collections.sort(tagNames);
}
/**
* Get the tag names for this file
*
* @return the tag names that matched this file.
*/
public List<String> getTagNames() {
return Collections.unmodifiableList(tagNames);
}
}

View File

@ -18,7 +18,34 @@
*/
package org.sleuthkit.autopsy.discovery.search;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
public class ResultDomain implements Result {
public class ResultDomain extends Result {
ResultDomain() {
this.setFrequency(SearchData.Frequency.UNKNOWN);
}
@Override
public long getDataSourceObjectId() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public Content getDataSource() throws TskCoreException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public TskData.FileKnown getKnown() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public SearchData.Type getType() {
return SearchData.Type.DOMAIN;
}
}

View File

@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.discovery.search.SearchData.Type.OTHER;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.Tag;
@ -40,13 +41,11 @@ import org.sleuthkit.datamodel.TskData;
/**
* Container for files that holds all necessary data for grouping and sorting.
*/
public class ResultFile implements Result{
public class ResultFile extends Result {
private final static Logger logger = Logger.getLogger(ResultFile.class.getName());
private SearchData.Frequency frequency;
private final List<String> keywordListNames;
private final List<String> hashSetNames;
private final List<String> tagNames;
private final List<String> interestingSetNames;
private final List<String> objectDetectedNames;
private final List<AbstractFile> instances = new ArrayList<>();
@ -73,33 +72,13 @@ public class ResultFile implements Result{
deleted = true;
}
updateScoreAndDescription(abstractFile);
this.frequency = SearchData.Frequency.UNKNOWN;
keywordListNames = new ArrayList<>();
hashSetNames = new ArrayList<>();
tagNames = new ArrayList<>();
interestingSetNames = new ArrayList<>();
objectDetectedNames = new ArrayList<>();
fileType = fromMIMEtype(abstractFile.getMIMEType());
}
/**
* Get the frequency of this file in the central repository
*
* @return The Frequency enum
*/
public SearchData.Frequency getFrequency() {
return frequency;
}
/**
* Set the frequency of this file from the central repository
*
* @param frequency The frequency of the file as an enum
*/
public void setFrequency(SearchData.Frequency frequency) {
this.frequency = frequency;
}
/**
* Add an AbstractFile to the list of files which are instances of this
* file.
@ -218,29 +197,6 @@ public class ResultFile implements Result{
return Collections.unmodifiableList(hashSetNames);
}
/**
* Add a tag name that matched this file.
*
* @param tagName
*/
public void addTagName(String tagName) {
if (!tagNames.contains(tagName)) {
tagNames.add(tagName);
}
// Sort the list so the getTagNames() will be consistent regardless of the order added
Collections.sort(tagNames);
}
/**
* Get the tag names for this file
*
* @return the tag names that matched this file.
*/
public List<String> getTagNames() {
return Collections.unmodifiableList(tagNames);
}
/**
* Add an interesting file set name that matched this file.
*
@ -300,7 +256,7 @@ public class ResultFile implements Result{
public String toString() {
return getFirstInstance().getName() + "(" + getFirstInstance().getId() + ") - "
+ getFirstInstance().getSize() + ", " + getFirstInstance().getParentPath() + ", "
+ getFirstInstance().getDataSourceObjectId() + ", " + frequency.toString() + ", "
+ getFirstInstance().getDataSourceObjectId() + ", " + getFrequency().toString() + ", "
+ String.join(",", keywordListNames) + ", " + getFirstInstance().getMIMEType();
}
@ -397,4 +353,24 @@ public class ResultFile implements Result{
}
return OTHER;
}
@Override
public long getDataSourceObjectId() {
return getFirstInstance().getDataSourceObjectId();
}
@Override
public Content getDataSource() throws TskCoreException {
return getFirstInstance().getDataSource();
}
@Override
public TskData.FileKnown getKnown() {
return getFirstInstance().getKnown();
}
@Override
public Type getType() {
return fileType;
}
}

View File

@ -54,7 +54,7 @@ public class SearchFiltering {
*
* @return
*/
static List<ResultFile> runQueries(List<AbstractFilter> filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
static List<Result> runQueries(List<AbstractFilter> filters, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws DiscoveryException {
if (caseDb == null) {
throw new DiscoveryException("Case DB parameter is null"); // NON-NLS
}
@ -94,9 +94,9 @@ public class SearchFiltering {
* @throws TskCoreException
* @throws DiscoveryException
*/
private static List<ResultFile> getResultList(List<AbstractFilter> filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws TskCoreException, DiscoveryException {
private static List<Result> getResultList(List<AbstractFilter> filters, String combinedQuery, SleuthkitCase caseDb, CentralRepository centralRepoDb) throws TskCoreException, DiscoveryException {
// Get all matching abstract files
List<ResultFile> resultList = new ArrayList<>();
List<Result> resultList = new ArrayList<>();
List<AbstractFile> sqlResults = caseDb.findAllFilesWhere(combinedQuery);
// If there are no results, return now
@ -514,7 +514,7 @@ public class SearchFiltering {
}
@Override
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
public List<Result> applyAlternateFilter(List<Result> currentResults, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
// We have to have run some kind of SQL filter before getting to this point,
@ -528,8 +528,8 @@ public class SearchFiltering {
freqAttr.addAttributeToResultFiles(currentResults, caseDb, centralRepoDb);
// If the frequency matches the filter, add the file to the results
List<ResultFile> frequencyResults = new ArrayList<>();
for (ResultFile file : currentResults) {
List<Result> frequencyResults = new ArrayList<>();
for (Result file : currentResults) {
if (frequencies.contains(file.getFrequency())) {
frequencyResults.add(file);
}
@ -834,7 +834,7 @@ public class SearchFiltering {
}
@Override
public List<ResultFile> applyAlternateFilter(List<ResultFile> currentResults, SleuthkitCase caseDb,
public List<Result> applyAlternateFilter(List<Result> currentResults, SleuthkitCase caseDb,
CentralRepository centralRepoDb) throws DiscoveryException {
if (centralRepoDb == null) {
@ -848,18 +848,21 @@ public class SearchFiltering {
}
// The matching files
List<ResultFile> notableResults = new ArrayList<>();
List<Result> notableResults = new ArrayList<>();
try {
CorrelationAttributeInstance.Type type = CorrelationAttributeInstance.getDefaultCorrelationTypes().get(CorrelationAttributeInstance.FILES_TYPE_ID);
for (ResultFile file : currentResults) {
for (Result result : currentResults) {
ResultFile file = (ResultFile) result;
if (result.getType() == SearchData.Type.DOMAIN) {
break;
}
if (file.getFirstInstance().getMd5Hash() != null && !file.getFirstInstance().getMd5Hash().isEmpty()) {
// Check if this file hash is marked as notable in the CR
String value = file.getFirstInstance().getMd5Hash();
if (centralRepoDb.getCountArtifactInstancesKnownBad(type, value) > 0) {
notableResults.add(file);
notableResults.add(result);
}
}
}
@ -927,7 +930,7 @@ public class SearchFiltering {
return result;
}
private SearchFiltering(){
private SearchFiltering() {
// Class should not be instantiated
}
}

View File

@ -72,15 +72,15 @@ class SearchResults {
*
* @param files The list of ResultFiles to add.
*/
void add(List<ResultFile> files) {
for (ResultFile file : files) {
void add(List<Result> results) {
for (Result result : results) {
// Add the file to the appropriate group, creating it if necessary
GroupKey groupKey = attrType.getGroupKey(file);
GroupKey groupKey = attrType.getGroupKey(result);
if (!groupMap.containsKey(groupKey)) {
groupMap.put(groupKey, new Group(groupSortingType, groupKey));
}
groupMap.get(groupKey).addFile(file);
groupMap.get(groupKey).addResult(result);
}
}
@ -102,25 +102,25 @@ class SearchResults {
@Override
public String toString() {
String result = "";
String resultString = "";
if (groupList == null) {
return result;
return resultString;
}
long count = 0;
for (Group group : groupList) {
result += group.getDisplayName() + "\n";
resultString += group.getDisplayName() + "\n";
for (ResultFile file : group.getFiles()) {
result += " " + file.toString() + "\n";
for (Result result : group.getResults()) {
resultString += " " + result.toString() + "\n";
count++;
if (count > MAX_OUTPUT_FILES) {
result += "(truncated)";
return result;
resultString += "(truncated)";
return resultString;
}
}
}
return result;
return resultString;
}
/**
@ -129,7 +129,7 @@ class SearchResults {
* @return The list of group names.
*/
List<String> getGroupNamesWithCounts() {
return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getFiles().size() + ")").collect(Collectors.toList());
return groupList.stream().map(p -> p.getDisplayName() + " (" + p.getResults().size() + ")").collect(Collectors.toList());
}
/**
@ -139,13 +139,13 @@ class SearchResults {
*
* @return The list of result files.
*/
List<ResultFile> getResultFilesInGroup(String groupName) {
List<Result> getResultFilesInGroup(String groupName) {
if (groupName != null) {
final String modifiedGroupName = groupName.replaceAll(" \\([0-9]+\\)$", "");
java.util.Optional<Group> fileGroup = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst();
if (fileGroup.isPresent()) {
return fileGroup.get().getFiles();
java.util.Optional<Group> group = groupList.stream().filter(p -> p.getDisplayName().equals(modifiedGroupName)).findFirst();
if (group.isPresent()) {
return group.get().getResults();
}
}
return new ArrayList<>();
@ -156,15 +156,15 @@ class SearchResults {
*
* @return The grouped and sorted results.
*/
Map<GroupKey, List<ResultFile>> toLinkedHashMap() throws DiscoveryException {
Map<GroupKey, List<ResultFile>> map = new LinkedHashMap<>();
Map<GroupKey, List<Result>> toLinkedHashMap() throws DiscoveryException {
Map<GroupKey, List<Result>> map = new LinkedHashMap<>();
// Sort the groups and files
sortGroupsAndFiles();
// groupList is sorted and a LinkedHashMap will preserve that order.
for (Group group : groupList) {
map.put(group.getGroupKey(), group.getFiles());
map.put(group.getGroupKey(), group.getResults());
}
return map;

View File

@ -232,6 +232,7 @@ final class DiscoveryUiUtils {
* Helper method to display an error message when the results of the
* Discovery Top component may be incomplete.
*/
@NbBundle.Messages({"DiscoveryUiUtils.resultsIncomplete.text=Discovery results may be incomplete"})
static void displayErrorMessage(DiscoveryDialog dialog) {
//check if modules run and assemble message
try {
@ -258,7 +259,7 @@ final class DiscoveryUiUtils {
messageScrollPane.setMaximumSize(new Dimension(600, 100));
messageScrollPane.setPreferredSize(new Dimension(600, 100));
messageScrollPane.setViewportView(messageTextPane);
JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE);
JOptionPane.showMessageDialog(dialog, messageScrollPane, Bundle.DiscoveryUiUtils_resultsIncomplete_text(), JOptionPane.PLAIN_MESSAGE);
}
} catch (NoCurrentCaseException | TskCoreException ex) {
logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex);

View File

@ -62,8 +62,6 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P
return Case.isCaseOpen();
}
@NbBundle.Messages({"OpenDiscoveryAction.resultsIncomplete.text=Discovery results may be incomplete"})
@Override
public void performAction() {
SwingUtilities.invokeLater(() -> {

View File

@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.discovery.search.FileSearch;
import org.sleuthkit.autopsy.discovery.search.SearchData;
import org.sleuthkit.autopsy.discovery.search.DiscoveryException;
import org.sleuthkit.autopsy.discovery.search.FileSorter;
import org.sleuthkit.autopsy.discovery.search.ResultFile;
import org.sleuthkit.autopsy.discovery.search.Result;
/**
* SwingWorker to retrieve the contents of a page.
@ -52,7 +52,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
private final int pageSize;
private final SearchData.Type resultType;
private final CentralRepository centralRepo;
private final List<ResultFile> results = new ArrayList<>();
private final List<Result> results = new ArrayList<>();
/**
* Construct a new PageWorker.