mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-20 11:26:53 +00:00
Cleanup
This commit is contained in:
parent
aeab334710
commit
be4b528ebe
@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.newpackage;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -32,8 +31,6 @@ import org.sleuthkit.datamodel.AbstractFile;
|
|||||||
class FileGroup implements Comparable<FileGroup> {
|
class FileGroup implements Comparable<FileGroup> {
|
||||||
|
|
||||||
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
||||||
//private final FileSearch.AttributeType attrType;
|
|
||||||
private final Comparator<ResultFile> fileSortingMethod;
|
|
||||||
private final FileSearch.GroupKey groupKey;
|
private final FileSearch.GroupKey groupKey;
|
||||||
private final List<ResultFile> files;
|
private final List<ResultFile> files;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
@ -41,17 +38,11 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
/**
|
/**
|
||||||
* Create a FileGroup object with its first file.
|
* Create a FileGroup object with its first file.
|
||||||
*
|
*
|
||||||
* @param attrType The type of attribute being used for grouping
|
|
||||||
* @param groupSortingType The method for sorting the group
|
* @param groupSortingType The method for sorting the group
|
||||||
* @param fileSortingMethod The method for sorting files within the group
|
|
||||||
* @param groupKey The GroupKey for this group
|
* @param groupKey The GroupKey for this group
|
||||||
*/
|
*/
|
||||||
FileGroup(//FileSearch.AttributeType attrType,
|
FileGroup(FileGroup.GroupSortingAlgorithm groupSortingType, FileSearch.GroupKey groupKey) {
|
||||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
|
||||||
Comparator<ResultFile> fileSortingMethod, FileSearch.GroupKey groupKey) {
|
|
||||||
this.groupSortingType = groupSortingType;
|
this.groupSortingType = groupSortingType;
|
||||||
//this.attrType = attrType;
|
|
||||||
this.fileSortingMethod = fileSortingMethod;
|
|
||||||
this.groupKey = groupKey;
|
this.groupKey = groupKey;
|
||||||
files = new ArrayList<>();
|
files = new ArrayList<>();
|
||||||
this.displayName = groupKey.getDisplayName();
|
this.displayName = groupKey.getDisplayName();
|
||||||
@ -89,8 +80,8 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
/**
|
/**
|
||||||
* Sort all the files in the group
|
* Sort all the files in the group
|
||||||
*/
|
*/
|
||||||
void sortFiles() {
|
void sortFiles(FileSorter sorter) {
|
||||||
Collections.sort(files, fileSortingMethod);
|
Collections.sort(files, sorter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,28 +107,27 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
switch (groupSortingType) {
|
switch (groupSortingType) {
|
||||||
case BY_GROUP_SIZE:
|
case BY_GROUP_SIZE:
|
||||||
return compareGroupsBySize(this, otherGroup);
|
return compareGroupsBySize(this, otherGroup);
|
||||||
case BY_ATTRIBUTE:
|
case BY_GROUP_KEY:
|
||||||
default:
|
default:
|
||||||
return compareGroupsByAttribute(this, otherGroup);
|
return compareGroupsByGroupKey(this, otherGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two groups based on the grouping attribute.
|
* Compare two groups based on the group key
|
||||||
*
|
*
|
||||||
* @param group1
|
* @param group1
|
||||||
* @param group2
|
* @param group2
|
||||||
*
|
*
|
||||||
* @return -1 if group1 should be displayed before group2, 1 otherwise
|
* @return -1 if group1 should be displayed before group2, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static int compareGroupsByAttribute(FileGroup group1, FileGroup group2) {
|
private static int compareGroupsByGroupKey(FileGroup group1, FileGroup group2) {
|
||||||
return group1.groupKey.compareTo(group2.groupKey);
|
return group1.groupKey.compareTo(group2.groupKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two groups based on the group size.
|
* Compare two groups based on the group size.
|
||||||
* Falls back on the attribute if the groups are the same size.
|
* Falls back on the group key if the groups are the same size.
|
||||||
*
|
*
|
||||||
* @param group1
|
* @param group1
|
||||||
* @param group2
|
* @param group2
|
||||||
@ -148,8 +138,8 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
if (group1.files.size() != group2.files.size()) {
|
if (group1.files.size() != group2.files.size()) {
|
||||||
return -1 * Long.compare(group1.files.size(), group2.files.size()); // High to low
|
return -1 * Long.compare(group1.files.size(), group2.files.size()); // High to low
|
||||||
} else {
|
} else {
|
||||||
// If the groups have the same size, fall through to the BY_ATTRIBUTE sorting
|
// If the groups have the same size, fall through to the BY_GROUP_KEY sorting
|
||||||
return compareGroupsByAttribute(group1, group2);
|
return compareGroupsByGroupKey(group1, group2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,8 +147,8 @@ class FileGroup implements Comparable<FileGroup> {
|
|||||||
* Enum to specify how to sort the group.
|
* Enum to specify how to sort the group.
|
||||||
*/
|
*/
|
||||||
enum GroupSortingAlgorithm {
|
enum GroupSortingAlgorithm {
|
||||||
BY_GROUP_SIZE,
|
BY_GROUP_SIZE, // Sort from largest to smallest group
|
||||||
BY_ATTRIBUTE
|
BY_GROUP_KEY // Sort using the group key (for example, if grouping by size sort from largest to smallest value)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,12 @@ package org.sleuthkit.autopsy.newpackage;
|
|||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
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.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
@ -70,10 +68,10 @@ class FileSearch {
|
|||||||
* @throws FileSearchException
|
* @throws FileSearchException
|
||||||
*/
|
*/
|
||||||
static LinkedHashMap<String, List<AbstractFile>> runFileSearch(
|
static LinkedHashMap<String, List<AbstractFile>> runFileSearch(
|
||||||
List<FileSearchFiltering.SubFilter> filters,
|
List<FileSearchFiltering.FileFilter> filters,
|
||||||
AttributeType groupAttributeType,
|
AttributeType groupAttributeType,
|
||||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||||
Comparator<ResultFile> fileSortingMethod,
|
FileSorter.SortingMethod fileSortingMethod,
|
||||||
List<AttributeType> attributesNeededForGroupingOrSorting,
|
List<AttributeType> attributesNeededForGroupingOrSorting,
|
||||||
SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
@ -84,11 +82,8 @@ class FileSearch {
|
|||||||
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
|
addAttributes(attributesNeededForGroupingOrSorting, resultFiles, caseDb, centralRepoDb);
|
||||||
|
|
||||||
// Collect everything in the search results
|
// Collect everything in the search results
|
||||||
// TODO move add into Searchresults
|
|
||||||
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||||
for (ResultFile file : resultFiles) {
|
searchResults.add(resultFiles);
|
||||||
searchResults.add(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a version of the results in general Java objects
|
// Return a version of the results in general Java objects
|
||||||
return searchResults.toLinkedHashMap();
|
return searchResults.toLinkedHashMap();
|
||||||
@ -112,20 +107,6 @@ class FileSearch {
|
|||||||
attr.addAttributeToResultFiles(resultFiles, caseDb, centralRepoDb);
|
attr.addAttributeToResultFiles(resultFiles, caseDb, centralRepoDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a comparator for sorting on file name
|
|
||||||
*
|
|
||||||
* @return comparator for case-insensitive sort on the abstract file name field
|
|
||||||
*/
|
|
||||||
static Comparator<ResultFile> getFileNameComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file2.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for the grouping attributes.
|
* Base class for the grouping attributes.
|
||||||
@ -141,13 +122,6 @@ class FileSearch {
|
|||||||
*/
|
*/
|
||||||
abstract GroupKey getGroupKey(ResultFile file);
|
abstract GroupKey getGroupKey(ResultFile file);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the file comparator based on this attribute.
|
|
||||||
*
|
|
||||||
* @return the file comparator based on this attribute
|
|
||||||
*/
|
|
||||||
abstract Comparator<ResultFile> getDefaultFileComparator();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add any extra data to the ResultFile object from this attribute.
|
* Add any extra data to the ResultFile object from this attribute.
|
||||||
*
|
*
|
||||||
@ -216,25 +190,12 @@ class FileSearch {
|
|||||||
GroupKey getGroupKey(ResultFile file) {
|
GroupKey getGroupKey(ResultFile file) {
|
||||||
return new FileSizeGroupKey(file);
|
return new FileSizeGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
// Sort large to small
|
|
||||||
if (file1.getAbstractFile().getSize() != file2.getAbstractFile().getSize()) {
|
|
||||||
return -1 * Long.compare(file1.getAbstractFile().getSize(), file2.getAbstractFile().getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secondary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FileSizeGroupKey extends GroupKey {
|
/**
|
||||||
|
* Key representing a file size group
|
||||||
|
*/
|
||||||
|
private static class FileSizeGroupKey extends GroupKey {
|
||||||
private final FileSize fileSize;
|
private final FileSize fileSize;
|
||||||
|
|
||||||
FileSizeGroupKey(ResultFile file) {
|
FileSizeGroupKey(ResultFile file) {
|
||||||
@ -285,37 +246,12 @@ class FileSearch {
|
|||||||
GroupKey getGroupKey(ResultFile file) {
|
GroupKey getGroupKey(ResultFile file) {
|
||||||
return new ParentPathGroupKey(file);
|
return new ParentPathGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
// Handle missing paths
|
|
||||||
if (file1.getAbstractFile().getParentPath() == null) {
|
|
||||||
if (file2.getAbstractFile().getParentPath() == null) {
|
|
||||||
// Secondary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if (file2.getAbstractFile().getParentPath() == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secondary sort on file name if the parent paths are the same
|
|
||||||
if (file1.getAbstractFile().getParentPath().equals(file2.getAbstractFile().getParentPath())) {
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case insensitive comparison on the parent path
|
|
||||||
return file1.getAbstractFile().getParentPath().compareToIgnoreCase(file2.getAbstractFile().getParentPath());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ParentPathGroupKey extends GroupKey {
|
/**
|
||||||
|
* Key representing a parent path group
|
||||||
|
*/
|
||||||
|
private static class ParentPathGroupKey extends GroupKey {
|
||||||
private final String parentPath;
|
private final String parentPath;
|
||||||
|
|
||||||
ParentPathGroupKey(ResultFile file) {
|
ParentPathGroupKey(ResultFile file) {
|
||||||
@ -370,25 +306,12 @@ class FileSearch {
|
|||||||
GroupKey getGroupKey(ResultFile file) {
|
GroupKey getGroupKey(ResultFile file) {
|
||||||
return new DataSourceGroupKey(file);
|
return new DataSourceGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
// Primary sort on data source object ID, small to large
|
|
||||||
if (file1.getAbstractFile().getDataSourceObjectId() != file2.getAbstractFile().getDataSourceObjectId()) {
|
|
||||||
return Long.compare(file1.getAbstractFile().getDataSourceObjectId(), file2.getAbstractFile().getDataSourceObjectId());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secondary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DataSourceGroupKey extends GroupKey {
|
/**
|
||||||
|
* Key representing a data source group
|
||||||
|
*/
|
||||||
|
private static class DataSourceGroupKey extends GroupKey {
|
||||||
private final long dataSourceID;
|
private final long dataSourceID;
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
|
||||||
@ -457,42 +380,6 @@ class FileSearch {
|
|||||||
return new FileTypeGroupKey(file);
|
return new FileTypeGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
if (file1.getFileType() != file2.getFileType()) {
|
|
||||||
// Primary sort on the file type enum
|
|
||||||
return Integer.compare(file1.getFileType().getRanking(), file2.getFileType().getRanking());
|
|
||||||
} else {
|
|
||||||
String mimeType1 = file1.getAbstractFile().getMIMEType();
|
|
||||||
String mimeType2 = file2.getAbstractFile().getMIMEType();
|
|
||||||
|
|
||||||
// Handle missing MIME types
|
|
||||||
if (mimeType1 == null) {
|
|
||||||
if (mimeType2 == null) {
|
|
||||||
// Tertiary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if (mimeType2 == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secondary sort on MIME type
|
|
||||||
if ( ! StringUtils.equals(mimeType1, mimeType2)) {
|
|
||||||
return mimeType1.compareToIgnoreCase(mimeType2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tertiary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
EamDb centralRepoDb) throws FileSearchException {
|
EamDb centralRepoDb) throws FileSearchException {
|
||||||
@ -504,7 +391,10 @@ class FileSearch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FileTypeGroupKey extends GroupKey {
|
/**
|
||||||
|
* Key representing a file type group
|
||||||
|
*/
|
||||||
|
private static class FileTypeGroupKey extends GroupKey {
|
||||||
private final FileType fileType;
|
private final FileType fileType;
|
||||||
|
|
||||||
FileTypeGroupKey(ResultFile file) {
|
FileTypeGroupKey(ResultFile file) {
|
||||||
@ -556,34 +446,6 @@ class FileSearch {
|
|||||||
return new KeywordListGroupKey(file);
|
return new KeywordListGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
|
|
||||||
// TODO fix sort
|
|
||||||
// Force "no keyword hits" to the bottom
|
|
||||||
if (! file1.hasKeywords()) {
|
|
||||||
if (! file2.hasKeywords()) {
|
|
||||||
// Secondary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}else if (! file2.hasKeywords()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file1.getKeywordListNames().equals(file2.getKeywordListNames())) {
|
|
||||||
// Secondary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
//return file1.getKeywordListNames().compareToIgnoreCase(file2.getKeywordListNames());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
EamDb centralRepoDb) throws FileSearchException {
|
EamDb centralRepoDb) throws FileSearchException {
|
||||||
@ -658,8 +520,11 @@ class FileSearch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class KeywordListGroupKey extends GroupKey {
|
/**
|
||||||
|
* Key representing a keyword list group
|
||||||
|
*/
|
||||||
|
private static class KeywordListGroupKey extends GroupKey {
|
||||||
private final List<String> keywordListNames;
|
private final List<String> keywordListNames;
|
||||||
private final String keywordListNamesString;
|
private final String keywordListNamesString;
|
||||||
|
|
||||||
@ -672,11 +537,10 @@ class FileSearch {
|
|||||||
if (keywordListNames.isEmpty()) {
|
if (keywordListNames.isEmpty()) {
|
||||||
keywordListNamesString = Bundle.FileSearch_KeywordListGroupKey_noKeywords();
|
keywordListNamesString = Bundle.FileSearch_KeywordListGroupKey_noKeywords();
|
||||||
} else {
|
} else {
|
||||||
keywordListNamesString = String.join(",", keywordListNames);
|
keywordListNamesString = String.join(",", keywordListNames); // NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getDisplayName() {
|
String getDisplayName() {
|
||||||
return keywordListNamesString;
|
return keywordListNamesString;
|
||||||
@ -686,6 +550,18 @@ class FileSearch {
|
|||||||
public int compareTo(GroupKey otherGroupKey) {
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
if (otherGroupKey instanceof KeywordListGroupKey) {
|
if (otherGroupKey instanceof KeywordListGroupKey) {
|
||||||
KeywordListGroupKey otherKeywordListNamesGroupKey = (KeywordListGroupKey)otherGroupKey;
|
KeywordListGroupKey otherKeywordListNamesGroupKey = (KeywordListGroupKey)otherGroupKey;
|
||||||
|
|
||||||
|
// Put the empty list at the end
|
||||||
|
if (keywordListNames.isEmpty()) {
|
||||||
|
if (otherKeywordListNamesGroupKey.keywordListNames.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (otherKeywordListNamesGroupKey.keywordListNames.isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return keywordListNamesString.compareTo(otherKeywordListNamesGroupKey.keywordListNamesString);
|
return keywordListNamesString.compareTo(otherKeywordListNamesGroupKey.keywordListNamesString);
|
||||||
} else {
|
} else {
|
||||||
return compareClassNames(otherGroupKey);
|
return compareClassNames(otherGroupKey);
|
||||||
@ -701,7 +577,7 @@ class FileSearch {
|
|||||||
if (!(otherKey instanceof KeywordListGroupKey)) {
|
if (!(otherKey instanceof KeywordListGroupKey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO put no kw group last
|
|
||||||
KeywordListGroupKey otherKeywordListGroupKey = (KeywordListGroupKey)otherKey;
|
KeywordListGroupKey otherKeywordListGroupKey = (KeywordListGroupKey)otherKey;
|
||||||
return keywordListNamesString.equals(otherKeywordListGroupKey.keywordListNamesString);
|
return keywordListNamesString.equals(otherKeywordListGroupKey.keywordListNamesString);
|
||||||
}
|
}
|
||||||
@ -722,21 +598,6 @@ class FileSearch {
|
|||||||
return new FrequencyGroupKey(file);
|
return new FrequencyGroupKey(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
return new Comparator<ResultFile>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
if (file1.getFrequency() != file2.getFrequency()) {
|
|
||||||
return Long.compare(file1.getFrequency().getRanking(), file2.getFrequency().getRanking());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Secondary sort on file name
|
|
||||||
return file1.getAbstractFile().getName().compareToIgnoreCase(file1.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb,
|
||||||
EamDb centralRepoDb) throws FileSearchException {
|
EamDb centralRepoDb) throws FileSearchException {
|
||||||
@ -763,7 +624,10 @@ class FileSearch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FrequencyGroupKey extends GroupKey {
|
/**
|
||||||
|
* Key representing a central repository frequency group
|
||||||
|
*/
|
||||||
|
private static class FrequencyGroupKey extends GroupKey {
|
||||||
private final Frequency frequency;
|
private final Frequency frequency;
|
||||||
|
|
||||||
FrequencyGroupKey(ResultFile file) {
|
FrequencyGroupKey(ResultFile file) {
|
||||||
@ -814,15 +678,12 @@ class FileSearch {
|
|||||||
GroupKey getGroupKey(ResultFile file) {
|
GroupKey getGroupKey(ResultFile file) {
|
||||||
return new NoGroupingGroupKey();
|
return new NoGroupingGroupKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Comparator<ResultFile> getDefaultFileComparator() {
|
|
||||||
// Default to sort by file name
|
|
||||||
return FileSearch.getFileNameComparator();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NoGroupingGroupKey extends GroupKey {
|
/**
|
||||||
|
* Dummy key for when there is no grouping. All files will have the same key.
|
||||||
|
*/
|
||||||
|
private static class NoGroupingGroupKey extends GroupKey {
|
||||||
|
|
||||||
NoGroupingGroupKey() {
|
NoGroupingGroupKey() {
|
||||||
// Nothing to save - all files will get the same GroupKey
|
// Nothing to save - all files will get the same GroupKey
|
||||||
@ -838,6 +699,7 @@ class FileSearch {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(GroupKey otherGroupKey) {
|
public int compareTo(GroupKey otherGroupKey) {
|
||||||
|
// As long as the other key is the same type, they are equal
|
||||||
if (otherGroupKey instanceof NoGroupingGroupKey) {
|
if (otherGroupKey instanceof NoGroupingGroupKey) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -855,6 +717,7 @@ class FileSearch {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As long as the other key is the same type, they are equal
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,13 +33,17 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run various filters to return a subset of files from the current case.
|
* Run various filters to return a subset of files from the current case.
|
||||||
*/
|
*/
|
||||||
class FileSearchFiltering {
|
class FileSearchFiltering {
|
||||||
|
|
||||||
|
private final static Logger logger = Logger.getLogger(FileSearchFiltering.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the given filters to get a list of matching files.
|
* Run the given filters to get a list of matching files.
|
||||||
*
|
*
|
||||||
@ -48,39 +52,37 @@ class FileSearchFiltering {
|
|||||||
* @param crDb The central repo. Can be null as long as no filters need it.
|
* @param crDb The central repo. Can be null as long as no filters need it.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static List<ResultFile> runQueries(List<SubFilter> filters, SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
static List<ResultFile> runQueries(List<FileFilter> filters, SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
if (caseDb == null) {
|
if (caseDb == null) {
|
||||||
throw new FileSearchException("Case DB parameter is null"); // NON-NLS
|
throw new FileSearchException("Case DB parameter is null"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug - print out the current filters. Could perhaps be an info statement.
|
// Record the selected filters
|
||||||
System.out.println("Running filters: ");
|
String filterStr = "";
|
||||||
for (SubFilter filter : filters) {
|
for (FileFilter filter : filters) {
|
||||||
System.out.println(" " + filter.getDesc());
|
filterStr += " " + filter.getDesc() + "\n";
|
||||||
}
|
}
|
||||||
System.out.println("\n");
|
logger.log(Level.INFO, "Running filters:\n{0}", filterStr);
|
||||||
|
|
||||||
// Combine all the SQL queries from the filters into one query
|
// Combine all the SQL queries from the filters into one query
|
||||||
// TODO - maybe exclude directories and other non-file objects?
|
// TODO - maybe exclude directories and other non-file objects?
|
||||||
String combinedQuery = "";
|
String combinedQuery = "";
|
||||||
for (SubFilter subFilter : filters) {
|
for (FileFilter filter : filters) {
|
||||||
if ( ! subFilter.getSQL().isEmpty()) {
|
if ( ! filter.getWhereClause().isEmpty()) {
|
||||||
if ( ! combinedQuery.isEmpty()) {
|
if ( ! combinedQuery.isEmpty()) {
|
||||||
combinedQuery += " AND "; // NON-NLS
|
combinedQuery += " AND "; // NON-NLS
|
||||||
}
|
}
|
||||||
combinedQuery += "(" + subFilter.getSQL() + ")"; // NON-NLS
|
combinedQuery += "(" + filter.getWhereClause() + ")"; // NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Get all matching abstract files
|
// Get all matching abstract files
|
||||||
List<ResultFile> resultList = new ArrayList<>();
|
List<ResultFile> resultList = new ArrayList<>();
|
||||||
|
|
||||||
// Debug - print the SQL. could also be info
|
|
||||||
System.out.println("SQL query: " + combinedQuery + "\n");
|
|
||||||
|
|
||||||
if ( ! combinedQuery.isEmpty()) {
|
if ( ! combinedQuery.isEmpty()) {
|
||||||
|
logger.log(Level.INFO, "Running SQL query: {0}", combinedQuery);
|
||||||
List<AbstractFile> sqlResults = caseDb.findAllFilesWhere(combinedQuery);
|
List<AbstractFile> sqlResults = caseDb.findAllFilesWhere(combinedQuery);
|
||||||
|
|
||||||
// If there are no results, return now
|
// If there are no results, return now
|
||||||
@ -95,11 +97,12 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now run any non-SQL filters. Note that resultList could be empty at this point if we had no SQL queries -
|
// Now run any non-SQL filters. Note that resultList could be empty at this point if we had no SQL queries -
|
||||||
// getMatchingFiles() will interpret this as no filters have been run up to this point
|
// applyAlternateFilter() will interpret this as no filters have been run up to this point
|
||||||
// and act accordingly.
|
// and act accordingly.
|
||||||
for (SubFilter subFilter : filters) {
|
// TODO maybe it is an error to have no SQL query
|
||||||
if (subFilter.useAlternameFilter()) { // TODO typo
|
for (FileFilter subFilter : filters) {
|
||||||
resultList = subFilter.getMatchingFiles(resultList, caseDb, centralRepoDb); // TODO rename
|
if (subFilter.useAlternateFilter()) {
|
||||||
|
resultList = subFilter.applyAlternateFilter(resultList, caseDb, centralRepoDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are no matches for the filters run so far, so return
|
// There are no matches for the filters run so far, so return
|
||||||
@ -117,18 +120,18 @@ class FileSearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* Base class for the filters.
|
* Base class for the filters.
|
||||||
*/
|
*/
|
||||||
static abstract class SubFilter {
|
static abstract class FileFilter {
|
||||||
/**
|
/**
|
||||||
* Returns part of a query on the tsk_files table that can be AND-ed with other pieces
|
* Returns part of a query on the tsk_files table that can be AND-ed with other pieces
|
||||||
* @return the SQL query or an empty string if there is no SQL query for this filter.
|
* @return the SQL query or an empty string if there is no SQL query for this filter.
|
||||||
*/
|
*/
|
||||||
abstract String getSQL();
|
abstract String getWhereClause();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this filter needs to use the secondary, non-SQL method getMatchingFiles().
|
* Indicates whether this filter needs to use the secondary, non-SQL method applyAlternateFilter().
|
||||||
* @return false by default
|
* @return false by default
|
||||||
*/
|
*/
|
||||||
boolean useAlternameFilter() {
|
boolean useAlternateFilter() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +148,7 @@ class FileSearchFiltering {
|
|||||||
*
|
*
|
||||||
* @throws FileSearchException
|
* @throws FileSearchException
|
||||||
*/
|
*/
|
||||||
List<ResultFile> getMatchingFiles (List<ResultFile> currentResults, SleuthkitCase caseDb,
|
List<ResultFile> applyAlternateFilter (List<ResultFile> currentResults, SleuthkitCase caseDb,
|
||||||
EamDb centralRepoDb) throws FileSearchException {
|
EamDb centralRepoDb) throws FileSearchException {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
@ -161,7 +164,7 @@ class FileSearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying the file size
|
* A filter for specifying the file size
|
||||||
*/
|
*/
|
||||||
static class SizeSubFilter extends SubFilter {
|
static class SizeSubFilter extends FileFilter {
|
||||||
private final List<FileSize> fileSizes;
|
private final List<FileSize> fileSizes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +177,7 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getSQL() {
|
String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (FileSize size : fileSizes) {
|
for (FileSize size : fileSizes) {
|
||||||
if (! queryStr.isEmpty()) {
|
if (! queryStr.isEmpty()) {
|
||||||
@ -249,7 +252,7 @@ class FileSearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying parent path (either full path or substring)
|
* A filter for specifying parent path (either full path or substring)
|
||||||
*/
|
*/
|
||||||
static class ParentSubFilter extends SubFilter {
|
static class ParentSubFilter extends FileFilter {
|
||||||
private final List<ParentSearchTerm> parentSearchTerms;
|
private final List<ParentSearchTerm> parentSearchTerms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,7 +265,7 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getSQL() {
|
String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (ParentSearchTerm searchTerm : parentSearchTerms) {
|
for (ParentSearchTerm searchTerm : parentSearchTerms) {
|
||||||
if (! queryStr.isEmpty()) {
|
if (! queryStr.isEmpty()) {
|
||||||
@ -301,7 +304,7 @@ class FileSearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying data sources
|
* A filter for specifying data sources
|
||||||
*/
|
*/
|
||||||
static class DataSourceSubFilter extends SubFilter {
|
static class DataSourceSubFilter extends FileFilter {
|
||||||
private final List<DataSource> dataSources;
|
private final List<DataSource> dataSources;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -314,7 +317,7 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getSQL() {
|
String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (DataSource ds : dataSources) {
|
for (DataSource ds : dataSources) {
|
||||||
if (! queryStr.isEmpty()) {
|
if (! queryStr.isEmpty()) {
|
||||||
@ -352,7 +355,7 @@ class FileSearchFiltering {
|
|||||||
* A filter for specifying keyword list names.
|
* A filter for specifying keyword list names.
|
||||||
* A file must contain a keyword from one of the given lists to pass.
|
* A file must contain a keyword from one of the given lists to pass.
|
||||||
*/
|
*/
|
||||||
static class KeywordListSubFilter extends SubFilter {
|
static class KeywordListSubFilter extends FileFilter {
|
||||||
private final List<String> listNames;
|
private final List<String> listNames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -364,7 +367,7 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getSQL() {
|
String getWhereClause() {
|
||||||
String keywordListPart = ""; // NON-NLS
|
String keywordListPart = ""; // NON-NLS
|
||||||
for (String listName : listNames) {
|
for (String listName : listNames) {
|
||||||
if (! keywordListPart.isEmpty()) {
|
if (! keywordListPart.isEmpty()) {
|
||||||
@ -402,7 +405,7 @@ class FileSearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying file types.
|
* A filter for specifying file types.
|
||||||
*/
|
*/
|
||||||
static class FileTypeSubFilter extends SubFilter {
|
static class FileTypeSubFilter extends FileFilter {
|
||||||
private final List<FileTypeUtils.FileTypeCategory> categories;
|
private final List<FileTypeUtils.FileTypeCategory> categories;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -414,7 +417,7 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getSQL() {
|
String getWhereClause() {
|
||||||
String queryStr = ""; // NON-NLS
|
String queryStr = ""; // NON-NLS
|
||||||
for (FileTypeUtils.FileTypeCategory cat : categories) {
|
for (FileTypeUtils.FileTypeCategory cat : categories) {
|
||||||
for (String type : cat.getMediaTypes()) {
|
for (String type : cat.getMediaTypes()) {
|
||||||
@ -450,7 +453,7 @@ class FileSearchFiltering {
|
|||||||
/**
|
/**
|
||||||
* A filter for specifying frequency in the central repository.
|
* A filter for specifying frequency in the central repository.
|
||||||
*/
|
*/
|
||||||
static class FrequencySubFilter extends SubFilter {
|
static class FrequencySubFilter extends FileFilter {
|
||||||
|
|
||||||
private final List<Frequency> frequencies;
|
private final List<Frequency> frequencies;
|
||||||
|
|
||||||
@ -464,19 +467,19 @@ class FileSearchFiltering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getSQL() {
|
String getWhereClause() {
|
||||||
// Since this relies on the central repository database, there is no
|
// Since this relies on the central repository database, there is no
|
||||||
// query on the case database.
|
// query on the case database.
|
||||||
return ""; // NON-NLS
|
return ""; // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean useAlternameFilter() {
|
boolean useAlternateFilter() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
List<ResultFile> getMatchingFiles (List<ResultFile> currentResults, SleuthkitCase caseDb,
|
List<ResultFile> applyAlternateFilter (List<ResultFile> currentResults, SleuthkitCase caseDb,
|
||||||
EamDb centralRepoDb) throws FileSearchException {
|
EamDb centralRepoDb) throws FileSearchException {
|
||||||
|
|
||||||
if (centralRepoDb == null) {
|
if (centralRepoDb == null) {
|
||||||
|
@ -20,32 +20,15 @@ package org.sleuthkit.autopsy.newpackage;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.nio.file.InvalidPathException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import java.beans.PropertyChangeEvent;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import java.awt.Frame;
|
|
||||||
import javax.swing.SwingWorker;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.openide.awt.ActionID;
|
import org.openide.awt.ActionID;
|
||||||
import org.openide.awt.ActionReference;
|
import org.openide.awt.ActionReference;
|
||||||
import org.openide.awt.ActionRegistration;
|
import org.openide.awt.ActionRegistration;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.windows.WindowManager;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.utils.FileTypeUtils;
|
import org.sleuthkit.autopsy.datamodel.utils.FileTypeUtils;
|
||||||
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
|
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.newpackage.FileSearchTestAction")
|
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.newpackage.FileSearchTestAction")
|
||||||
@ -68,27 +51,27 @@ public final class FileSearchTestAction extends CallableSystemAction {
|
|||||||
System.out.println("\n#########################\nTesting file search!!!");
|
System.out.println("\n#########################\nTesting file search!!!");
|
||||||
|
|
||||||
// Set up all the test filters
|
// Set up all the test filters
|
||||||
FileSearchFiltering.SubFilter size_medSmallXS = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.MEDIUM, FileSearchData.FileSize.SMALL, FileSearchData.FileSize.XS));
|
FileSearchFiltering.FileFilter size_medSmallXS = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.MEDIUM, FileSearchData.FileSize.SMALL, FileSearchData.FileSize.XS));
|
||||||
FileSearchFiltering.SubFilter size_XL = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.XL));
|
FileSearchFiltering.FileFilter size_XL = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.XL));
|
||||||
FileSearchFiltering.SubFilter size_largeXL = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.LARGE, FileSearchData.FileSize.XL));
|
FileSearchFiltering.FileFilter size_largeXL = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.LARGE, FileSearchData.FileSize.XL));
|
||||||
FileSearchFiltering.SubFilter size_medLargeXL = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.MEDIUM, FileSearchData.FileSize.LARGE, FileSearchData.FileSize.XL));
|
FileSearchFiltering.FileFilter size_medLargeXL = new FileSearchFiltering.SizeSubFilter(Arrays.asList(FileSearchData.FileSize.MEDIUM, FileSearchData.FileSize.LARGE, FileSearchData.FileSize.XL));
|
||||||
|
|
||||||
FileSearchFiltering.SubFilter kw_alphaBeta = new FileSearchFiltering.KeywordListSubFilter(Arrays.asList("Alpha", "Beta"));
|
FileSearchFiltering.FileFilter kw_alphaBeta = new FileSearchFiltering.KeywordListSubFilter(Arrays.asList("Alpha", "Beta"));
|
||||||
FileSearchFiltering.SubFilter kw_alpha = new FileSearchFiltering.KeywordListSubFilter(Arrays.asList("Alpha"));
|
FileSearchFiltering.FileFilter kw_alpha = new FileSearchFiltering.KeywordListSubFilter(Arrays.asList("Alpha"));
|
||||||
|
|
||||||
FileSearchFiltering.SubFilter freq_uniqueRare = new FileSearchFiltering.FrequencySubFilter(Arrays.asList(FileSearchData.Frequency.UNIQUE, FileSearchData.Frequency.RARE));
|
FileSearchFiltering.FileFilter freq_uniqueRare = new FileSearchFiltering.FrequencySubFilter(Arrays.asList(FileSearchData.Frequency.UNIQUE, FileSearchData.Frequency.RARE));
|
||||||
|
|
||||||
FileSearchFiltering.SubFilter path_II = new FileSearchFiltering.ParentSubFilter(Arrays.asList(new FileSearchFiltering.ParentSearchTerm("II", false)));
|
FileSearchFiltering.FileFilter path_II = new FileSearchFiltering.ParentSubFilter(Arrays.asList(new FileSearchFiltering.ParentSearchTerm("II", false)));
|
||||||
FileSearchFiltering.SubFilter path_IIfolderA = new FileSearchFiltering.ParentSubFilter(Arrays.asList(new FileSearchFiltering.ParentSearchTerm("II", false),
|
FileSearchFiltering.FileFilter path_IIfolderA = new FileSearchFiltering.ParentSubFilter(Arrays.asList(new FileSearchFiltering.ParentSearchTerm("II", false),
|
||||||
new FileSearchFiltering.ParentSearchTerm("/Rare in CR/Folder A/", true)));
|
new FileSearchFiltering.ParentSearchTerm("/Rare in CR/Folder A/", true)));
|
||||||
|
|
||||||
FileSearchFiltering.SubFilter type_video = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.VIDEO));
|
FileSearchFiltering.FileFilter type_video = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.VIDEO));
|
||||||
FileSearchFiltering.SubFilter type_imageAudio = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.IMAGE,
|
FileSearchFiltering.FileFilter type_imageAudio = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.IMAGE,
|
||||||
FileTypeUtils.FileTypeCategory.AUDIO));
|
FileTypeUtils.FileTypeCategory.AUDIO));
|
||||||
FileSearchFiltering.SubFilter type_image = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.IMAGE));
|
FileSearchFiltering.FileFilter type_image = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.IMAGE));
|
||||||
FileSearchFiltering.SubFilter type_doc = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.DOCUMENTS));
|
FileSearchFiltering.FileFilter type_doc = new FileSearchFiltering.FileTypeSubFilter(Arrays.asList(FileTypeUtils.FileTypeCategory.DOCUMENTS));
|
||||||
|
|
||||||
FileSearchFiltering.SubFilter ds_46 = null;
|
FileSearchFiltering.FileFilter ds_46 = null;
|
||||||
try {
|
try {
|
||||||
DataSource ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(46);
|
DataSource ds = Case.getCurrentCase().getSleuthkitCase().getDataSource(46);
|
||||||
ds_46 = new FileSearchFiltering.DataSourceSubFilter(Arrays.asList(ds));
|
ds_46 = new FileSearchFiltering.DataSourceSubFilter(Arrays.asList(ds));
|
||||||
@ -97,14 +80,15 @@ public final class FileSearchTestAction extends CallableSystemAction {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// Set up test
|
// Set up test
|
||||||
|
|
||||||
// Select test filters
|
// Select test filters
|
||||||
List<FileSearchFiltering.SubFilter> filters = new ArrayList<>();
|
List<FileSearchFiltering.FileFilter> filters = new ArrayList<>();
|
||||||
filters.add(size_medSmallXS);
|
filters.add(size_medSmallXS);
|
||||||
//filters.add(kw_alpha);
|
//filters.add(kw_alpha);
|
||||||
filters.add(freq_uniqueRare);
|
//filters.add(freq_uniqueRare);
|
||||||
|
|
||||||
// Choose grouping attribute
|
// Choose grouping attribute
|
||||||
//FileSearch.AttributeType groupingAttr = new FileSearch.FileTypeAttribute();
|
//FileSearch.AttributeType groupingAttr = new FileSearch.FileTypeAttribute();
|
||||||
@ -112,17 +96,14 @@ public final class FileSearchTestAction extends CallableSystemAction {
|
|||||||
FileSearch.AttributeType groupingAttr = new FileSearch.KeywordListAttribute();
|
FileSearch.AttributeType groupingAttr = new FileSearch.KeywordListAttribute();
|
||||||
//FileSearch.AttributeType groupingAttr = new FileSearch.FrequencyAttribute();
|
//FileSearch.AttributeType groupingAttr = new FileSearch.FrequencyAttribute();
|
||||||
//FileSearch.AttributeType groupingAttr = new FileSearch.ParentPathAttribute();
|
//FileSearch.AttributeType groupingAttr = new FileSearch.ParentPathAttribute();
|
||||||
|
//FileSearch.AttributeType groupingAttr = new FileSearch.NoGroupingAttribute();
|
||||||
|
|
||||||
// Choose group sorting method
|
// Choose group sorting method
|
||||||
//FileGroup.GroupSortingAlgorithm groupSortAlgorithm = FileGroup.GroupSortingAlgorithm.BY_ATTRIBUTE;
|
FileGroup.GroupSortingAlgorithm groupSortAlgorithm = FileGroup.GroupSortingAlgorithm.BY_GROUP_KEY;
|
||||||
FileGroup.GroupSortingAlgorithm groupSortAlgorithm = FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE;
|
//FileGroup.GroupSortingAlgorithm groupSortAlgorithm = FileGroup.GroupSortingAlgorithm.BY_GROUP_SIZE;
|
||||||
|
|
||||||
// Choose file sorting method
|
// Choose file sorting method
|
||||||
Comparator<ResultFile> fileSort = FileSearch.getFileNameComparator();
|
FileSorter.SortingMethod fileSort = FileSorter.SortingMethod.BY_FILE_SIZE;
|
||||||
//Comparator<ResultFile> fileSort = new FileSearch.FrequencyAttribute().getDefaultFileComparator();
|
|
||||||
//Comparator<ResultFile> fileSort = new FileSearch.FileSizeAttribute().getDefaultFileComparator();
|
|
||||||
//Comparator<ResultFile> fileSort = new FileSearch.ParentPathAttribute().getDefaultFileComparator();
|
|
||||||
//Comparator<ResultFile> fileSort = new FileSearch.FileTypeAttribute().getDefaultFileComparator();
|
|
||||||
|
|
||||||
EamDb crDb = null;
|
EamDb crDb = null;
|
||||||
if (EamDb.isEnabled()) {
|
if (EamDb.isEnabled()) {
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
* Autopsy Forensic Browser
|
||||||
* To change this template file, choose Tools | Templates
|
*
|
||||||
* and open the template in the editor.
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.newpackage;
|
package org.sleuthkit.autopsy.newpackage;
|
||||||
|
|
||||||
@ -10,15 +23,22 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Class used to sort ResultFiles using the supplied method.
|
||||||
*/
|
*/
|
||||||
class FileSorter implements Comparator<ResultFile> {
|
class FileSorter implements Comparator<ResultFile> {
|
||||||
|
|
||||||
List<Comparator<ResultFile>> comparators = new ArrayList<>();
|
private final List<Comparator<ResultFile>> comparators = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the sorter using the supplied sorting method.
|
||||||
|
* The sorting is defined by a list of ResultFile comparators. These
|
||||||
|
* comparators will be run in order until one returns a non-zero result.
|
||||||
|
*
|
||||||
|
* @param method The method that should be used to sort the files
|
||||||
|
*/
|
||||||
FileSorter(SortingMethod method) {
|
FileSorter(SortingMethod method) {
|
||||||
|
|
||||||
// Set up the comparators that should run on the files
|
// Set up the primary comparators that should applied to the files
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case BY_DATA_SOURCE:
|
case BY_DATA_SOURCE:
|
||||||
comparators.add(getDataSourceComparator());
|
comparators.add(getDataSourceComparator());
|
||||||
@ -34,12 +54,16 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
comparators.add(getFrequencyComparator());
|
comparators.add(getFrequencyComparator());
|
||||||
break;
|
break;
|
||||||
case BY_KEYWORD_LIST_NAMES:
|
case BY_KEYWORD_LIST_NAMES:
|
||||||
|
comparators.add(getKeywordListNameComparator());
|
||||||
break;
|
break;
|
||||||
case BY_PARENT_PATH:
|
case BY_PARENT_PATH:
|
||||||
|
comparators.add(getParentPathComparator());
|
||||||
break;
|
break;
|
||||||
case BY_FILE_NAME:
|
case BY_FILE_NAME:
|
||||||
comparators.add(getFileNameComparator());
|
comparators.add(getFileNameComparator());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
// The default comparator will be added afterward
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,73 +75,106 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
@Override
|
@Override
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
public int compare(ResultFile file1, ResultFile file2) {
|
||||||
|
|
||||||
return 0;
|
int result = 0;
|
||||||
|
for (Comparator<ResultFile> comp : comparators) {
|
||||||
|
result = comp.compare(file1, file2);
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The files are the same
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files using data source ID. Will order smallest to largest.
|
||||||
|
*
|
||||||
|
* @return -1 if file1 has the lower data source ID, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getDataSourceComparator() {
|
private static Comparator<ResultFile> getDataSourceComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> Long.compare(file1.getAbstractFile().getDataSourceObjectId(), file2.getAbstractFile().getDataSourceObjectId());
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
// Sort large to small
|
|
||||||
return Long.compare(file1.getAbstractFile().getDataSourceObjectId(), file2.getAbstractFile().getDataSourceObjectId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files using their FileType enum. Orders based on the ranking
|
||||||
|
* in the FileType enum.
|
||||||
|
*
|
||||||
|
* @return -1 if file1 has the lower FileType value, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getFileTypeComparator() {
|
private static Comparator<ResultFile> getFileTypeComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFileType().getRanking(), file2.getFileType().getRanking());
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
return Integer.compare(file1.getFileType().getRanking(), file2.getFileType().getRanking());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files using a concatenated version of keyword list names. Alphabetical by
|
||||||
|
* the list names with files with no keyword list hits going last.
|
||||||
|
*
|
||||||
|
* @return -1 if file1 has the earliest combined keyword list name, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
|
private static Comparator<ResultFile> getKeywordListNameComparator() {
|
||||||
|
return (ResultFile file1, ResultFile file2) -> {
|
||||||
|
// Put empty lists at the bottom
|
||||||
|
if (file1.getKeywordListNames().isEmpty()) {
|
||||||
|
if (file2.getKeywordListNames().isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else if (file2.getKeywordListNames().isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String list1 = String.join(",", file1.getKeywordListNames());
|
||||||
|
String list2 = String.join(",", file2.getKeywordListNames());
|
||||||
|
return compareStrings(list1, list2);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files based on parent path. Order alphabetically.
|
||||||
|
*
|
||||||
|
* @return -1 if file1's path comes first alphabetically, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getParentPathComparator() {
|
private static Comparator<ResultFile> getParentPathComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getAbstractFile().getParentPath(), file2.getAbstractFile().getParentPath());
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
return compareStrings(file1.getAbstractFile().getParentPath(), file2.getAbstractFile().getParentPath());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files based on number of occurrences in the central repository.
|
||||||
|
* Order from most rare to least rare Frequency enum.
|
||||||
|
*
|
||||||
|
* @return -1 if file1's rarity is lower than file2, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getFrequencyComparator() {
|
private static Comparator<ResultFile> getFrequencyComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> Integer.compare(file1.getFrequency().getRanking(), file2.getFrequency().getRanking());
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
return Integer.compare(file1.getFrequency().getRanking(), file2.getFrequency().getRanking());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files based on MIME type. Order is alphabetical.
|
||||||
|
*
|
||||||
|
* @return -1 if file1's MIME type comes before file2's, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getMIMETypeComparator() {
|
private static Comparator<ResultFile> getMIMETypeComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getAbstractFile().getMIMEType(), file2.getAbstractFile().getMIMEType());
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
// Secondary sort on the MIME type
|
|
||||||
return compareStrings(file1.getAbstractFile().getMIMEType(), file2.getAbstractFile().getMIMEType());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files based on size. Order large to small.
|
||||||
|
*
|
||||||
|
* @return -1 if file1 is larger than file2, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getFileSizeComparator() {
|
private static Comparator<ResultFile> getFileSizeComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> -1 * Long.compare(file1.getAbstractFile().getSize(), file2.getAbstractFile().getSize()) // Sort large to small
|
||||||
@Override
|
;
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
// Sort large to small
|
|
||||||
return -1 * Long.compare(file1.getAbstractFile().getSize(), file2.getAbstractFile().getSize());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare files based on file name. Order alphabetically.
|
||||||
|
*
|
||||||
|
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
|
||||||
|
*/
|
||||||
private static Comparator<ResultFile> getFileNameComparator() {
|
private static Comparator<ResultFile> getFileNameComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> compareStrings(file1.getAbstractFile().getName(), file2.getAbstractFile().getName());
|
||||||
@Override
|
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
|
||||||
return compareStrings(file1.getAbstractFile().getName(), file2.getAbstractFile().getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,19 +183,16 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
* should always include something like the object ID to ensure a
|
* should always include something like the object ID to ensure a
|
||||||
* consistent sorting when the rest of the compared fields are the same.
|
* consistent sorting when the rest of the compared fields are the same.
|
||||||
*
|
*
|
||||||
* @return
|
* @return -1 if file1 comes before file2, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static Comparator<ResultFile> getDefaultComparator() {
|
private static Comparator<ResultFile> getDefaultComparator() {
|
||||||
return new Comparator<ResultFile>() {
|
return (ResultFile file1, ResultFile file2) -> {
|
||||||
@Override
|
// Compare file names and then object ID (to ensure a consistent sort)
|
||||||
public int compare(ResultFile file1, ResultFile file2) {
|
int result = getFileNameComparator().compare(file1, file2);
|
||||||
// For now, compare file names and then object ID (to ensure a consistent sort)
|
if (result == 0) {
|
||||||
int result = getFileNameComparator().compare(file1, file2);
|
return Long.compare(file1.getAbstractFile().getId(), file2.getAbstractFile().getId());
|
||||||
if (result == 0) {
|
|
||||||
return Long.compare(file1.getAbstractFile().getId(), file2.getAbstractFile().getId());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +202,7 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
* @param s1
|
* @param s1
|
||||||
* @param s2
|
* @param s2
|
||||||
*
|
*
|
||||||
* @return
|
* @return -1 if s1 comes before s2, 0 if equal, 1 otherwise
|
||||||
*/
|
*/
|
||||||
private static int compareStrings(String s1, String s2) {
|
private static int compareStrings(String s1, String s2) {
|
||||||
if (s1 == null) {
|
if (s1 == null) {
|
||||||
@ -160,13 +214,16 @@ class FileSorter implements Comparator<ResultFile> {
|
|||||||
return s1.compareTo(s2);
|
return s1.compareTo(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for selecting the primary method for sorting result files.
|
||||||
|
*/
|
||||||
enum SortingMethod {
|
enum SortingMethod {
|
||||||
BY_DATA_SOURCE,
|
BY_DATA_SOURCE, // Sort in increasing order of data source ID
|
||||||
BY_FILE_NAME,
|
BY_FILE_NAME, // Sort alphabetically by file name
|
||||||
BY_FILE_SIZE,
|
BY_FILE_SIZE, // Sort in decreasing order of size
|
||||||
BY_FILE_TYPE,
|
BY_FILE_TYPE, // Sort in order of file type (defined in FileType enum), with secondary sort on MIME type
|
||||||
BY_FREQUENCY,
|
BY_FREQUENCY, // Sort by decreasing rarity in the central repository
|
||||||
BY_KEYWORD_LIST_NAMES,
|
BY_KEYWORD_LIST_NAMES, // Sort alphabetically by list of keyword list names found
|
||||||
BY_PARENT_PATH;
|
BY_PARENT_PATH; // Sort alphabetically by path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ class ResultFile {
|
|||||||
keywordListNames.add(keywordListName);
|
keywordListNames.add(keywordListName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the list so the getKeywordListNames () will be consistent regardless of the order added
|
// Sort the list so the getKeywordListNames() will be consistent regardless of the order added
|
||||||
Collections.sort(keywordListNames);
|
Collections.sort(keywordListNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,15 +101,6 @@ class ResultFile {
|
|||||||
return keywordListNames;
|
return keywordListNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether this file has any keyword list matches
|
|
||||||
*
|
|
||||||
* @return true if it has a keyword list match, false otherwise
|
|
||||||
*/
|
|
||||||
boolean hasKeywords() {
|
|
||||||
return ! keywordListNames.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the AbstractFile
|
* Get the AbstractFile
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.newpackage;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,9 +33,9 @@ class SearchResults {
|
|||||||
|
|
||||||
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
||||||
private final FileSearch.AttributeType attrType;
|
private final FileSearch.AttributeType attrType;
|
||||||
private final Comparator<ResultFile> fileSortingMethod;
|
private final FileSorter fileSorter;
|
||||||
|
|
||||||
private final Map<Object, FileGroup> groupMap = new HashMap<>();
|
private final Map<FileSearch.GroupKey, FileGroup> groupMap = new HashMap<>();
|
||||||
private List<FileGroup> groupList = null;
|
private List<FileGroup> groupList = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,24 +46,27 @@ class SearchResults {
|
|||||||
* @param fileSortingMethod The method that should be used to sortGroupsAndFiles the files in each group
|
* @param fileSortingMethod The method that should be used to sortGroupsAndFiles the files in each group
|
||||||
*/
|
*/
|
||||||
SearchResults(FileGroup.GroupSortingAlgorithm groupSortingType, FileSearch.AttributeType attrType,
|
SearchResults(FileGroup.GroupSortingAlgorithm groupSortingType, FileSearch.AttributeType attrType,
|
||||||
Comparator<ResultFile> fileSortingMethod) {
|
FileSorter.SortingMethod fileSortingMethod) {
|
||||||
this.groupSortingType = groupSortingType;
|
this.groupSortingType = groupSortingType;
|
||||||
this.attrType = attrType;
|
this.attrType = attrType;
|
||||||
this.fileSortingMethod = fileSortingMethod;
|
this.fileSorter = new FileSorter(fileSortingMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a ResultFile to the results
|
* Add a list of ResultFile to the results
|
||||||
*
|
*
|
||||||
* @param file the ResultFile
|
* @param files the ResultFiles
|
||||||
*/
|
*/
|
||||||
void add(ResultFile file) {
|
void add(List<ResultFile> files) {
|
||||||
FileSearch.GroupKey groupKey = attrType.getGroupKey(file);
|
for (ResultFile file : files) {
|
||||||
|
// Add the file to the appropriate group, creating it if necessary
|
||||||
if ( ! groupMap.containsKey(groupKey)) {
|
FileSearch.GroupKey groupKey = attrType.getGroupKey(file);
|
||||||
groupMap.put(groupKey, new FileGroup(groupSortingType, fileSortingMethod, groupKey));
|
|
||||||
|
if ( ! groupMap.containsKey(groupKey)) {
|
||||||
|
groupMap.put(groupKey, new FileGroup(groupSortingType, groupKey));
|
||||||
|
}
|
||||||
|
groupMap.get(groupKey).addFile(file);
|
||||||
}
|
}
|
||||||
groupMap.get(groupKey).addFile(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +76,7 @@ class SearchResults {
|
|||||||
|
|
||||||
// First sortGroupsAndFiles the files
|
// First sortGroupsAndFiles the files
|
||||||
for (FileGroup group : groupMap.values()) {
|
for (FileGroup group : groupMap.values()) {
|
||||||
group.sortFiles();
|
group.sortFiles(fileSorter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now put the groups in a list and sortGroupsAndFiles them
|
// Now put the groups in a list and sortGroupsAndFiles them
|
||||||
@ -82,6 +84,7 @@ class SearchResults {
|
|||||||
Collections.sort(groupList);
|
Collections.sort(groupList);
|
||||||
|
|
||||||
// Debugging - print the results here
|
// Debugging - print the results here
|
||||||
|
// This code should remain until we have a working UI.
|
||||||
System.out.println("\nSearchResults");
|
System.out.println("\nSearchResults");
|
||||||
for (FileGroup group : groupList) {
|
for (FileGroup group : groupList) {
|
||||||
System.out.println(" " + group.getDisplayName());
|
System.out.println(" " + group.getDisplayName());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user