5368 change group list to use group keys instead of strings

This commit is contained in:
William Schaefer
2019-10-17 17:44:08 -04:00
parent c79e76a576
commit 84e947bcf2
11 changed files with 140 additions and 256 deletions
@@ -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&lt;GroupKey&gt;()" 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="&lt;String&gt;"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;GroupKey&gt;"/>
</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,