mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge pull request #7162 from wschaeferB/7802-FileSearchByAttrOffEDT
7802 initial move of file search by attrs off EDT
This commit is contained in:
commit
8e65dde1cf
@ -1,7 +1,10 @@
|
|||||||
DataSourceFilter.errorMessage.emptyDataSource=At least one data source must be selected.
|
DataSourceFilter.errorMessage.emptyDataSource=At least one data source must be selected.
|
||||||
DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.
|
DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.
|
||||||
DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected.
|
DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected.
|
||||||
|
FileSearchPanel.cancelledSearch.text=Search Was Cancelled
|
||||||
FileSearchPanel.emptyNode.display.text=No results found.
|
FileSearchPanel.emptyNode.display.text=No results found.
|
||||||
|
FileSearchPanel.searchingNode.display.text=Performing file search by attributes. Please wait.
|
||||||
|
FileSearchPanel.searchingPath.text=File Search In Progress
|
||||||
HashSearchFilter.errorMessage.emptyHash=Hash data is empty.
|
HashSearchFilter.errorMessage.emptyHash=Hash data is empty.
|
||||||
HashSearchFilter.errorMessage.wrongCharacter=MD5 contains invalid hex characters.
|
HashSearchFilter.errorMessage.wrongCharacter=MD5 contains invalid hex characters.
|
||||||
# {0} - hash data length
|
# {0} - hash data length
|
||||||
|
@ -29,15 +29,19 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
import org.openide.NotifyDescriptor;
|
import org.openide.NotifyDescriptor;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||||
@ -56,9 +60,12 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
class FileSearchPanel extends javax.swing.JPanel {
|
class FileSearchPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(FileSearchPanel.class.getName());
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private final List<FileSearchFilter> filters = new ArrayList<>();
|
private final List<FileSearchFilter> filters = new ArrayList<>();
|
||||||
private static int resultWindowCount = 0; //keep track of result windows so they get unique names
|
private static int resultWindowCount = 0; //keep track of result windows so they get unique names
|
||||||
private static final String EMPTY_WHERE_CLAUSE = NbBundle.getMessage(DateSearchFilter.class, "FileSearchPanel.emptyWhereClause.text");
|
private static final String EMPTY_WHERE_CLAUSE = NbBundle.getMessage(DateSearchFilter.class, "FileSearchPanel.emptyWhereClause.text");
|
||||||
|
private static SwingWorker<TableFilterNode, Void> searchWorker = null;
|
||||||
|
|
||||||
enum EVENT {
|
enum EVENT {
|
||||||
CHECKED
|
CHECKED
|
||||||
@ -168,56 +175,102 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
* Action when the "Search" button is pressed.
|
* Action when the "Search" button is pressed.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages("FileSearchPanel.emptyNode.display.text=No results found.")
|
@NbBundle.Messages({"FileSearchPanel.emptyNode.display.text=No results found.",
|
||||||
|
"FileSearchPanel.searchingNode.display.text=Performing file search by attributes. Please wait.",
|
||||||
|
"FileSearchPanel.searchingPath.text=File Search In Progress",
|
||||||
|
"FileSearchPanel.cancelledSearch.text=Search Was Cancelled"})
|
||||||
private void search() {
|
private void search() {
|
||||||
// change the cursor to "waiting cursor" for this operation
|
if (searchWorker != null && searchWorker.isDone()) {
|
||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
searchWorker.cancel(true);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (this.isValidSearch()) {
|
if (this.isValidSearch()) {
|
||||||
String title = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.title", ++resultWindowCount);
|
|
||||||
String pathText = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.pathText");
|
|
||||||
|
|
||||||
// try to get the number of matches first
|
// try to get the number of matches first
|
||||||
Case currentCase = Case.getCurrentCaseThrows(); // get the most updated case
|
Case currentCase = Case.getCurrentCaseThrows(); // get the most updated case
|
||||||
long totalMatches = 0;
|
Node emptyNode = new TableFilterNode(new EmptyNode(Bundle.FileSearchPanel_searchingNode_display_text()), true);
|
||||||
|
String title = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.title", ++resultWindowCount);
|
||||||
|
String pathText = Bundle.FileSearchPanel_searchingPath_text();
|
||||||
|
final DataResultTopComponent searchResultWin = DataResultTopComponent.createInstance(title, pathText,
|
||||||
|
emptyNode, 0);
|
||||||
|
searchResultWin.requestActive(); // make it the active top component
|
||||||
|
searchResultWin.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
|
searchWorker = new SwingWorker<TableFilterNode, Void>() {
|
||||||
List<AbstractFile> contentList = null;
|
List<AbstractFile> contentList = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TableFilterNode doInBackground() throws Exception {
|
||||||
try {
|
try {
|
||||||
SleuthkitCase tskDb = currentCase.getSleuthkitCase();
|
SleuthkitCase tskDb = currentCase.getSleuthkitCase();
|
||||||
contentList = tskDb.findAllFilesWhere(this.getQuery());
|
contentList = tskDb.findAllFilesWhere(getQuery());
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger logger = Logger.getLogger(this.getClass().getName());
|
Logger logger = Logger.getLogger(this.getClass().getName());
|
||||||
logger.log(Level.WARNING, "Error while trying to get the number of matches.", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error while trying to get the number of matches.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentList == null) {
|
if (contentList == null) {
|
||||||
contentList = Collections.<AbstractFile>emptyList();
|
contentList = Collections.<AbstractFile>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchNode sn = new SearchNode(contentList);
|
|
||||||
TableFilterNode tableFilterNode = new TableFilterNode(sn, true, sn.getName());
|
|
||||||
final TopComponent searchResultWin;
|
|
||||||
if (contentList.isEmpty()) {
|
if (contentList.isEmpty()) {
|
||||||
Node emptyNode = new TableFilterNode(new EmptyNode(Bundle.FileSearchPanel_emptyNode_display_text()), true);
|
return new TableFilterNode(new EmptyNode(Bundle.FileSearchPanel_emptyNode_display_text()), true);
|
||||||
searchResultWin = DataResultTopComponent.createInstance(title, pathText,
|
}
|
||||||
emptyNode, 0);
|
SearchNode sn = new SearchNode(contentList);
|
||||||
} else {
|
return new TableFilterNode(sn, true, sn.getName());
|
||||||
searchResultWin = DataResultTopComponent.createInstance(title, pathText,
|
|
||||||
tableFilterNode, contentList.size());
|
|
||||||
}
|
}
|
||||||
searchResultWin.requestActive(); // make it the active top component
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
String pathText = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.pathText");
|
||||||
|
try {
|
||||||
|
TableFilterNode tableFilterNode = get();
|
||||||
|
if (tableFilterNode == null) { //just incase this get() gets modified to return null or somehow can return null
|
||||||
|
tableFilterNode = new TableFilterNode(new EmptyNode(Bundle.FileSearchPanel_emptyNode_display_text()), true);
|
||||||
|
}
|
||||||
|
if (searchResultWin != null && searchResultWin.isOpened()) {
|
||||||
|
searchResultWin.setNode(tableFilterNode);
|
||||||
|
searchResultWin.requestActive(); // make it the active top component
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* If total matches more than 1000, pop up a dialog box that say
|
* If total matches more than 1000, pop up a dialog
|
||||||
* the performance maybe be slow and to increase the
|
* box that say the performance maybe be slow and to
|
||||||
* performance, tell the users to refine their search.
|
* increase the performance, tell the users to
|
||||||
|
* refine their search.
|
||||||
*/
|
*/
|
||||||
if (totalMatches > 10000) {
|
if (contentList.size() > 10000) {
|
||||||
// show info
|
// show info
|
||||||
String msg = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.msg", totalMatches);
|
String msg = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.msg", contentList.size());
|
||||||
String details = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.details");
|
String details = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.details");
|
||||||
MessageNotifyUtil.Notify.info(msg, details);
|
MessageNotifyUtil.Notify.info(msg, details);
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error while performing file search by attributes", ex);
|
||||||
|
} catch (CancellationException ex) {
|
||||||
|
if (searchResultWin != null && searchResultWin.isOpened()) {
|
||||||
|
Node emptyNode = new TableFilterNode(new EmptyNode(Bundle.FileSearchPanel_cancelledSearch_text()), true);
|
||||||
|
searchResultWin.setNode(emptyNode);
|
||||||
|
pathText = Bundle.FileSearchPanel_cancelledSearch_text();
|
||||||
|
}
|
||||||
|
logger.log(Level.INFO, "File search by attributes was cancelled", ex);
|
||||||
|
} finally {
|
||||||
|
if (searchResultWin != null && searchResultWin.isOpened()) {
|
||||||
|
searchResultWin.setPath(pathText);
|
||||||
|
searchResultWin.requestActive(); // make it the active top component
|
||||||
|
searchResultWin.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (searchResultWin != null && searchResultWin.isOpened()) {
|
||||||
|
searchResultWin.addPropertyChangeListener(new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if (evt.getPropertyName().equals("tcClosed") && !searchWorker.isDone() && evt.getOldValue() == null) {
|
||||||
|
searchWorker.cancel(true);
|
||||||
|
logger.log(Level.INFO, "User has closed the results window while search was in progress, search will be cancelled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
searchWorker.execute();
|
||||||
} else {
|
} else {
|
||||||
throw new FilterValidationException(
|
throw new FilterValidationException(
|
||||||
NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.exception.noFilterSelected.msg"));
|
NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.exception.noFilterSelected.msg"));
|
||||||
@ -226,8 +279,6 @@ class FileSearchPanel extends javax.swing.JPanel {
|
|||||||
NotifyDescriptor d = new NotifyDescriptor.Message(
|
NotifyDescriptor d = new NotifyDescriptor.Message(
|
||||||
NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.validationErr.msg", ex.getMessage()));
|
NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.validationErr.msg", ex.getMessage()));
|
||||||
DialogDisplayer.getDefault().notify(d);
|
DialogDisplayer.getDefault().notify(d);
|
||||||
} finally {
|
|
||||||
this.setCursor(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user