1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-04 06:50:00 +00:00

Merge pull request #3381 from wschaeferB/3408-MultiUserCaseExplorer-2.11.0

3408 make search tip more helpful and fix comments
This commit is contained in:
Richard Cordovano
2018-01-22 16:26:49 -05:00
committed by GitHub
5 changed files with 88 additions and 101 deletions

View File

@@ -229,5 +229,5 @@ CueBannerPanel.openCaseButton.text=
CueBannerPanel.openCaseLabel.text=Open Case
MultiUserCasesPanel.bnOpenSingleUserCase.text=Open Single-User Case...
CueBannerPanel.newCaseButton.text=
MultiUserCasesPanel.searchLabel.text=Start typing to search by case name
MultiUserCasesPanel.searchLabel.text=Select any case and start typing to search by case name
MultiUserCasesPanel.cancelButton.text=Cancel

View File

@@ -18,11 +18,9 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
import java.lang.reflect.InvocationTargetException;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.netbeans.swing.etable.ETableColumn;
import org.netbeans.swing.etable.ETableColumnModel;
@@ -33,14 +31,12 @@ import java.awt.EventQueue;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.SwingWorker;
import org.openide.explorer.ExplorerManager;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coordinationservice.CaseNodeData;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.EmptyNode;
@@ -61,7 +57,7 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
private final org.openide.explorer.view.OutlineView outlineView;
private int originalPathColumnIndex = 0;
private static final Logger LOGGER = Logger.getLogger(CaseBrowser.class.getName());
private LoadCaseMapWorker tableWorker;
private LoadCaseListWorker tableWorker;
@Override
public ExplorerManager getExplorerManager() {
@@ -78,7 +74,6 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
outline = outlineView.getOutline();
outlineView.setPropertyColumns(
Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(),
Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath());
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CaseNode_column_name());
customize();
@@ -100,7 +95,7 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
dateColumnIndex = index;
}
}
//Hide path column by default will need to
//Hide path column by default (user can unhide it)
ETableColumn column = (ETableColumn) columnModel.getColumn(originalPathColumnIndex);
((ETableColumnModel) columnModel).setColumnHidden(column, true);
outline.setRootVisible(false);
@@ -124,6 +119,11 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
outline.getSelectionModel().addListSelectionListener(listener);
}
/**
* Get the path to the .aut file for the selected case.
*
* @return the full path to the selected case's .aut file
*/
String getCasePath() {
int[] selectedRows = outline.getSelectedRows();
if (selectedRows.length == 1) {
@@ -157,7 +157,7 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
//set the table to display text informing the user that the list is being retreived and disable case selection
EmptyNode emptyNode = new EmptyNode(Bundle.CaseBrowser_caseListLoading_message());
em.setRootContext(emptyNode);
tableWorker = new LoadCaseMapWorker();
tableWorker = new LoadCaseListWorker();
tableWorker.execute();
}
@@ -189,13 +189,11 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
// End of variables declaration//GEN-END:variables
/**
* Swingworker to fetch the updated map of cases and their status in a
* background thread
* Swingworker to fetch the updated List of cases in a background thread
*/
private class LoadCaseMapWorker extends SwingWorker<Void, Void> {
private class LoadCaseListWorker extends SwingWorker<Void, Void> {
private static final String ALERT_FILE_NAME = "autoingest.alert";
private Map<CaseMetadata, Boolean> cases;
private List<CaseMetadata> cases;
/**
* Gets a list of the cases in the top level case folder
@@ -204,8 +202,8 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
*
* @throws CoordinationServiceException
*/
private Map<CaseMetadata, Boolean> getCases() throws CoordinationService.CoordinationServiceException {
Map<CaseMetadata, Boolean> casesMap = new HashMap<>();
private List<CaseMetadata> getCases() throws CoordinationService.CoordinationServiceException {
List<CaseMetadata> caseList = new ArrayList<>();
List<String> nodeList = CoordinationService.getInstance().getNodeList(CoordinationService.CategoryNode.CASES);
for (String node : nodeList) {
@@ -213,64 +211,27 @@ class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider
File caseFolder = casePath.toFile();
if (caseFolder.exists()) {
/*
* Search for '*.aut' and 'autoingest.alert' files.
* Search for '*.aut' files.
*/
File[] fileArray = caseFolder.listFiles();
if (fileArray == null) {
continue;
}
String autFilePath = null;
boolean alertFileFound = false;
for (File file : fileArray) {
String name = file.getName().toLowerCase();
if (autFilePath == null && name.endsWith(".aut")) {
autFilePath = file.getAbsolutePath();
if (!alertFileFound) {
continue;
try {
caseList.add(new CaseMetadata(Paths.get(file.getAbsolutePath())));
} catch (CaseMetadata.CaseMetadataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
}
}
if (!alertFileFound && name.endsWith(ALERT_FILE_NAME)) {
alertFileFound = true;
}
if (autFilePath != null && alertFileFound) {
break;
}
}
if (autFilePath != null) {
try {
boolean hasAlertStatus = false;
if (alertFileFound) {
/*
* When an alert file exists, ignore the node
* data and use the ALERT status.
*/
hasAlertStatus = true;
} else {
byte[] rawData = CoordinationService.getInstance().getNodeData(CoordinationService.CategoryNode.CASES, node);
if (rawData != null && rawData.length > 0) {
/*
* When node data exists, use the status
* stored in the node data.
*/
CaseNodeData caseNodeData = new CaseNodeData(rawData);
if (caseNodeData.getErrorsOccurred()) {
hasAlertStatus = true;
}
}
}
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(autFilePath));
casesMap.put(caseMetadata, hasAlertStatus);
} catch (CaseMetadata.CaseMetadataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
} catch (InterruptedException | CaseNodeData.InvalidDataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case node data for '%s'.", node), ex);
}
}
}
}
return casesMap;
return caseList;
}
@Override

View File

@@ -27,13 +27,13 @@
<Group type="103" groupAlignment="1" attributes="0">
<Component id="caseExplorerScrollPane" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="searchLabel" min="-2" pref="555" max="-2" attributes="0"/>
<EmptySpace pref="175" max="32767" attributes="0"/>
<Component id="bnOpen" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="searchLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="120" max="32767" attributes="0"/>
<Component id="bnOpenSingleUserCase" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="226" max="-2" attributes="0"/>
<Component id="bnOpen" linkSize="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@@ -52,7 +52,7 @@
<Component id="bnOpenSingleUserCase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="searchLabel" alignment="3" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -64,6 +64,15 @@
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.bnOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenActionPerformed"/>
@@ -74,6 +83,12 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.bnOpenSingleUserCase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[156, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[156, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenSingleUserCaseActionPerformed"/>
@@ -84,6 +99,15 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>

View File

@@ -165,6 +165,9 @@ final class MultiUserCasesPanel extends JPanel{
org.openide.awt.Mnemonics.setLocalizedText(bnOpen, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnOpen.text")); // NOI18N
bnOpen.setEnabled(false);
bnOpen.setMaximumSize(new java.awt.Dimension(80, 23));
bnOpen.setMinimumSize(new java.awt.Dimension(80, 23));
bnOpen.setPreferredSize(new java.awt.Dimension(80, 23));
bnOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnOpenActionPerformed(evt);
@@ -172,6 +175,8 @@ final class MultiUserCasesPanel extends JPanel{
});
org.openide.awt.Mnemonics.setLocalizedText(bnOpenSingleUserCase, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnOpenSingleUserCase.text")); // NOI18N
bnOpenSingleUserCase.setMinimumSize(new java.awt.Dimension(156, 23));
bnOpenSingleUserCase.setPreferredSize(new java.awt.Dimension(156, 23));
bnOpenSingleUserCase.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnOpenSingleUserCaseActionPerformed(evt);
@@ -179,6 +184,9 @@ final class MultiUserCasesPanel extends JPanel{
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.cancelButton.text")); // NOI18N
cancelButton.setMaximumSize(new java.awt.Dimension(80, 23));
cancelButton.setMinimumSize(new java.awt.Dimension(80, 23));
cancelButton.setPreferredSize(new java.awt.Dimension(80, 23));
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
@@ -196,15 +204,18 @@ final class MultiUserCasesPanel extends JPanel{
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(caseExplorerScrollPane)
.addGroup(layout.createSequentialGroup()
.addComponent(searchLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 555, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 175, Short.MAX_VALUE)
.addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(searchLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 120, Short.MAX_VALUE)
.addComponent(bnOpenSingleUserCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(226, 226, 226)
.addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnOpenSingleUserCase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)))
.addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnOpen, cancelButton});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
@@ -212,11 +223,11 @@ final class MultiUserCasesPanel extends JPanel{
.addComponent(caseExplorerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 450, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancelButton)
.addComponent(bnOpen)
.addComponent(bnOpenSingleUserCase)
.addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnOpenSingleUserCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(searchLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents

View File

@@ -25,8 +25,6 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
@@ -49,7 +47,6 @@ final class MultiUserNode extends AbstractNode {
@Messages({"CaseNode.column.name=Name",
"CaseNode.column.createdTime=Created Time",
"CaseNode.column.status=Status",
"CaseNode.column.metadataFilePath=Path"})
private static final Logger LOGGER = Logger.getLogger(MultiUserNode.class.getName());
private static final String LOG_FILE_NAME = "auto_ingest_log.txt";
@@ -57,31 +54,30 @@ final class MultiUserNode extends AbstractNode {
/**
* Provides a root node with children which each represent a case.
*
* @param caseMap the map of cases and a boolean indicating if they have an
* alert
* @param caseList the list of CaseMetadata objects representing the cases
*/
MultiUserNode(Map<CaseMetadata, Boolean> caseMap) {
super(Children.create(new MultiUserNodeChildren(caseMap), true));
MultiUserNode(List<CaseMetadata> caseList) {
super(Children.create(new MultiUserNodeChildren(caseList), true));
}
static class MultiUserNodeChildren extends ChildFactory<Entry<CaseMetadata, Boolean>> {
static class MultiUserNodeChildren extends ChildFactory<CaseMetadata> {
private final Map<CaseMetadata, Boolean> caseMap;
private final List<CaseMetadata> caseList;
MultiUserNodeChildren(Map<CaseMetadata, Boolean> caseMap) {
this.caseMap = caseMap;
MultiUserNodeChildren(List<CaseMetadata> caseList) {
this.caseList = caseList;
}
@Override
protected boolean createKeys(List<Entry<CaseMetadata, Boolean>> list) {
if (caseMap != null && caseMap.size() > 0) {
list.addAll(caseMap.entrySet());
protected boolean createKeys(List<CaseMetadata> list) {
if (caseList != null && caseList.size() > 0) {
list.addAll(caseList);
}
return true;
}
@Override
protected Node createNodeForKey(Entry<CaseMetadata, Boolean> key) {
protected Node createNodeForKey(CaseMetadata key) {
return new MultiUserCaseNode(key);
}
@@ -95,19 +91,17 @@ final class MultiUserNode extends AbstractNode {
private final String caseName;
private final String caseCreatedDate;
private final String caseMetadataFilePath;
private final boolean caseHasAlert;
private final Path caseLogFilePath;
MultiUserCaseNode(Entry<CaseMetadata, Boolean> multiUserCase) {
MultiUserCaseNode(CaseMetadata multiUserCase) {
super(Children.LEAF);
caseName = multiUserCase.getKey().getCaseDisplayName();
caseCreatedDate = multiUserCase.getKey().getCreatedDate();
caseHasAlert = multiUserCase.getValue();
caseName = multiUserCase.getCaseDisplayName();
caseCreatedDate = multiUserCase.getCreatedDate();
super.setName(caseName);
setName(caseName);
setDisplayName(caseName);
caseMetadataFilePath = multiUserCase.getKey().getFilePath().toString();
caseLogFilePath = Paths.get(multiUserCase.getKey().getCaseDirectory(), LOG_FILE_NAME);
caseMetadataFilePath = multiUserCase.getFilePath().toString();
caseLogFilePath = Paths.get(multiUserCase.getCaseDirectory(), LOG_FILE_NAME);
}
/**
@@ -119,7 +113,6 @@ final class MultiUserNode extends AbstractNode {
return new OpenMultiUserCaseAction(caseMetadataFilePath);
}
@Messages({"MultiUserNode.AlertColumn.text=Alert"}) //text to display when there is an alert present
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
@@ -132,8 +125,6 @@ final class MultiUserNode extends AbstractNode {
caseName));
ss.put(new NodeProperty<>(Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
caseCreatedDate));
ss.put(new NodeProperty<>(Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(),
(caseHasAlert == true ? Bundle.MultiUserNode_AlertColumn_text() : "")));
ss.put(new NodeProperty<>(Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath(),
caseMetadataFilePath));
return s;