mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-04 00:09:53 +00:00
5368 change group list to use group keys instead of strings
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
CTL_FileDiscoveryTestAction=Test file discovery
|
||||
CTL_FileSearchTestAction=Test file search
|
||||
# {0} - Data source name
|
||||
# {1} - Data source ID
|
||||
FileSearch.DataSourceGroupKey.datasourceAndID={0}(ID: {1})
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.google.common.eventbus.EventBus;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
|
||||
/**
|
||||
@@ -74,7 +75,7 @@ final class DiscoveryEvents {
|
||||
*/
|
||||
static final class SearchCompleteEvent {
|
||||
|
||||
private final Map<String, Integer> groupMap;
|
||||
private final Map<GroupKey, Integer> groupMap;
|
||||
private final List<FileSearchFiltering.FileFilter> searchFilters;
|
||||
private final FileSearch.AttributeType groupingAttribute;
|
||||
private final FileGroup.GroupSortingAlgorithm groupSort;
|
||||
@@ -91,7 +92,7 @@ final class DiscoveryEvents {
|
||||
* @param groupSort The sorting algorithm used for groups.
|
||||
* @param fileSortMethod The sorting method used for files.
|
||||
*/
|
||||
SearchCompleteEvent(Map<String, Integer> groupMap, List<FileSearchFiltering.FileFilter> searchfilters,
|
||||
SearchCompleteEvent(Map<GroupKey, Integer> groupMap, List<FileSearchFiltering.FileFilter> searchfilters,
|
||||
FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort,
|
||||
FileSorter.SortingMethod fileSortMethod) {
|
||||
this.groupMap = groupMap;
|
||||
@@ -106,7 +107,7 @@ final class DiscoveryEvents {
|
||||
*
|
||||
* @return The map of groups which were found by the search.
|
||||
*/
|
||||
Map<String, Integer> getGroupMap() {
|
||||
Map<GroupKey, Integer> getGroupMap() {
|
||||
return Collections.unmodifiableMap(groupMap);
|
||||
}
|
||||
|
||||
@@ -218,7 +219,7 @@ final class DiscoveryEvents {
|
||||
static final class GroupSelectedEvent {
|
||||
|
||||
private final FileType resultType;
|
||||
private final String groupName;
|
||||
private final GroupKey groupKey;
|
||||
private final int groupSize;
|
||||
private final List<FileSearchFiltering.FileFilter> searchfilters;
|
||||
private final FileSearch.AttributeType groupingAttribute;
|
||||
@@ -233,19 +234,20 @@ final class DiscoveryEvents {
|
||||
* @param groupingAttribute The grouping attribute used by the search.
|
||||
* @param groupSort The sorting algorithm used for groups.
|
||||
* @param fileSortMethod The sorting method used for files.
|
||||
* @param groupName The name of the group which was selected.
|
||||
* @param groupKey The key associated with the group which was
|
||||
* selected.
|
||||
* @param groupSize The number of files in the group which was
|
||||
* selected.
|
||||
* @param resultType The type of files which exist in the group.
|
||||
*/
|
||||
GroupSelectedEvent(List<FileSearchFiltering.FileFilter> searchfilters,
|
||||
FileSearch.AttributeType groupingAttribute, FileGroup.GroupSortingAlgorithm groupSort,
|
||||
FileSorter.SortingMethod fileSortMethod, String groupName, int groupSize, FileType resultType) {
|
||||
FileSorter.SortingMethod fileSortMethod, GroupKey groupKey, int groupSize, FileType resultType) {
|
||||
this.searchfilters = searchfilters;
|
||||
this.groupingAttribute = groupingAttribute;
|
||||
this.groupSort = groupSort;
|
||||
this.fileSortMethod = fileSortMethod;
|
||||
this.groupName = groupName;
|
||||
this.groupKey = groupKey;
|
||||
this.groupSize = groupSize;
|
||||
this.resultType = resultType;
|
||||
}
|
||||
@@ -260,12 +262,14 @@ final class DiscoveryEvents {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the group which was selected.
|
||||
* Get the group key which is used to uniquely identify the group
|
||||
* selected.
|
||||
*
|
||||
* @return The name of the group which was selected.
|
||||
* @return The group key which is used to uniquely identify the group
|
||||
* selected.
|
||||
*/
|
||||
String getGroupName() {
|
||||
return groupName;
|
||||
GroupKey getGroupKey() {
|
||||
return groupKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.filequery;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
|
||||
/**
|
||||
* Class for storing files that belong to a particular group.
|
||||
@@ -28,7 +29,7 @@ import java.util.List;
|
||||
class FileGroup implements Comparable<FileGroup> {
|
||||
|
||||
private final FileGroup.GroupSortingAlgorithm groupSortingType;
|
||||
private final FileSearch.GroupKey groupKey;
|
||||
private final GroupKey groupKey;
|
||||
private final List<ResultFile> files;
|
||||
private final String displayName;
|
||||
|
||||
@@ -38,7 +39,7 @@ class FileGroup implements Comparable<FileGroup> {
|
||||
* @param groupSortingType The method for sorting the group
|
||||
* @param groupKey The GroupKey for this group
|
||||
*/
|
||||
FileGroup(FileGroup.GroupSortingAlgorithm groupSortingType, FileSearch.GroupKey groupKey) {
|
||||
FileGroup(FileGroup.GroupSortingAlgorithm groupSortingType, GroupKey groupKey) {
|
||||
this.groupSortingType = groupSortingType;
|
||||
this.groupKey = groupKey;
|
||||
files = new ArrayList<>();
|
||||
@@ -54,21 +55,29 @@ class FileGroup implements Comparable<FileGroup> {
|
||||
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());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name for this group. This must be unique for each group.
|
||||
* Get the display name for this group.
|
||||
*
|
||||
* @return the display name
|
||||
* @return The display name of the group.
|
||||
*/
|
||||
String getDisplayName() {
|
||||
return displayName; // NON-NLS
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key which uniquely identifies each group.
|
||||
*
|
||||
* @return The unique key for the group.
|
||||
*/
|
||||
GroupKey getGroupKey() {
|
||||
return groupKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the AbstractFile objects out of the ResultFile objects.
|
||||
*
|
||||
|
||||
@@ -69,7 +69,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
class FileSearch {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
|
||||
private static final Cache<String, List<ResultFile>> groupCache = CacheBuilder.newBuilder().build();
|
||||
private static final Cache<GroupKey, List<ResultFile>> groupCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
/**
|
||||
* Run the file search and returns the SearchResults object for debugging.
|
||||
@@ -116,15 +116,15 @@ class FileSearch {
|
||||
|
||||
// Sort and group the results
|
||||
searchResults.sortGroupsAndFiles();
|
||||
Map<String, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
for (String groupName : resultHashMap.keySet()) {
|
||||
groupCache.put(groupName, resultHashMap.get(groupName));
|
||||
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
for (GroupKey groupKey : resultHashMap.keySet()) {
|
||||
groupCache.put(groupKey, resultHashMap.get(groupKey));
|
||||
}
|
||||
return searchResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the file search to get the group names and sizes. Clears cache of
|
||||
* Run the file search to get the group keys and sizes. Clears cache of
|
||||
* search results, caching new results for access at later time.
|
||||
*
|
||||
* @param filters The filters to apply
|
||||
@@ -140,17 +140,17 @@ class FileSearch {
|
||||
*
|
||||
* @throws FileSearchException
|
||||
*/
|
||||
static LinkedHashMap<String, Integer> getGroupSizes(
|
||||
static LinkedHashMap<GroupKey, Integer> getGroupSizes(
|
||||
List<FileSearchFiltering.FileFilter> filters,
|
||||
AttributeType groupAttributeType,
|
||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||
FileSorter.SortingMethod fileSortingMethod,
|
||||
SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||
Map<String, List<ResultFile>> searchResults = runFileSearch(filters,
|
||||
Map<GroupKey, List<ResultFile>> searchResults = runFileSearch(filters,
|
||||
groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||
LinkedHashMap<String, Integer> groupSizes = new LinkedHashMap<>();
|
||||
for (String groupName : searchResults.keySet()) {
|
||||
groupSizes.put(groupName, searchResults.get(groupName).size());
|
||||
LinkedHashMap<GroupKey, Integer> groupSizes = new LinkedHashMap<>();
|
||||
for (GroupKey groupKey : searchResults.keySet()) {
|
||||
groupSizes.put(groupKey, searchResults.get(groupKey).size());
|
||||
}
|
||||
return groupSizes;
|
||||
}
|
||||
@@ -164,7 +164,8 @@ class FileSearch {
|
||||
* @param groupSortingType The method to use to sort the groups
|
||||
* @param fileSortingMethod The method to use to sort the files within the
|
||||
* groups
|
||||
* @param groupName Name of the group to get entries from
|
||||
* @param groupKey The key which uniquely identifies the group to
|
||||
* get entries from
|
||||
* @param startingEntry The first entry to return
|
||||
* @param numberOfEntries The number of entries to return
|
||||
* @param caseDb The case database
|
||||
@@ -180,19 +181,19 @@ class FileSearch {
|
||||
AttributeType groupAttributeType,
|
||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||
FileSorter.SortingMethod fileSortingMethod,
|
||||
String groupName,
|
||||
GroupKey groupKey,
|
||||
int startingEntry,
|
||||
int numberOfEntries,
|
||||
SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||
//the group should be in the cache at this point
|
||||
List<ResultFile> filesInGroup = groupCache.getIfPresent(groupName);
|
||||
List<ResultFile> filesInGroup = groupCache.getIfPresent(groupKey);
|
||||
List<ResultFile> page = new ArrayList<>();
|
||||
if (filesInGroup == null) {
|
||||
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupName);
|
||||
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupKey);
|
||||
runFileSearch(filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||
filesInGroup = groupCache.getIfPresent(groupName);
|
||||
filesInGroup = groupCache.getIfPresent(groupKey);
|
||||
if (filesInGroup == null) {
|
||||
logger.log(Level.WARNING, "Group {0} did not exist in cache or new search results", groupName);
|
||||
logger.log(Level.WARNING, "Group {0} did not exist in cache or new search results", groupKey);
|
||||
return page; //group does not exist
|
||||
}
|
||||
}
|
||||
@@ -226,7 +227,7 @@ class FileSearch {
|
||||
*
|
||||
* @throws FileSearchException
|
||||
*/
|
||||
private synchronized static Map<String, List<ResultFile>> runFileSearch(
|
||||
private synchronized static Map<GroupKey, List<ResultFile>> runFileSearch(
|
||||
List<FileSearchFiltering.FileFilter> filters,
|
||||
AttributeType groupAttributeType,
|
||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||
@@ -251,9 +252,9 @@ class FileSearch {
|
||||
// Collect everything in the search results
|
||||
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||
searchResults.add(resultFiles);
|
||||
Map<String, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
for (String groupName : resultHashMap.keySet()) {
|
||||
groupCache.put(groupName, resultHashMap.get(groupName));
|
||||
Map<GroupKey, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
for (GroupKey groupKey : resultHashMap.keySet()) {
|
||||
groupCache.put(groupKey, resultHashMap.get(groupKey));
|
||||
}
|
||||
// Return a version of the results in general Java objects
|
||||
return resultHashMap;
|
||||
@@ -581,6 +582,11 @@ class FileSearch {
|
||||
int compareClassNames(GroupKey otherGroupKey) {
|
||||
return this.getClass().getName().compareTo(otherGroupKey.getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -657,12 +663,14 @@ class FileSearch {
|
||||
private static class ParentPathGroupKey extends GroupKey {
|
||||
|
||||
private String parentPath;
|
||||
private Long parentID = -1L;
|
||||
|
||||
ParentPathGroupKey(ResultFile file) {
|
||||
if (file.getFirstInstance().getParentPath() != null) {
|
||||
|
||||
try {
|
||||
parentPath = file.getFirstInstance().getParent().getUniquePath();
|
||||
parentID = file.getFirstInstance().getParent().getId();
|
||||
} catch (TskCoreException ingored) {
|
||||
parentPath = file.getFirstInstance().getParentPath();
|
||||
}
|
||||
@@ -680,7 +688,11 @@ class FileSearch {
|
||||
public int compareTo(GroupKey otherGroupKey) {
|
||||
if (otherGroupKey instanceof ParentPathGroupKey) {
|
||||
ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherGroupKey;
|
||||
return parentPath.compareTo(otherParentPathGroupKey.parentPath);
|
||||
int comparisonResult = parentPath.compareTo(otherParentPathGroupKey.parentPath);
|
||||
if (comparisonResult == 0) {
|
||||
comparisonResult = parentID.compareTo(otherParentPathGroupKey.parentID);
|
||||
}
|
||||
return comparisonResult;
|
||||
} else {
|
||||
return compareClassNames(otherGroupKey);
|
||||
}
|
||||
@@ -697,12 +709,15 @@ class FileSearch {
|
||||
}
|
||||
|
||||
ParentPathGroupKey otherParentPathGroupKey = (ParentPathGroupKey) otherKey;
|
||||
return parentPath.equals(otherParentPathGroupKey.parentPath);
|
||||
return parentPath.equals(otherParentPathGroupKey.parentPath) && parentID.equals(otherParentPathGroupKey.parentID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(parentPath);
|
||||
int hashCode = 11;
|
||||
hashCode = 61 * hashCode + Objects.hash(parentPath);
|
||||
hashCode = 61 * hashCode + Objects.hash(parentID);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 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.filequery;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Class to test the file search API. Allows the user to run searches and see results.
|
||||
*/
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.newpackage.FileSearchTestAction")
|
||||
@ActionReference(path = "Menu/Tools", position = 1852, separatorBefore = 1851)
|
||||
@ActionRegistration(displayName = "#CTL_FileSearchTestAction", lazy = false)
|
||||
@NbBundle.Messages({"CTL_FileSearchTestAction=Test file search"})
|
||||
public final class FileSearchTestAction extends CallableSystemAction {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(FileSearchTestAction.class.getName());
|
||||
private static final String DISPLAY_NAME = "Test file search";
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return Case.isCaseOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("fallthrough")
|
||||
public void performAction() {
|
||||
|
||||
// Load the central repository database.
|
||||
EamDb crDb = null;
|
||||
if (EamDb.isEnabled()) {
|
||||
try {
|
||||
crDb = EamDb.getInstance();
|
||||
} catch (EamDbException ex) {
|
||||
logger.log(Level.SEVERE, "Error loading central repository database", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FileSearchDialog dialog = new FileSearchDialog(null, true, Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
|
||||
// For testing, allow the user to run different searches in loop
|
||||
while (true) {
|
||||
|
||||
// Display the dialog
|
||||
dialog.display();
|
||||
|
||||
if (dialog.searchCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the selected filters
|
||||
List<FileSearchFiltering.FileFilter> filters = dialog.getFilters();
|
||||
|
||||
// Get the grouping attribute and group sorting method
|
||||
FileSearch.AttributeType groupingAttr = dialog.getGroupingAttribute();
|
||||
FileGroup.GroupSortingAlgorithm groupSortAlgorithm = dialog.getGroupSortingMethod();
|
||||
|
||||
// Get the file sorting method
|
||||
FileSorter.SortingMethod fileSort = dialog.getFileSortingMethod();
|
||||
|
||||
try {
|
||||
|
||||
// Test getting the groups
|
||||
LinkedHashMap<String, Integer> groups = FileSearch.getGroupSizes(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
|
||||
System.out.println("Groups: ");
|
||||
for (String name : groups.keySet()) {
|
||||
System.out.println(" " + name + " : " + groups.get(name));
|
||||
}
|
||||
|
||||
if (! groups.isEmpty()) {
|
||||
String firstGroupName = groups.keySet().iterator().next();
|
||||
|
||||
List<ResultFile> entries0to5 = FileSearch.getFilesInGroup(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
firstGroupName,
|
||||
0,
|
||||
5,
|
||||
Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
System.out.println("First five " + firstGroupName + " : ");
|
||||
for (ResultFile f : entries0to5) {
|
||||
System.out.println(" " + f.getFirstInstance().getName());
|
||||
}
|
||||
|
||||
List<ResultFile> entries6to106 = FileSearch.getFilesInGroup(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
firstGroupName,
|
||||
5,
|
||||
100,
|
||||
Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
System.out.println(firstGroupName + " 6 to 106: ");
|
||||
for (ResultFile f : entries6to106) {
|
||||
System.out.println(" " + f.getFirstInstance().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Run the search
|
||||
SearchResults results = FileSearch.runFileSearchDebug(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
|
||||
// Display the results
|
||||
ResultsDialog resultsDialog = new ResultsDialog(null, true, results.toString());
|
||||
resultsDialog.display();
|
||||
|
||||
if ( ! resultsDialog.shouldRunAnotherSearch()) {
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (FileSearchException ex) {
|
||||
logger.log(Level.SEVERE, "Error running file search test", ex);
|
||||
|
||||
// Display the exception in the UI for easier debugging
|
||||
String message = ex.toString() + "\n" + ExceptionUtils.getStackTrace(ex);
|
||||
ResultsDialog resultsDialog = new ResultsDialog(null, true, message);
|
||||
resultsDialog.display();
|
||||
if (! resultsDialog.runAnotherSearch) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return DISPLAY_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asynchronous() {
|
||||
return false; // run on edt
|
||||
}
|
||||
}
|
||||
@@ -39,18 +39,21 @@
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JList" name="groupDisplayNameList">
|
||||
<Component class="javax.swing.JList" name="groupKeyList">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
|
||||
<StringArray count="0"/>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultListModel<GroupKey>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="selectionMode" type="int" value="0"/>
|
||||
<Property name="cellRenderer" type="javax.swing.ListCellRenderer" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new GroupListRenderer()" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="groupSelected"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<GroupKey>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
|
||||
@@ -21,7 +21,10 @@ package org.sleuthkit.autopsy.filequery;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
|
||||
/**
|
||||
@@ -31,12 +34,12 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private FileType resultType = null;
|
||||
private Map<String, Integer> groupMap = null;
|
||||
private Map<GroupKey, Integer> groupMap = null;
|
||||
private List<FileSearchFiltering.FileFilter> searchfilters;
|
||||
private FileSearch.AttributeType groupingAttribute;
|
||||
private FileGroup.GroupSortingAlgorithm groupSort;
|
||||
private FileSorter.SortingMethod fileSortMethod;
|
||||
private String selectedGroupName;
|
||||
private GroupKey selectedGroupKey;
|
||||
|
||||
/**
|
||||
* Creates new form GroupListPanel
|
||||
@@ -53,7 +56,7 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
@Subscribe
|
||||
void handleSearchStartedEvent(DiscoveryEvents.SearchStartedEvent searchStartedEvent) {
|
||||
resultType = searchStartedEvent.getType();
|
||||
groupDisplayNameList.setListData(new String[0]);
|
||||
groupKeyList.setListData(new GroupKey[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,10 +72,9 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
groupingAttribute = searchCompleteEvent.getGroupingAttr();
|
||||
groupSort = searchCompleteEvent.getGroupSort();
|
||||
fileSortMethod = searchCompleteEvent.getFileSort();
|
||||
List<String> groupNames = groupMap.entrySet().stream().map(e -> e.getKey() + " (" + e.getValue() + ")").collect(Collectors.toList());
|
||||
groupDisplayNameList.setListData(groupNames.toArray(new String[groupNames.size()]));
|
||||
if (groupDisplayNameList.getModel().getSize() > 0) {
|
||||
groupDisplayNameList.setSelectedIndex(0);
|
||||
groupKeyList.setListData(groupMap.keySet().toArray(new GroupKey[groupMap.keySet().size()]));
|
||||
if (groupKeyList.getModel().getSize() > 0) {
|
||||
groupKeyList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,15 +88,17 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
private void initComponents() {
|
||||
|
||||
groupListScrollPane = new javax.swing.JScrollPane();
|
||||
groupDisplayNameList = new javax.swing.JList<>();
|
||||
groupKeyList = new javax.swing.JList<>();
|
||||
|
||||
groupDisplayNameList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
groupDisplayNameList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
|
||||
groupKeyList.setModel(new DefaultListModel<GroupKey>());
|
||||
groupKeyList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
|
||||
groupKeyList.setCellRenderer(new GroupListRenderer());
|
||||
groupKeyList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
|
||||
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
|
||||
groupSelected(evt);
|
||||
}
|
||||
});
|
||||
groupListScrollPane.setViewportView(groupDisplayNameList);
|
||||
groupListScrollPane.setViewportView(groupKeyList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@@ -119,13 +123,13 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
private void groupSelected(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_groupSelected
|
||||
if (!evt.getValueIsAdjusting()) {
|
||||
if (groupDisplayNameList.getSelectedValue() != null) {
|
||||
String selectedGroup = groupDisplayNameList.getSelectedValue().replaceAll(" \\([0-9]+\\)$", "");
|
||||
for (String groupName : groupMap.keySet()) {
|
||||
if (selectedGroup.equalsIgnoreCase(groupName)) {
|
||||
selectedGroupName = groupName;
|
||||
if (groupKeyList.getSelectedValue() != null) {
|
||||
GroupKey selectedGroup = groupKeyList.getSelectedValue();
|
||||
for (GroupKey groupKey : groupMap.keySet()) {
|
||||
if (selectedGroup.equals(groupKey)) {
|
||||
selectedGroupKey = groupKey;
|
||||
DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.GroupSelectedEvent(
|
||||
searchfilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupName, groupMap.get(selectedGroupName), resultType));
|
||||
searchfilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupKey, groupMap.get(selectedGroupKey), resultType));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -136,7 +140,32 @@ class GroupListPanel extends javax.swing.JPanel {
|
||||
}//GEN-LAST:event_groupSelected
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JList<String> groupDisplayNameList;
|
||||
private javax.swing.JList<GroupKey> groupKeyList;
|
||||
private javax.swing.JScrollPane groupListScrollPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* GroupListCellRenderer displays GroupKeys as their String value followed
|
||||
* by the number of items in the group.
|
||||
*/
|
||||
private class GroupListRenderer extends DefaultListCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public java.awt.Component getListCellRendererComponent(
|
||||
JList<?> list,
|
||||
Object value,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
Object newValue = value;
|
||||
if (newValue instanceof GroupKey) {
|
||||
newValue = newValue.toString() + " (" + groupMap.get(newValue) + ")";
|
||||
}
|
||||
super.getListCellRendererComponent(list, newValue, index, isSelected, cellHasFocus);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.swing.SwingWorker;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
|
||||
/**
|
||||
* SwingWorker to retrieve the contents of a page.
|
||||
@@ -35,7 +36,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
|
||||
private final FileSearch.AttributeType groupingAttribute;
|
||||
private final FileGroup.GroupSortingAlgorithm groupSort;
|
||||
private final FileSorter.SortingMethod fileSortMethod;
|
||||
private final String groupName;
|
||||
private final GroupKey groupKey;
|
||||
private final int startingEntry;
|
||||
private final int pageSize;
|
||||
private final FileSearchData.FileType resultType;
|
||||
@@ -49,7 +50,8 @@ final class PageWorker extends SwingWorker<Void, Void> {
|
||||
* @param groupingAttribute The grouping attribute used by the search.
|
||||
* @param groupSort The sorting algorithm used for groups.
|
||||
* @param fileSortMethod The sorting method used for files.
|
||||
* @param groupName The name of the group which was selected.
|
||||
* @param groupKey The key which uniquely identifies the group
|
||||
* which was selected.
|
||||
* @param startingEntry The first entry in the group to include in this
|
||||
* page.
|
||||
* @param pageSize The number of files to include in this page.
|
||||
@@ -57,13 +59,13 @@ final class PageWorker extends SwingWorker<Void, Void> {
|
||||
* @param centralRepo The central repository to be used.
|
||||
*/
|
||||
PageWorker(List<FileSearchFiltering.FileFilter> searchfilters, FileSearch.AttributeType groupingAttribute,
|
||||
FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod, String groupName,
|
||||
FileGroup.GroupSortingAlgorithm groupSort, FileSorter.SortingMethod fileSortMethod, GroupKey groupKey,
|
||||
int startingEntry, int pageSize, FileSearchData.FileType resultType, EamDb centralRepo) {
|
||||
this.searchfilters = searchfilters;
|
||||
this.groupingAttribute = groupingAttribute;
|
||||
this.groupSort = groupSort;
|
||||
this.fileSortMethod = fileSortMethod;
|
||||
this.groupName = groupName;
|
||||
this.groupKey = groupKey;
|
||||
this.startingEntry = startingEntry;
|
||||
this.pageSize = pageSize;
|
||||
this.resultType = resultType;
|
||||
@@ -78,7 +80,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
|
||||
List<ResultFile> results = FileSearch.getFilesInGroup(searchfilters,
|
||||
groupingAttribute,
|
||||
groupSort,
|
||||
fileSortMethod, groupName, startingEntry, pageSize,
|
||||
fileSortMethod, groupKey, startingEntry, pageSize,
|
||||
Case.getCurrentCase().getSleuthkitCase(), centralRepo);
|
||||
int currentPage = startingEntry / pageSize; //integer division should round down to get page number correctly
|
||||
DiscoveryEvents.getDiscoveryEventBus().post(new DiscoveryEvents.PageRetrievedEvent(resultType, currentPage, results));
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
@@ -57,7 +58,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
private FileSearch.AttributeType groupingAttribute;
|
||||
private FileGroup.GroupSortingAlgorithm groupSort;
|
||||
private FileSorter.SortingMethod fileSortMethod;
|
||||
private String selectedGroupName;
|
||||
private GroupKey selectedGroupKey;
|
||||
private int currentPage = 0;
|
||||
private int previousPageSize = 10;
|
||||
private FileSearchData.FileType resultType;
|
||||
@@ -241,7 +242,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
groupingAttribute = groupSelectedEvent.getGroupingAttr();
|
||||
groupSort = groupSelectedEvent.getGroupSort();
|
||||
fileSortMethod = groupSelectedEvent.getFileSort();
|
||||
selectedGroupName = groupSelectedEvent.getGroupName();
|
||||
selectedGroupKey = groupSelectedEvent.getGroupKey();
|
||||
resultType = groupSelectedEvent.getResultType();
|
||||
groupSize = groupSelectedEvent.getGroupSize();
|
||||
setPage(0);
|
||||
@@ -274,7 +275,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
if (pageWorker != null && !pageWorker.isDone()) {
|
||||
pageWorker.cancel(true);
|
||||
}
|
||||
pageWorker = new PageWorker(searchFilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupName, startingEntry, pageSize, resultType, centralRepo);
|
||||
pageWorker = new PageWorker(searchFilters, groupingAttribute, groupSort, fileSortMethod, selectedGroupKey, startingEntry, pageSize, resultType, centralRepo);
|
||||
pageWorker.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
|
||||
/**
|
||||
* Class to hold the results of the filtering/grouping/sorting operations
|
||||
@@ -150,15 +151,15 @@ class SearchResults {
|
||||
*
|
||||
* @return the grouped and sorted results
|
||||
*/
|
||||
Map<String, List<ResultFile>> toLinkedHashMap() throws FileSearchException {
|
||||
Map<String, List<ResultFile>> map = new LinkedHashMap<>();
|
||||
Map<GroupKey, List<ResultFile>> toLinkedHashMap() throws FileSearchException {
|
||||
Map<GroupKey, List<ResultFile>> map = new LinkedHashMap<>();
|
||||
|
||||
// Sort the groups and files
|
||||
sortGroupsAndFiles();
|
||||
|
||||
// groupList is sorted and a LinkedHashMap will preserve that order.
|
||||
for (FileGroup group : groupList) {
|
||||
map.put(group.getDisplayName(), group.getAbstractFiles());
|
||||
map.put(group.getGroupKey(), group.getAbstractFiles());
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearch.GroupKey;
|
||||
|
||||
/**
|
||||
* SwingWorker to perform search on a background thread
|
||||
@@ -65,7 +66,7 @@ final class SearchWorker extends SwingWorker<Void, Void> {
|
||||
|
||||
try {
|
||||
// Run the search
|
||||
LinkedHashMap<String, Integer> results = FileSearch.getGroupSizes(filters,
|
||||
LinkedHashMap<GroupKey, Integer> results = FileSearch.getGroupSizes(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
|
||||
Reference in New Issue
Block a user