mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Bug fixes for multi-user case infrastructure
This commit is contained in:
parent
18e3b39a3f
commit
e8b74dd1db
@ -242,6 +242,7 @@
|
|||||||
<package>org.sleuthkit.autopsy.events</package>
|
<package>org.sleuthkit.autopsy.events</package>
|
||||||
<package>org.sleuthkit.autopsy.externalresults</package>
|
<package>org.sleuthkit.autopsy.externalresults</package>
|
||||||
<package>org.sleuthkit.autopsy.filesearch</package>
|
<package>org.sleuthkit.autopsy.filesearch</package>
|
||||||
|
<package>org.sleuthkit.autopsy.framework</package>
|
||||||
<package>org.sleuthkit.autopsy.ingest</package>
|
<package>org.sleuthkit.autopsy.ingest</package>
|
||||||
<package>org.sleuthkit.autopsy.keywordsearchservice</package>
|
<package>org.sleuthkit.autopsy.keywordsearchservice</package>
|
||||||
<package>org.sleuthkit.autopsy.menuactions</package>
|
<package>org.sleuthkit.autopsy.menuactions</package>
|
||||||
|
@ -43,8 +43,7 @@ final public class ExitAction implements ActionListener {
|
|||||||
try {
|
try {
|
||||||
Case.closeCurrentCase();
|
Case.closeCurrentCase();
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
// RJCTODO: Pop up here
|
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Error closing the current case on exit", ex); //NON-NLS
|
||||||
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Error closing the current case", ex); //NON-NLS
|
|
||||||
} finally {
|
} finally {
|
||||||
LifecycleManager.getDefault().exit();
|
LifecycleManager.getDefault().exit();
|
||||||
}
|
}
|
||||||
|
@ -98,12 +98,9 @@ AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules
|
|||||||
AddImageWizardIterator.stepXofN=Step {0} of {1}
|
AddImageWizardIterator.stepXofN=Step {0} of {1}
|
||||||
AddLocalFilesTask.localFileAdd.progress.text=Adding\: {0}/{1}
|
AddLocalFilesTask.localFileAdd.progress.text=Adding\: {0}/{1}
|
||||||
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
|
Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
|
||||||
Case.create.exception.msg=Error creating a case\: {0} in dir {1}
|
|
||||||
Case.databaseConnectionInfo.error.msg=Error accessing database server connection info. See Tools, Options, Multi-user.
|
Case.databaseConnectionInfo.error.msg=Error accessing database server connection info. See Tools, Options, Multi-user.
|
||||||
Case.open.exception.blankCase.msg=Case name is blank.
|
|
||||||
Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made\:\n {0}
|
Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made\:\n {0}
|
||||||
Case.open.msgDlg.updated.title=Case Database Schema Update
|
Case.open.msgDlg.updated.title=Case Database Schema Update
|
||||||
Case.open.exception.checkFile.msg=Case file must have {0} extension.
|
|
||||||
Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-user.
|
Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-user.
|
||||||
Case.checkImgExist.confDlg.doesntExist.msg={0} has detected that one of the images associated with \n\
|
Case.checkImgExist.confDlg.doesntExist.msg={0} has detected that one of the images associated with \n\
|
||||||
this case are missing. Would you like to search for them now?\n\
|
this case are missing. Would you like to search for them now?\n\
|
||||||
@ -113,9 +110,6 @@ Please note that you will still be able to browse directories and generate repor
|
|||||||
if you choose No, but you will not be able to view file content or run the ingest process.
|
if you choose No, but you will not be able to view file content or run the ingest process.
|
||||||
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
||||||
Case.addImg.exception.msg=Error adding image to the case
|
Case.addImg.exception.msg=Error adding image to the case
|
||||||
Case.closeCase.exception.msg=Error while trying to close the current case.
|
|
||||||
Case.deleteCase.exception.msg=Error deleting the case dir\: {0}
|
|
||||||
Case.deleteCase.exception.msg2=Error deleting the case dir\: {0}
|
|
||||||
Case.updateCaseName.exception.msg=Error while trying to update the case name.
|
Case.updateCaseName.exception.msg=Error while trying to update the case name.
|
||||||
Case.updateExaminer.exception.msg=Error while trying to update the examiner.
|
Case.updateExaminer.exception.msg=Error while trying to update the examiner.
|
||||||
Case.updateCaseNum.exception.msg=Error while trying to update the case number.
|
Case.updateCaseNum.exception.msg=Error while trying to update the case number.
|
||||||
@ -240,4 +234,3 @@ LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
|
|||||||
IngestJobInfoPanel.jLabel1.text=Ingest Modules
|
IngestJobInfoPanel.jLabel1.text=Ingest Modules
|
||||||
IngestJobInfoPanel.jLabel2.text=Ingest Jobs
|
IngestJobInfoPanel.jLabel2.text=Ingest Jobs
|
||||||
CaseInformationPanel.closeButton.text=Close
|
CaseInformationPanel.closeButton.text=Close
|
||||||
ProgressPanel.progressMessage.text=Message
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
Case.closeCase.exception.msgCTL_AddImage=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0...
|
|
||||||
CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
CTL_AddImageButton=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u8ffd\u52a0
|
||||||
CTL_CaseCloseAct=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b
|
CTL_CaseCloseAct=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b
|
||||||
CTL_CaseNewAction=\u65b0\u898f\u30b1\u30fc\u30b9...
|
CTL_CaseNewAction=\u65b0\u898f\u30b1\u30fc\u30b9...
|
||||||
@ -80,21 +79,15 @@ AddImageWizardIngestConfigVisual.getName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30
|
|||||||
AddImageWizardIterator.stepXofN=\u30b9\u30c6\u30c3\u30d7{0}\uff0f{1}
|
AddImageWizardIterator.stepXofN=\u30b9\u30c6\u30c3\u30d7{0}\uff0f{1}
|
||||||
AddLocalFilesTask.localFileAdd.progress.text=\u8ffd\u52a0\u4e2d\uff1a{0}/{1}
|
AddLocalFilesTask.localFileAdd.progress.text=\u8ffd\u52a0\u4e2d\uff1a{0}/{1}
|
||||||
Case.getCurCase.exception.noneOpen=\u4f5c\u696d\u4e2d\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\uff1b\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\uff01
|
Case.getCurCase.exception.noneOpen=\u4f5c\u696d\u4e2d\u306e\u30b1\u30fc\u30b9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\uff1b\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\uff01
|
||||||
Case.create.exception.msg=\u30b1\u30fc\u30b9\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a\u30c7\u30a3\u30ec\u30af\u30c8\u30ea{1}\u306e{0}
|
|
||||||
Case.open.exception.blankCase.msg=\u30b1\u30fc\u30b9\u540d\u304c\u7a7a\u767d\u3067\u3059\u3002
|
|
||||||
Case.open.msgDlg.updated.msg=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\uff1a\n\
|
Case.open.msgDlg.updated.msg=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n\u6b21\u306e\u30d1\u30b9\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u304c\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\uff1a\n\
|
||||||
{0}
|
{0}
|
||||||
Case.open.msgDlg.updated.title=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0
|
Case.open.msgDlg.updated.title=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30b9\u30ad\u30fc\u30de\u3092\u66f4\u65b0
|
||||||
Case.open.exception.checkFile.msg=\u30b1\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f{0}\u62e1\u5f35\u5b50\u304c\u5fc5\u8981\u3067\u3059\u3002
|
|
||||||
Case.checkImgExist.confDlg.doesntExist.msg={0} \u304c\u3053\u306e\u30b1\u30fc\u30b9\u306b\u95a2\u9023\u3059\u308b\u30a4\u30e1\u30fc\u30b8\u306e\u3046\u3061\uff11\u3064\u304c\u6b20\u843d\u3057\u3066\u3044\u308b\u306e\u3092\u691c\u51fa\u3057\u307e\u3057\u305f\u3002\u305d\u308c\u3092\u4eca\u304b\u3089\u691c\u7d22\u3057\u307e\u3059\u304b\uff1f\n\n\
|
Case.checkImgExist.confDlg.doesntExist.msg={0} \u304c\u3053\u306e\u30b1\u30fc\u30b9\u306b\u95a2\u9023\u3059\u308b\u30a4\u30e1\u30fc\u30b8\u306e\u3046\u3061\uff11\u3064\u304c\u6b20\u843d\u3057\u3066\u3044\u308b\u306e\u3092\u691c\u51fa\u3057\u307e\u3057\u305f\u3002\u305d\u308c\u3092\u4eca\u304b\u3089\u691c\u7d22\u3057\u307e\u3059\u304b\uff1f\n\n\
|
||||||
\u4ee5\u524d\u3001\u30a4\u30e1\u30fc\u30b8\u306f\u6b21\u306b\u3042\u308a\u307e\u3057\u305f\uff1a\n\
|
\u4ee5\u524d\u3001\u30a4\u30e1\u30fc\u30b8\u306f\u6b21\u306b\u3042\u308a\u307e\u3057\u305f\uff1a\n\
|
||||||
{1}\n\
|
{1}\n\
|
||||||
\u3044\u3044\u3048\u3092\u9078\u629e\u3057\u3066\u3082\u3001\u4eca\u5f8c\u3082\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u95b2\u89a7\u3057\u3001\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u304c\u3067\u304d\u307e\u3059\u304c\u3001\n\u30d5\u30a1\u30a4\u30eb\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u8868\u793a\u307e\u305f\u306f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30d7\u30ed\u30bb\u30b9\u306e\u5b9f\u884c\u304c\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002
|
\u3044\u3044\u3048\u3092\u9078\u629e\u3057\u3066\u3082\u3001\u4eca\u5f8c\u3082\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u95b2\u89a7\u3057\u3001\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u304c\u3067\u304d\u307e\u3059\u304c\u3001\n\u30d5\u30a1\u30a4\u30eb\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u8868\u793a\u307e\u305f\u306f\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30d7\u30ed\u30bb\u30b9\u306e\u5b9f\u884c\u304c\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002
|
||||||
Case.checkImgExist.confDlg.doesntExist.title=\u6b20\u843d\u3057\u3066\u3044\u308b\u30a4\u30e1\u30fc\u30b8
|
Case.checkImgExist.confDlg.doesntExist.title=\u6b20\u843d\u3057\u3066\u3044\u308b\u30a4\u30e1\u30fc\u30b8
|
||||||
Case.addImg.exception.msg=\u30b1\u30fc\u30b9\u306b\u30a4\u30e1\u30fc\u30b8\u3092\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
Case.addImg.exception.msg=\u30b1\u30fc\u30b9\u306b\u30a4\u30e1\u30fc\u30b8\u3092\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||||
Case.closeCase.exception.msg=\u4f5c\u696d\u4e2d\u306e\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b\u6700\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
|
||||||
Case.deleteCase.exception.msg=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}
|
|
||||||
Case.deleteCase.exception.msg2=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u524a\u9664\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a{0}
|
|
||||||
Case.updateCaseName.exception.msg=\u30b1\u30fc\u30b9\u540d\u3092\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
Case.updateCaseName.exception.msg=\u30b1\u30fc\u30b9\u540d\u3092\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||||
Case.updateExaminer.exception.msg=\u8abf\u67fb\u62c5\u5f53\u8005\u3092\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
Case.updateExaminer.exception.msg=\u8abf\u67fb\u62c5\u5f53\u8005\u3092\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||||
Case.updateCaseNum.exception.msg=\u30b1\u30fc\u30b9\u756a\u53f7\u3092\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
Case.updateCaseNum.exception.msg=\u30b1\u30fc\u30b9\u756a\u53f7\u3092\u66f4\u65b0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2011-2017 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.casemodule;
|
|
||||||
|
|
||||||
import java.awt.Cursor;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import org.openide.DialogDescriptor;
|
|
||||||
import org.openide.DialogDisplayer;
|
|
||||||
import org.openide.NotifyDescriptor;
|
|
||||||
import org.openide.util.NbBundle;
|
|
||||||
import org.openide.windows.WindowManager;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A utility class for common code for case actions.
|
|
||||||
*/
|
|
||||||
class CaseActionHelper {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to closes the current case, if any, with a checks to see if ingest
|
|
||||||
* is running; if it is, the user is given the opportunity to let the ingest
|
|
||||||
* continue and stop the case action.
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* @return True if the current case, if any, is closed, false otherwise.
|
|
||||||
*/
|
|
||||||
// RJCTODO: Be sure to test this! Discard this class
|
|
||||||
static boolean closeCaseAndContinueAction() {
|
|
||||||
if (IngestManager.getInstance().isIngestRunning()) {
|
|
||||||
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
|
||||||
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO
|
|
||||||
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO
|
|
||||||
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
|
|
||||||
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
|
||||||
Object choice = DialogDisplayer.getDefault().notify(descriptor);
|
|
||||||
if (null != choice && DialogDescriptor.YES_OPTION == choice) {
|
|
||||||
IngestManager.getInstance().cancelAllIngestJobs(IngestJob.CancellationReason.USER_CANCELLED);
|
|
||||||
// RJCTODO; refer to JIRA here for blocking wait on cancel...
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
|
||||||
try {
|
|
||||||
Case.closeCurrentCase();
|
|
||||||
} catch (CaseActionException ex) {
|
|
||||||
// RJCTODO: Pop up here
|
|
||||||
Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.SEVERE, "Error closing case.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private contructor to prevent instantiation.
|
|
||||||
*/
|
|
||||||
private CaseActionHelper() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,7 @@ import java.awt.Component;
|
|||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.logging.Level;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
@ -38,6 +39,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,6 +54,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
|
|||||||
public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar {
|
public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Logger logger = Logger.getLogger(CaseCloseAction.class.getName());
|
||||||
private final JButton toolbarButton = new JButton();
|
private final JButton toolbarButton = new JButton();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,8 +80,8 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
|
|||||||
*/
|
*/
|
||||||
if (IngestManager.getInstance().isIngestRunning()) {
|
if (IngestManager.getInstance().isIngestRunning()) {
|
||||||
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
||||||
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"),
|
||||||
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"),
|
||||||
NotifyDescriptor.YES_NO_OPTION,
|
NotifyDescriptor.YES_NO_OPTION,
|
||||||
NotifyDescriptor.WARNING_MESSAGE);
|
NotifyDescriptor.WARNING_MESSAGE);
|
||||||
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
||||||
@ -105,7 +108,7 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
|
|||||||
try {
|
try {
|
||||||
get();
|
get();
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
// RJCTODO: Pop up error and log
|
logger.log(Level.SEVERE, "Error closing the current case", ex);
|
||||||
}
|
}
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
|
@ -169,45 +169,10 @@ public final class CaseMetadata {
|
|||||||
*
|
*
|
||||||
* @return The case display name.
|
* @return The case display name.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Deal with the change
|
|
||||||
public String getCaseName() {
|
public String getCaseName() {
|
||||||
return caseName;
|
return caseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the case display name. This does not change the name of the case
|
|
||||||
* directory, the case database, or the text index name.
|
|
||||||
*
|
|
||||||
* @param caseName A case display name.
|
|
||||||
*/
|
|
||||||
// RJCTODO: Deal with the change, remove this
|
|
||||||
void setCaseName(String caseName) throws CaseMetadataException {
|
|
||||||
String oldCaseName = caseName;
|
|
||||||
this.caseName = caseName;
|
|
||||||
try {
|
|
||||||
writeToFile();
|
|
||||||
} catch (CaseMetadataException ex) {
|
|
||||||
this.caseName = oldCaseName;
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the text index name.
|
|
||||||
*
|
|
||||||
* @param caseTextIndexName The text index name.
|
|
||||||
*/
|
|
||||||
void setTextIndexName(String caseTextIndexName) throws CaseMetadataException {
|
|
||||||
String oldIndexName = caseTextIndexName;
|
|
||||||
this.textIndexName = caseTextIndexName;
|
|
||||||
try {
|
|
||||||
writeToFile();
|
|
||||||
} catch (CaseMetadataException ex) {
|
|
||||||
this.textIndexName = oldIndexName;
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the case display name.
|
* Gets the case display name.
|
||||||
*
|
*
|
||||||
@ -223,7 +188,6 @@ public final class CaseMetadata {
|
|||||||
*
|
*
|
||||||
* @param caseName A case display name.
|
* @param caseName A case display name.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Deal with the change
|
|
||||||
void setCaseDisplayName(String caseName) throws CaseMetadataException {
|
void setCaseDisplayName(String caseName) throws CaseMetadataException {
|
||||||
String oldCaseName = caseName;
|
String oldCaseName = caseName;
|
||||||
this.caseDisplayName = caseName;
|
this.caseDisplayName = caseName;
|
||||||
@ -282,6 +246,22 @@ public final class CaseMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text index name.
|
||||||
|
*
|
||||||
|
* @param caseTextIndexName The text index name.
|
||||||
|
*/
|
||||||
|
void setTextIndexName(String caseTextIndexName) throws CaseMetadataException {
|
||||||
|
String oldIndexName = caseTextIndexName;
|
||||||
|
this.textIndexName = caseTextIndexName;
|
||||||
|
try {
|
||||||
|
writeToFile();
|
||||||
|
} catch (CaseMetadataException ex) {
|
||||||
|
this.textIndexName = oldIndexName;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the text index name.
|
* Gets the text index name.
|
||||||
*
|
*
|
||||||
@ -349,7 +329,6 @@ public final class CaseMetadata {
|
|||||||
* @throws CaseMetadataException If there is an error writing to the case
|
* @throws CaseMetadataException If there is an error writing to the case
|
||||||
* metadata file.
|
* metadata file.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Should we have a backup copy of the file in case of error?
|
|
||||||
private void writeToFile() throws CaseMetadataException {
|
private void writeToFile() throws CaseMetadataException {
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
|
@ -43,7 +43,9 @@ import org.sleuthkit.autopsy.coreutils.Version;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action that opens an existing case.
|
* An action that opens an existing case. It is associated with the Case/Open
|
||||||
|
* menu item via the layer.xml file, with a toolbar button, and with a button on
|
||||||
|
* the startup window.
|
||||||
*/
|
*/
|
||||||
@ServiceProvider(service = CaseOpenAction.class)
|
@ServiceProvider(service = CaseOpenAction.class)
|
||||||
public final class CaseOpenAction extends CallableSystemAction implements ActionListener {
|
public final class CaseOpenAction extends CallableSystemAction implements ActionListener {
|
||||||
@ -82,8 +84,8 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
|
|||||||
*/
|
*/
|
||||||
if (IngestManager.getInstance().isIngestRunning()) {
|
if (IngestManager.getInstance().isIngestRunning()) {
|
||||||
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
||||||
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"),
|
||||||
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"),
|
||||||
NotifyDescriptor.YES_NO_OPTION,
|
NotifyDescriptor.YES_NO_OPTION,
|
||||||
NotifyDescriptor.WARNING_MESSAGE);
|
NotifyDescriptor.WARNING_MESSAGE);
|
||||||
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
||||||
@ -116,7 +118,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground() throws Exception {
|
protected Void doInBackground() throws Exception {
|
||||||
Case.openCurrentCase(path);
|
Case.openAsCurrentCase(path);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,15 +77,15 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
|||||||
*/
|
*/
|
||||||
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
|
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
|
||||||
initComponents();
|
initComponents();
|
||||||
caseNameTextField.setText(currentCase.getName());
|
caseNameTextField.setText(currentCase.getDisplayName());
|
||||||
String caseNumber = currentCase.getNumber();
|
String caseNumber = currentCase.getNumber();
|
||||||
if (!caseNumber.equals("")) {
|
if (!caseNumber.isEmpty()) {
|
||||||
caseNumberField.setText(caseNumber);
|
caseNumberField.setText(caseNumber);
|
||||||
} else {
|
} else {
|
||||||
caseNumberField.setText("N/A");
|
caseNumberField.setText("N/A");
|
||||||
}
|
}
|
||||||
String examiner = currentCase.getExaminer();
|
String examiner = currentCase.getExaminer();
|
||||||
if (!examiner.equals("")) {
|
if (!examiner.isEmpty()) {
|
||||||
examinerField.setText(examiner);
|
examinerField.setText(examiner);
|
||||||
} else {
|
} else {
|
||||||
examinerField.setText("N/A");
|
examinerField.setText("N/A");
|
||||||
@ -303,13 +303,13 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
|||||||
* @param evt The action event
|
* @param evt The action event
|
||||||
*/
|
*/
|
||||||
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
|
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
|
||||||
String oldCaseName = Case.getCurrentCase().getName();
|
String oldCaseName = Case.getCurrentCase().getDisplayName();
|
||||||
String newCaseName = caseNameTextField.getText();
|
String newCaseName = caseNameTextField.getText();
|
||||||
// check if the old and new case name is not equal
|
// check if the old and new case name is not equal
|
||||||
if (!oldCaseName.equals(newCaseName)) {
|
if (!oldCaseName.equals(newCaseName)) {
|
||||||
|
|
||||||
// check if the case name is empty
|
// check if the case name is empty
|
||||||
if (newCaseName.trim().equals("")) {
|
if (newCaseName.trim().isEmpty()) {
|
||||||
JOptionPane.showMessageDialog(caller,
|
JOptionPane.showMessageDialog(caller,
|
||||||
NbBundle.getMessage(this.getClass(),
|
NbBundle.getMessage(this.getClass(),
|
||||||
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),
|
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2015 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -77,8 +77,13 @@ final class CollaborationMonitor {
|
|||||||
* collaborating nodes, informs the user of collaboration tasks on other
|
* collaborating nodes, informs the user of collaboration tasks on other
|
||||||
* nodes using progress bars, and monitors the health of key collaboration
|
* nodes using progress bars, and monitors the health of key collaboration
|
||||||
* services.
|
* services.
|
||||||
|
*
|
||||||
|
* @param eventChannelPrefix The prefix for the remote events channel.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.casemodule.CollaborationMonitor.CollaborationMonitorException
|
||||||
*/
|
*/
|
||||||
CollaborationMonitor() throws CollaborationMonitorException {
|
CollaborationMonitor(String eventChannelPrefix) throws CollaborationMonitorException {
|
||||||
/**
|
/**
|
||||||
* Get the local host name so it can be used to identify the source of
|
* Get the local host name so it can be used to identify the source of
|
||||||
* collaboration tasks broadcast by this node.
|
* collaboration tasks broadcast by this node.
|
||||||
@ -91,9 +96,7 @@ final class CollaborationMonitor {
|
|||||||
*/
|
*/
|
||||||
eventPublisher = new AutopsyEventPublisher();
|
eventPublisher = new AutopsyEventPublisher();
|
||||||
try {
|
try {
|
||||||
Case openedCase = Case.getCurrentCase();
|
eventPublisher.openRemoteEventChannel(String.format(EVENT_CHANNEL_NAME, eventChannelPrefix));
|
||||||
String channelPrefix = openedCase.getTextIndexName();
|
|
||||||
eventPublisher.openRemoteEventChannel(String.format(EVENT_CHANNEL_NAME, channelPrefix));
|
|
||||||
} catch (AutopsyEventException ex) {
|
} catch (AutopsyEventException ex) {
|
||||||
throw new CollaborationMonitorException("Failed to initialize", ex);
|
throw new CollaborationMonitorException("Failed to initialize", ex);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ final class DeleteCurrentCaseAction extends CallableSystemAction {
|
|||||||
try {
|
try {
|
||||||
Case currentCase = Case.getCurrentCase();
|
Case currentCase = Case.getCurrentCase();
|
||||||
String caseName = currentCase.getName();
|
String caseName = currentCase.getName();
|
||||||
|
String caseDirectory = currentCase.getCaseDirectory();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do a confirmation dialog and close the current case if the user
|
* Do a confirmation dialog and close the current case if the user
|
||||||
@ -68,16 +69,15 @@ final class DeleteCurrentCaseAction extends CallableSystemAction {
|
|||||||
NotifyDescriptor.NO_OPTION));
|
NotifyDescriptor.NO_OPTION));
|
||||||
if (null != response && DialogDescriptor.YES_OPTION == response) {
|
if (null != response && DialogDescriptor.YES_OPTION == response) {
|
||||||
try {
|
try {
|
||||||
Case.deleteCurrentCase(); // RJCTODO: Test this!
|
Case.deleteCurrentCase();
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Failed to delete case %s", caseName), ex);
|
logger.log(Level.SEVERE, String.format("Failed to delete case %s at %s", caseName, caseDirectory), ex);
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
null,
|
null,
|
||||||
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getMessage()),
|
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getMessage()),
|
||||||
Bundle.Case_deleteCaseFailureMessageBox_title(),
|
Bundle.Case_deleteCaseFailureMessageBox_title(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
// RJCTODO: Fix this
|
|
||||||
// because the "Delete Case" button is in the "CaseProperties" window, we have to close that window when we delete the case.
|
// because the "Delete Case" button is in the "CaseProperties" window, we have to close that window when we delete the case.
|
||||||
CasePropertiesAction.closeCasePropertiesWindow();
|
CasePropertiesAction.closeCasePropertiesWindow();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.DataSourceUtils;
|
import org.sleuthkit.autopsy.coreutils.DataSourceUtils;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A image file data source processor that implements the DataSourceProcessor
|
* A image file data source processor that implements the DataSourceProcessor
|
||||||
|
@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.DriveUtils;
|
import org.sleuthkit.autopsy.coreutils.DriveUtils;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A local drive data source processor that implements the DataSourceProcessor
|
* A local drive data source processor that implements the DataSourceProcessor
|
||||||
|
@ -29,7 +29,7 @@ import org.openide.util.lookup.ServiceProviders;
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A local/logical files and/or directories data source processor that
|
* A local/logical files and/or directories data source processor that
|
||||||
|
@ -27,9 +27,10 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
|
import org.openide.DialogDescriptor;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
|
import org.openide.NotifyDescriptor;
|
||||||
import org.openide.WizardDescriptor;
|
import org.openide.WizardDescriptor;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
@ -37,7 +38,9 @@ import org.openide.util.actions.CallableSystemAction;
|
|||||||
import org.openide.util.actions.SystemAction;
|
import org.openide.util.actions.SystemAction;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action that creates and runs the new case wizard.
|
* An action that creates and runs the new case wizard.
|
||||||
@ -50,13 +53,28 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performAction() {
|
public void performAction() {
|
||||||
if (CaseActionHelper.closeCaseAndContinueAction()) {
|
/*
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); // RJCTODO: Is this right?
|
* If ingest is running, give the user the option to abort changing
|
||||||
runNewCaseWizard();
|
* cases.
|
||||||
|
*/
|
||||||
|
// Is this right here?
|
||||||
|
if (IngestManager.getInstance().isIngestRunning()) {
|
||||||
|
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
||||||
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"),
|
||||||
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"),
|
||||||
|
NotifyDescriptor.YES_NO_OPTION,
|
||||||
|
NotifyDescriptor.WARNING_MESSAGE);
|
||||||
|
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
||||||
|
Object response = DialogDisplayer.getDefault().notify(descriptor);
|
||||||
|
if (DialogDescriptor.NO_OPTION == response) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
runNewCaseWizard();
|
||||||
|
}
|
||||||
|
|
||||||
private void runNewCaseWizard() {
|
private void runNewCaseWizard() {
|
||||||
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
final WizardDescriptor wizardDescriptor = new WizardDescriptor(getNewCaseWizardPanels());
|
final WizardDescriptor wizardDescriptor = new WizardDescriptor(getNewCaseWizardPanels());
|
||||||
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
||||||
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
|
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
|
||||||
@ -72,7 +90,7 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
|||||||
final String caseName = (String) wizardDescriptor.getProperty("caseName"); //NON-NLS
|
final String caseName = (String) wizardDescriptor.getProperty("caseName"); //NON-NLS
|
||||||
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
||||||
CaseType caseType = CaseType.values()[(int) wizardDescriptor.getProperty("caseType")]; //NON-NLS
|
CaseType caseType = CaseType.values()[(int) wizardDescriptor.getProperty("caseType")]; //NON-NLS
|
||||||
Case.createCurrentCase(createdDirectory, caseName, caseNumber, examiner, caseType);
|
Case.createAsCurrentCase(createdDirectory, caseName, caseNumber, examiner, caseType);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,16 +102,16 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
|||||||
addImageAction.actionPerformed(null);
|
addImageAction.actionPerformed(null);
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
|
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
WindowManager.getDefault().getMainWindow(),
|
WindowManager.getDefault().getMainWindow(),
|
||||||
(ex instanceof ExecutionException ? ex.getCause().getMessage() : ex.getMessage()),
|
(ex instanceof ExecutionException ? ex.getCause().getMessage() : ex.getMessage()),
|
||||||
NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"), //NON-NLS
|
NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"), //NON-NLS
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
StartupWindowProvider.getInstance().close(); // RC: Why close and open?
|
StartupWindowProvider.getInstance().close();
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
});
|
|
||||||
doFailedCaseCleanup(wizardDescriptor);
|
doFailedCaseCleanup(wizardDescriptor);
|
||||||
|
} finally {
|
||||||
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
@ -107,11 +125,8 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
|||||||
private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor) {
|
private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor) {
|
||||||
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
||||||
if (createdDirectory != null) {
|
if (createdDirectory != null) {
|
||||||
Case.deleteCaseDirectory(new File(createdDirectory));
|
FileUtil.deleteDir(new File(createdDirectory));
|
||||||
}
|
}
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +35,7 @@ import org.openide.WizardDescriptor;
|
|||||||
import org.openide.WizardValidationException;
|
import org.openide.WizardValidationException;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +176,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
createdDirectory = (String) settings.getProperty("createdDirectory"); //NON-NLS
|
createdDirectory = (String) settings.getProperty("createdDirectory"); //NON-NLS
|
||||||
if (createdDirectory != null && !createdDirectory.equals("")) {
|
if (createdDirectory != null && !createdDirectory.equals("")) {
|
||||||
logger.log(Level.INFO, "Deleting a case dir in readSettings(): " + createdDirectory); //NON-NLS
|
logger.log(Level.INFO, "Deleting a case dir in readSettings(): " + createdDirectory); //NON-NLS
|
||||||
Case.deleteCaseDirectory(new File(createdDirectory));
|
FileUtil.deleteDir(new File(createdDirectory));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.WARNING, "Could not read wizard settings in NewCaseWizardPanel1, ", e); //NON-NLS
|
logger.log(Level.WARNING, "Could not read wizard settings in NewCaseWizardPanel1, ", e); //NON-NLS
|
||||||
@ -298,7 +299,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
|
|
||||||
// delete the folder if we already created the folder and the error shows up
|
// delete the folder if we already created the folder and the error shows up
|
||||||
if (new File(caseDirPath).exists()) {
|
if (new File(caseDirPath).exists()) {
|
||||||
Case.deleteCaseDirectory(new File(caseDirPath));
|
FileUtil.deleteDir(new File(caseDirPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
String errorMsg = NbBundle.getMessage(this.getClass(),
|
String errorMsg = NbBundle.getMessage(this.getClass(),
|
||||||
|
@ -124,7 +124,7 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
} else {
|
} else {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Case.openCurrentCase(casePath);
|
Case.openAsCurrentCase(casePath);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", casePath), ex); //NON-NLS
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", casePath), ex); //NON-NLS
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2014 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -30,13 +30,13 @@ import java.util.List;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
import org.openide.filesystems.FileUtil;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
import org.openide.filesystems.FileUtil;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The action in this class is to clear the list of "Recent Cases". The
|
* The action in this class is to clear the list of "Recent Cases". The
|
||||||
@ -45,14 +45,13 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
*/
|
*/
|
||||||
final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
||||||
|
|
||||||
static final int LENGTH = 6;
|
private static final long serialVersionUID = 1L;
|
||||||
static final String NAME_PROP_KEY = "LBL_RecentCase_Name"; //NON-NLS
|
private static final int LENGTH = 6;
|
||||||
static final String PATH_PROP_KEY = "LBL_RecentCase_Path"; //NON-NLS
|
private static final String NAME_PROP_KEY = "LBL_RecentCase_Name"; //NON-NLS
|
||||||
static final RecentCase BLANK_RECENTCASE = new RecentCase("", "");
|
private static final String PATH_PROP_KEY = "LBL_RecentCase_Path"; //NON-NLS
|
||||||
|
private static final RecentCase BLANK_RECENTCASE = new RecentCase("", "");
|
||||||
private final static RecentCases INSTANCE = new RecentCases();
|
private final static RecentCases instance = new RecentCases();
|
||||||
|
private final Deque<RecentCase> recentCases; // newest case is last case
|
||||||
private Deque<RecentCase> recentCases; // newest case is last case
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the instance of the RecentCases singleton.
|
* Gets the instance of the RecentCases singleton.
|
||||||
@ -61,8 +60,8 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
|||||||
* @return INSTANCE the RecentCases singleton
|
* @return INSTANCE the RecentCases singleton
|
||||||
*/
|
*/
|
||||||
static public RecentCases getInstance() {
|
static public RecentCases getInstance() {
|
||||||
INSTANCE.refreshRecentCases();
|
instance.refreshRecentCases();
|
||||||
return INSTANCE;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,7 +83,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load recentCases from properties
|
// Load recentCases from properties
|
||||||
recentCases = new LinkedList<RecentCase>();
|
recentCases = new LinkedList<>();
|
||||||
|
|
||||||
for (int i = 0; i < LENGTH; i++) {
|
for (int i = 0; i < LENGTH; i++) {
|
||||||
final RecentCase rc = new RecentCase(getName(i), getPath(i));
|
final RecentCase rc = new RecentCase(getName(i), getPath(i));
|
||||||
@ -256,7 +255,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
UpdateRecentCases.hasRecentCase = false;
|
UpdateRecentCases.setHasRecentCase(false);
|
||||||
|
|
||||||
recentCases.clear();
|
recentCases.clear();
|
||||||
|
|
||||||
@ -375,7 +374,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
String currentCaseName = null;
|
String currentCaseName = null;
|
||||||
try {
|
try {
|
||||||
currentCaseName = Case.getCurrentCase().getName();
|
currentCaseName = Case.getCurrentCase().getDisplayName();
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// in case there is no current case.
|
// in case there is no current case.
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,17 @@ import java.awt.event.ActionListener;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import org.openide.DialogDescriptor;
|
||||||
|
import org.openide.DialogDisplayer;
|
||||||
|
import org.openide.NotifyDescriptor;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action listener that opens a recent case.
|
* An action listener for a specific case, associated with a Recent Cases menu
|
||||||
*
|
* item for the case by a DynamicMenuContent content JMenuItem.
|
||||||
* IMPORTANT: Must be called in the Swing Event Dispatch Thread (EDT).
|
|
||||||
*/
|
*/
|
||||||
class RecentItems implements ActionListener {
|
class RecentItems implements ActionListener {
|
||||||
|
|
||||||
@ -41,7 +44,9 @@ class RecentItems implements ActionListener {
|
|||||||
private final String caseMetaDataFilePath;
|
private final String caseMetaDataFilePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an action listener that opens a recent case.
|
* Constructs an action listener for a specific case, associated with a
|
||||||
|
* Recent Cases menu item for the case by a DynamicMenuContent content
|
||||||
|
* JMenuItem.
|
||||||
*
|
*
|
||||||
* @param caseName The name of the case.
|
* @param caseName The name of the case.
|
||||||
* @param caseMetaDataFilePath The path to the case metadata file.
|
* @param caseMetaDataFilePath The path to the case metadata file.
|
||||||
@ -52,37 +57,42 @@ class RecentItems implements ActionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the recent case.
|
* Opens the case associated with the action.
|
||||||
*
|
*
|
||||||
* @param e the action event
|
* @param e the action event
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (CaseActionHelper.closeCaseAndContinueAction()) {
|
/*
|
||||||
if (caseName.isEmpty() || caseMetaDataFilePath.isEmpty() || (!new File(caseMetaDataFilePath).exists())) {
|
* If ingest is running, give the user the option to abort changing
|
||||||
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
|
* cases.
|
||||||
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text", caseName),
|
*/
|
||||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
|
if (IngestManager.getInstance().isIngestRunning()) {
|
||||||
JOptionPane.ERROR_MESSAGE);
|
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
||||||
RecentCases.getInstance().removeRecentCase(caseName, caseMetaDataFilePath);
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"),
|
||||||
EventQueue.invokeLater(() -> {
|
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"),
|
||||||
StartupWindowProvider.getInstance().open();
|
NotifyDescriptor.YES_NO_OPTION,
|
||||||
});
|
NotifyDescriptor.WARNING_MESSAGE);
|
||||||
} else {
|
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
||||||
|
Object response = DialogDisplayer.getDefault().notify(descriptor);
|
||||||
|
if (DialogDescriptor.NO_OPTION == response) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
Case.openCurrentCase(caseMetaDataFilePath);
|
Case.openAsCurrentCase(caseMetaDataFilePath);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetaDataFilePath), ex); //NON-NLS
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetaDataFilePath), ex); //NON-NLS
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
WindowManager.getDefault().getMainWindow(),
|
WindowManager.getDefault().getMainWindow(),
|
||||||
ex.getMessage(), // Should be user-friendly
|
ex.getMessage(), // Should be user-friendly
|
||||||
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
}
|
} finally {
|
||||||
}
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
*/
|
*/
|
||||||
public class SingleUserCaseConverter {
|
public class SingleUserCaseConverter {
|
||||||
|
|
||||||
static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS // RJCTODO
|
private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS
|
||||||
private static final String AUTOPSY_DB_FILE = "autopsy.db"; //NON-NLS
|
private static final String AUTOPSY_DB_FILE = "autopsy.db"; //NON-NLS
|
||||||
private static final String DOTAUT = CaseMetadata.getFileExtension(); //NON-NLS
|
private static final String DOTAUT = CaseMetadata.getFileExtension(); //NON-NLS
|
||||||
private static final String TIMELINE_FOLDER = "Timeline"; //NON-NLS
|
private static final String TIMELINE_FOLDER = "Timeline"; //NON-NLS
|
||||||
@ -196,7 +196,7 @@ public class SingleUserCaseConverter {
|
|||||||
CaseMetadata newCaseMetadata = new CaseMetadata(icd.getCaseOutputFolder().toString(),
|
CaseMetadata newCaseMetadata = new CaseMetadata(icd.getCaseOutputFolder().toString(),
|
||||||
CaseType.MULTI_USER_CASE,
|
CaseType.MULTI_USER_CASE,
|
||||||
icd.getNewCaseName(),
|
icd.getNewCaseName(),
|
||||||
icd.getNewCaseName(), // RJCTODO
|
icd.getNewCaseName(),
|
||||||
oldCaseMetadata.getCaseNumber(),
|
oldCaseMetadata.getCaseNumber(),
|
||||||
oldCaseMetadata.getExaminer(),
|
oldCaseMetadata.getExaminer(),
|
||||||
dbName);
|
dbName);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2015 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -30,15 +30,20 @@ import org.openide.util.actions.SystemAction;
|
|||||||
*/
|
*/
|
||||||
class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
|
class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
|
||||||
|
|
||||||
int length;
|
private static final long serialVersionUID = 1L;
|
||||||
static boolean hasRecentCase = false;
|
private static int NUM_CASES_TO_DISPLAY;
|
||||||
|
private static boolean hasRecentCase = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the constructor
|
* the constructor
|
||||||
*/
|
*/
|
||||||
UpdateRecentCases() {
|
UpdateRecentCases() {
|
||||||
// display last 5 cases.
|
// display last 5 cases.
|
||||||
length = RecentCases.LENGTH - 1;
|
NUM_CASES_TO_DISPLAY = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setHasRecentCase(boolean value) {
|
||||||
|
hasRecentCase = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,10 +58,10 @@ class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
|
|||||||
public JComponent[] getMenuPresenters() {
|
public JComponent[] getMenuPresenters() {
|
||||||
String[] caseName = RecentCases.getInstance().getRecentCaseNames();
|
String[] caseName = RecentCases.getInstance().getRecentCaseNames();
|
||||||
String[] casePath = RecentCases.getInstance().getRecentCasePaths();
|
String[] casePath = RecentCases.getInstance().getRecentCasePaths();
|
||||||
JComponent[] comps = new JComponent[length + 2]; // + 2 for separator and clear menu
|
JComponent[] comps = new JComponent[NUM_CASES_TO_DISPLAY + 2]; // + 2 for separator and clear menu
|
||||||
|
|
||||||
// if it has the recent menus, add them to the component list
|
// if it has the recent menus, add them to the component list
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < NUM_CASES_TO_DISPLAY; i++) {
|
||||||
if ((!caseName[i].equals(""))) {
|
if ((!caseName[i].equals(""))) {
|
||||||
JMenuItem menuItem = new JMenuItem(caseName[i]);
|
JMenuItem menuItem = new JMenuItem(caseName[i]);
|
||||||
menuItem.setActionCommand(caseName[i].toUpperCase());
|
menuItem.setActionCommand(caseName[i].toUpperCase());
|
||||||
@ -68,11 +73,11 @@ class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
|
|||||||
|
|
||||||
// if it has recent case, create clear menu
|
// if it has recent case, create clear menu
|
||||||
if (hasRecentCase) {
|
if (hasRecentCase) {
|
||||||
comps[length] = new JSeparator();
|
comps[NUM_CASES_TO_DISPLAY] = new JSeparator();
|
||||||
JMenuItem clearMenu = new JMenuItem(
|
JMenuItem clearMenu = new JMenuItem(
|
||||||
NbBundle.getMessage(UpdateRecentCases.class, "UpdateRecentCases.menuItem.clearRecentCases.text"));
|
NbBundle.getMessage(UpdateRecentCases.class, "UpdateRecentCases.menuItem.clearRecentCases.text"));
|
||||||
clearMenu.addActionListener(SystemAction.get(RecentCases.class));
|
clearMenu.addActionListener(SystemAction.get(RecentCases.class));
|
||||||
comps[length + 1] = clearMenu;
|
comps[NUM_CASES_TO_DISPLAY + 1] = clearMenu;
|
||||||
} // otherwise, just create a disabled empty menu
|
} // otherwise, just create a disabled empty menu
|
||||||
else {
|
else {
|
||||||
comps = new JComponent[1];
|
comps = new JComponent[1];
|
||||||
@ -85,17 +90,15 @@ class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates main menu presenters. This method is called only by the main menu
|
* Updates the Recent Cases menu items.
|
||||||
* processing.
|
|
||||||
*
|
*
|
||||||
* @param jcs the previously used menu items returned by previous call to
|
* @param menuItems A set of Recent Case menu items to be updated.
|
||||||
* getMenuPresenters() or synchMenuPresenters()
|
|
||||||
*
|
*
|
||||||
* @return menu a new set of items to show in menu. Can be either an updated
|
* @return A updated set of recent case menu items to show in the Recent
|
||||||
* old set of instances or a completely new one.
|
* Cases menu.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public JComponent[] synchMenuPresenters(JComponent[] jcs) {
|
public JComponent[] synchMenuPresenters(JComponent[] menuItems) {
|
||||||
return getMenuPresenters();
|
return getMenuPresenters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-2015 Basis Technology Corp.
|
* Copyright 2013-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -59,18 +59,33 @@ public class RuntimeProperties {
|
|||||||
* Private constructor to prevent creation of instances of this class.
|
* Private constructor to prevent creation of instances of this class.
|
||||||
*/
|
*/
|
||||||
private RuntimeProperties() {
|
private RuntimeProperties() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class RuntimePropertiesException extends Exception {
|
/**
|
||||||
|
* Exception to throw if there is an error setting a runtime property.
|
||||||
|
*/
|
||||||
|
public final static class RuntimePropertiesException extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private RuntimePropertiesException(String message) {
|
/**
|
||||||
|
* Constructor for an exception to throw if there is an error setting
|
||||||
|
* a runtime property.
|
||||||
|
*
|
||||||
|
* @param message The exception message.
|
||||||
|
*/
|
||||||
|
public RuntimePropertiesException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RuntimePropertiesException(String message, Throwable cause) {
|
/**
|
||||||
|
* Constructor for an exception to throw if there is an error setting
|
||||||
|
* a runtime property.
|
||||||
|
*
|
||||||
|
* @param message The exception message.
|
||||||
|
* @param cause The cause of the error.
|
||||||
|
*/
|
||||||
|
public RuntimePropertiesException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
public class Installer extends ModuleInstall {
|
public class Installer extends ModuleInstall {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger LOGGER = Logger.getLogger(Installer.class.getName());
|
private static final Logger logger = Logger.getLogger(Installer.class.getName());
|
||||||
private static Installer instance;
|
private static Installer instance;
|
||||||
|
|
||||||
public synchronized static Installer getDefault() {
|
public synchronized static Installer getDefault() {
|
||||||
@ -82,10 +82,9 @@ public class Installer extends ModuleInstall {
|
|||||||
final String caseFile = argsProcessor.getDefaultArg();
|
final String caseFile = argsProcessor.getDefaultArg();
|
||||||
if (caseFile != null && !caseFile.isEmpty() && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
|
if (caseFile != null && !caseFile.isEmpty() && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
|
||||||
try {
|
try {
|
||||||
Case.openCurrentCase(caseFile);
|
Case.openAsCurrentCase(caseFile);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
// RJCTODO: SHould there be a popup here?
|
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseFile), ex); //NON-NLS
|
||||||
LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseFile), ex); //NON-NLS
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -105,7 +104,7 @@ public class Installer extends ModuleInstall {
|
|||||||
try {
|
try {
|
||||||
Case.closeCurrentCase();
|
Case.closeCurrentCase();
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error closing current case", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Error closing current case", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ public class Installer extends ModuleInstall {
|
|||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Error setting OS-X look-and-feel", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error setting OS-X look-and-feel", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the keys that deal with menu items
|
// Store the keys that deal with menu items
|
||||||
@ -140,7 +139,7 @@ public class Installer extends ModuleInstall {
|
|||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(info.getClassName());
|
UIManager.setLookAndFeel(info.getClassName());
|
||||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Error setting OS-X look-and-feel", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error setting OS-X look-and-feel", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.framework;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface implemented by DataSourceProcessors in order to be supported by
|
* Interface implemented by DataSourceProcessors in order to be supported by
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.framework;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
|
@ -16,16 +16,15 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.framework;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.ProgressIndicator;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A progress indicator that writes progress to the Autopsy application log.
|
* A progress indicator that writes progress to the Autopsy application log.
|
||||||
*/
|
*/
|
||||||
class LoggingProgressIndicator implements ProgressIndicator {
|
public final class LoggingProgressIndicator implements ProgressIndicator {
|
||||||
|
|
||||||
private final Logger LOGGER = Logger.getLogger(LoggingProgressIndicator.class.getName());
|
private final Logger LOGGER = Logger.getLogger(LoggingProgressIndicator.class.getName());
|
||||||
private int totalWorkUnits;
|
private int totalWorkUnits;
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.framework;
|
||||||
|
|
||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
@ -24,7 +24,7 @@ import javax.swing.SwingUtilities;
|
|||||||
import org.openide.DialogDescriptor;
|
import org.openide.DialogDescriptor;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.ProgressIndicator;
|
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A progress indicator that displays progress using a modal dialog with a
|
* A progress indicator that displays progress using a modal dialog with a
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.framework;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for progress indicators. A progress indicator can run in
|
* An interface for progress indicators. A progress indicator can run in
|
@ -42,7 +42,7 @@
|
|||||||
<Component class="javax.swing.JLabel" name="progressMessage">
|
<Component class="javax.swing.JLabel" name="progressMessage">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="ProgressPanel.progressMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/framework/Bundle.properties" key="ProgressPanel.progressMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
@ -16,27 +16,20 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.framework;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RJCTODO
|
* A progress panel consisting of a message label and a progress bar.
|
||||||
*/
|
*/
|
||||||
class ProgressPanel extends javax.swing.JPanel {
|
class ProgressPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
ProgressPanel() {
|
ProgressPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
this.progressBar.setMinimum(0);
|
this.progressBar.setMinimum(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
void setMessage(String message) {
|
void setMessage(String message) {
|
||||||
this.progressMessage.setText(message);
|
this.progressMessage.setText(message);
|
||||||
}
|
}
|
@ -379,7 +379,7 @@ public class IngestManager {
|
|||||||
* Case.getTextIndexName() API.
|
* Case.getTextIndexName() API.
|
||||||
*/
|
*/
|
||||||
Case openedCase = Case.getCurrentCase();
|
Case openedCase = Case.getCurrentCase();
|
||||||
String channelPrefix = openedCase.getTextIndexName();
|
String channelPrefix = openedCase.getName();
|
||||||
if (Case.CaseType.MULTI_USER_CASE == openedCase.getCaseType()) {
|
if (Case.CaseType.MULTI_USER_CASE == openedCase.getCaseType()) {
|
||||||
jobEventPublisher.openRemoteEventChannel(String.format(JOB_EVENT_CHANNEL_NAME, channelPrefix));
|
jobEventPublisher.openRemoteEventChannel(String.format(JOB_EVENT_CHANNEL_NAME, channelPrefix));
|
||||||
moduleEventPublisher.openRemoteEventChannel(String.format(MODULE_EVENT_CHANNEL_NAME, channelPrefix));
|
moduleEventPublisher.openRemoteEventChannel(String.format(MODULE_EVENT_CHANNEL_NAME, channelPrefix));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2011-2017 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,36 +19,42 @@
|
|||||||
package org.sleuthkit.autopsy.keywordsearchservice;
|
package org.sleuthkit.autopsy.keywordsearchservice;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of a keyword search service.
|
* An interface for implementations of a keyword search service.
|
||||||
*
|
*
|
||||||
* TODO (AUT-2158: This interface should not extend Closeable.
|
* TODO (AUT-2158: This interface should not extend Closeable.
|
||||||
*/
|
*/
|
||||||
public interface KeywordSearchService extends Closeable {
|
public interface KeywordSearchService extends Closeable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a Blackboard artifact and adds all of its attributes to the keyword
|
* Tries to connect to the keyword search service server.
|
||||||
* search index.
|
|
||||||
*
|
*
|
||||||
* @param artifact
|
* @param host The hostname or IP address of the service.
|
||||||
|
* @param port The port used by the service.
|
||||||
|
*
|
||||||
|
* @throws KeywordSearchServiceException if cannot connect.
|
||||||
|
*/
|
||||||
|
public void tryConnect(String host, int port) throws KeywordSearchServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an artifact to the keyword search text index as a concantenation of
|
||||||
|
* all of its attributes.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact to index.
|
||||||
*
|
*
|
||||||
* @throws org.sleuthkit.datamodel.TskCoreException
|
* @throws org.sleuthkit.datamodel.TskCoreException
|
||||||
*/
|
*/
|
||||||
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException;
|
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if we can communicate with the KeywordSearchService using the
|
* Deletes the keyword search text index for a case.
|
||||||
* passed-in host and port. Closes the connection upon exit. Throws if it
|
|
||||||
* cannot communicate.
|
|
||||||
*
|
*
|
||||||
* @param host the remote hostname or IP address of the server
|
* @param textIndexName The text index name.
|
||||||
* @param port the remote port of the server
|
|
||||||
*
|
|
||||||
* @throws KeywordSearchServiceException
|
|
||||||
*/
|
*/
|
||||||
public void tryConnect(String host, int port) throws KeywordSearchServiceException;
|
public void deleteTextIndex(String textIndexName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.hashdatabase;
|
package org.sleuthkit.autopsy.modules.hashdatabase;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.ProgressIndicator;
|
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "silent" or "null" progress indicator.
|
* A "silent" or "null" progress indicator.
|
||||||
|
@ -301,7 +301,7 @@ class ReportExcel implements TableReportModule {
|
|||||||
row = sheet.createRow(rowIndex);
|
row = sheet.createRow(rowIndex);
|
||||||
row.setRowStyle(setStyle);
|
row.setRowStyle(setStyle);
|
||||||
row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseName"));
|
row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseName"));
|
||||||
row.createCell(1).setCellValue(currentCase.getName());
|
row.createCell(1).setCellValue(currentCase.getDisplayName());
|
||||||
++rowIndex;
|
++rowIndex;
|
||||||
|
|
||||||
row = sheet.createRow(rowIndex);
|
row = sheet.createRow(rowIndex);
|
||||||
|
@ -93,7 +93,7 @@ class ReportGenerator {
|
|||||||
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
||||||
Date date = new Date();
|
Date date = new Date();
|
||||||
String dateNoTime = dateFormat.format(date);
|
String dateNoTime = dateFormat.format(date);
|
||||||
this.reportPath = currentCase.getReportDirectory() + File.separator + currentCase.getName() + " " + dateNoTime + File.separator;
|
this.reportPath = currentCase.getReportDirectory() + File.separator + currentCase.getDisplayName() + " " + dateNoTime + File.separator;
|
||||||
|
|
||||||
this.errorList = new ArrayList<>();
|
this.errorList = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -857,7 +857,7 @@ class ReportHTML implements TableReportModule {
|
|||||||
iconPath = "favicon.ico";
|
iconPath = "favicon.ico";
|
||||||
}
|
}
|
||||||
index.append("<head>\n<title>").append(reportTitle).append(" ").append(
|
index.append("<head>\n<title>").append(reportTitle).append(" ").append(
|
||||||
NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.title", currentCase.getName())).append(
|
NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.title", currentCase.getDisplayName())).append(
|
||||||
"</title>\n"); //NON-NLS
|
"</title>\n"); //NON-NLS
|
||||||
index.append("<link rel=\"icon\" type=\"image/ico\" href=\"")
|
index.append("<link rel=\"icon\" type=\"image/ico\" href=\"")
|
||||||
.append(iconPath).append("\" />\n"); //NON-NLS
|
.append(iconPath).append("\" />\n"); //NON-NLS
|
||||||
@ -1017,7 +1017,7 @@ class ReportHTML implements TableReportModule {
|
|||||||
Date date = new Date();
|
Date date = new Date();
|
||||||
String datetime = datetimeFormat.format(date);
|
String datetime = datetimeFormat.format(date);
|
||||||
|
|
||||||
String caseName = currentCase.getName();
|
String caseName = currentCase.getDisplayName();
|
||||||
String caseNumber = currentCase.getNumber();
|
String caseNumber = currentCase.getNumber();
|
||||||
String examiner = currentCase.getExaminer();
|
String examiner = currentCase.getExaminer();
|
||||||
int imagecount;
|
int imagecount;
|
||||||
|
@ -90,7 +90,7 @@ public class AddTaggedHashesToHashDb implements GeneralReportModule {
|
|||||||
if (content instanceof AbstractFile) {
|
if (content instanceof AbstractFile) {
|
||||||
if (null != ((AbstractFile) content).getMd5Hash()) {
|
if (null != ((AbstractFile) content).getMd5Hash()) {
|
||||||
try {
|
try {
|
||||||
hashSet.addHashes(tag.getContent(), Case.getCurrentCase().getName());
|
hashSet.addHashes(tag.getContent(), Case.getCurrentCase().getDisplayName());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(AddTaggedHashesToHashDb.class.getName()).log(Level.SEVERE, "Error adding hash for obj_id = " + tag.getContent().getId() + " to hash database " + hashSet.getHashSetName(), ex);
|
Logger.getLogger(AddTaggedHashesToHashDb.class.getName()).log(Level.SEVERE, "Error adding hash for obj_id = " + tag.getContent().getId() + " to hash database " + hashSet.getHashSetName(), ex);
|
||||||
failedExports.add(tag.getContent().getName());
|
failedExports.add(tag.getContent().getName());
|
||||||
|
@ -20,14 +20,14 @@ package org.sleuthkit.autopsy.test;
|
|||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutopsyService;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.ProgressIndicator;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.framework.AutopsyService;
|
||||||
|
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of the Autopsy service interface used for test purposes.
|
* An implementation of the Autopsy service interface used for test purposes.
|
||||||
*/
|
*/
|
||||||
@ServiceProvider(service = AutopsyService.class)
|
//@ServiceProvider(service = AutopsyService.class)
|
||||||
public class TestAutopsyService implements AutopsyService {
|
public class TestAutopsyService implements AutopsyService {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(TestAutopsyService.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(TestAutopsyService.class.getName());
|
||||||
|
@ -100,7 +100,7 @@ public class SaveSnapshotAsReport extends Action {
|
|||||||
setEventHandler(actionEvent -> {
|
setEventHandler(actionEvent -> {
|
||||||
//capture generation date and use to make default report name
|
//capture generation date and use to make default report name
|
||||||
Date generationDate = new Date();
|
Date generationDate = new Date();
|
||||||
final String defaultReportName = FileUtil.escapeFileName(currentCase.getName() + " " + new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss").format(generationDate)); //NON_NLS
|
final String defaultReportName = FileUtil.escapeFileName(currentCase.getDisplayName() + " " + new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss").format(generationDate)); //NON_NLS
|
||||||
BufferedImage snapshot = SwingFXUtils.fromFXImage(nodeSupplier.get().snapshot(null, null), null);
|
BufferedImage snapshot = SwingFXUtils.fromFXImage(nodeSupplier.get().snapshot(null, null), null);
|
||||||
|
|
||||||
//prompt user to pick report name
|
//prompt user to pick report name
|
||||||
|
@ -46,7 +46,6 @@ class AutoIngestCase implements Comparable<AutoIngestCase> {
|
|||||||
*
|
*
|
||||||
* @param caseDirectoryPath The case directory path.
|
* @param caseDirectoryPath The case directory path.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Throw instead of reporting error, let client decide what to do.
|
|
||||||
AutoIngestCase(Path caseDirectoryPath) {
|
AutoIngestCase(Path caseDirectoryPath) {
|
||||||
this.caseDirectoryPath = caseDirectoryPath;
|
this.caseDirectoryPath = caseDirectoryPath;
|
||||||
caseName = PathUtils.caseNameFromCaseDirectoryPath(caseDirectoryPath);
|
caseName = PathUtils.caseNameFromCaseDirectoryPath(caseDirectoryPath);
|
||||||
@ -100,7 +99,6 @@ class AutoIngestCase implements Comparable<AutoIngestCase> {
|
|||||||
*
|
*
|
||||||
* @return The last accessed date.
|
* @return The last accessed date.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Throw instead of reporting error, let client decide what to do.
|
|
||||||
Date getLastAccessedDate() {
|
Date getLastAccessedDate() {
|
||||||
try {
|
try {
|
||||||
BasicFileAttributes fileAttrs = Files.readAttributes(metadataFilePath, BasicFileAttributes.class);
|
BasicFileAttributes fileAttrs = Files.readAttributes(metadataFilePath, BasicFileAttributes.class);
|
||||||
|
@ -45,20 +45,10 @@ final class AutoIngestCaseDeletedEvent extends AutopsyEvent implements Serializa
|
|||||||
this.nodeName = nodeName;
|
this.nodeName = nodeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
String getCaseName() {
|
String getCaseName() {
|
||||||
return caseName;
|
return caseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
String getNodeName() {
|
String getNodeName() {
|
||||||
return nodeName;
|
return nodeName;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,6 @@ final class AutoIngestCaseManager {
|
|||||||
* this machine, but review mode is only for looking at cases created by
|
* this machine, but review mode is only for looking at cases created by
|
||||||
* automated ingest.
|
* automated ingest.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Write a story about this.
|
|
||||||
FileObject root = FileUtil.getConfigRoot();
|
FileObject root = FileUtil.getConfigRoot();
|
||||||
FileObject openRecentCasesMenu = root.getFileObject("Menu/Case/OpenRecentCase");
|
FileObject openRecentCasesMenu = root.getFileObject("Menu/Case/OpenRecentCase");
|
||||||
if (openRecentCasesMenu != null) {
|
if (openRecentCasesMenu != null) {
|
||||||
@ -108,7 +107,7 @@ final class AutoIngestCaseManager {
|
|||||||
/*
|
/*
|
||||||
* Open the case.
|
* Open the case.
|
||||||
*/
|
*/
|
||||||
Case.openCurrentCase(caseMetadataFilePath.toString());
|
Case.openAsCurrentCase(caseMetadataFilePath.toString());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the add data source action in auto ingest examiner mode. This
|
* Disable the add data source action in auto ingest examiner mode. This
|
||||||
@ -117,7 +116,6 @@ final class AutoIngestCaseManager {
|
|||||||
* enables the menus on EDT by calling SwingUtilities.invokeLater(), we
|
* enables the menus on EDT by calling SwingUtilities.invokeLater(), we
|
||||||
* have to do the same thing here to maintain the order of execution.
|
* have to do the same thing here to maintain the order of execution.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Write a story about this.
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
|
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.events.AutopsyEvent;
|
|||||||
* Event published when an automated ingest manager prioritizes all or part of a
|
* Event published when an automated ingest manager prioritizes all or part of a
|
||||||
* case.
|
* case.
|
||||||
*/
|
*/
|
||||||
public final class AutoIngestCasePrioritizedEvent extends AutopsyEvent implements Serializable { // RJCTODO: Rename to AutoIngestPrioritizationEvent
|
public final class AutoIngestCasePrioritizedEvent extends AutopsyEvent implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final String caseName;
|
private final String caseName;
|
||||||
|
@ -24,6 +24,7 @@ import java.nio.file.Paths;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
@ -55,9 +56,9 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
transient private IngestJob ingestJob;
|
transient private IngestJob ingestJob;
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
transient private boolean cancelled; // RJCTODO: Document
|
transient private boolean cancelled;
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
transient private boolean completed; // RJCTODO: Document
|
transient private boolean completed;
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private Date completedDate;
|
private Date completedDate;
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
@ -81,7 +82,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
* indicate the the job is not completed, i.e., new
|
* indicate the the job is not completed, i.e., new
|
||||||
* Date(0L).
|
* Date(0L).
|
||||||
*/
|
*/
|
||||||
// RJCTODO: The null case directory is error-prone and the nodeName is confusing.
|
|
||||||
AutoIngestJob(Manifest manifest, Path caseDirectoryPath, int priority, String nodeName, Stage stage, Date completedDate, boolean errorsOccurred) {
|
AutoIngestJob(Manifest manifest, Path caseDirectoryPath, int priority, String nodeName, Stage stage, Date completedDate, boolean errorsOccurred) {
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
if (null != caseDirectoryPath) {
|
if (null != caseDirectoryPath) {
|
||||||
@ -112,7 +112,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
*
|
*
|
||||||
* @return True or false
|
* @return True or false
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Use this or lose this
|
|
||||||
synchronized boolean hasCaseDirectoryPath() {
|
synchronized boolean hasCaseDirectoryPath() {
|
||||||
return (false == this.caseDirectoryPath.isEmpty());
|
return (false == this.caseDirectoryPath.isEmpty());
|
||||||
}
|
}
|
||||||
@ -161,21 +160,10 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
return this.priority;
|
return this.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param newStage
|
|
||||||
*/
|
|
||||||
synchronized void setStage(Stage newStage) {
|
synchronized void setStage(Stage newStage) {
|
||||||
setStage(newStage, Date.from(Instant.now()));
|
setStage(newStage, Date.from(Instant.now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param state
|
|
||||||
* @param stateStartedDate
|
|
||||||
*/
|
|
||||||
synchronized void setStage(Stage newState, Date stateStartedDate) {
|
synchronized void setStage(Stage newState, Date stateStartedDate) {
|
||||||
if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newState) {
|
if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newState) {
|
||||||
return;
|
return;
|
||||||
@ -184,29 +172,14 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
this.stageStartDate = stateStartedDate;
|
this.stageStartDate = stateStartedDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO:
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
synchronized Stage getStage() {
|
synchronized Stage getStage() {
|
||||||
return this.stage;
|
return this.stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
synchronized Date getStageStartDate() {
|
synchronized Date getStageStartDate() {
|
||||||
return this.stageStartDate;
|
return this.stageStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
synchronized StageDetails getStageDetails() {
|
synchronized StageDetails getStageDetails() {
|
||||||
String description;
|
String description;
|
||||||
Date startDate;
|
Date startDate;
|
||||||
@ -223,7 +196,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
if (!ingestModuleHandle.isCancelled()) {
|
if (!ingestModuleHandle.isCancelled()) {
|
||||||
description = ingestModuleHandle.displayName();
|
description = ingestModuleHandle.displayName();
|
||||||
} else {
|
} else {
|
||||||
description = String.format(Stage.CANCELLING_MODULE.getDisplayText(), ingestModuleHandle.displayName()); // RJCTODO: FIx this
|
description = String.format(Stage.CANCELLING_MODULE.getDisplayText(), ingestModuleHandle.displayName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
@ -248,26 +221,14 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
this.dataSourceProcessor = dataSourceProcessor;
|
this.dataSourceProcessor = dataSourceProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
// RJCTODO: Consider moving this class into AIM and making this private
|
|
||||||
synchronized void setIngestJob(IngestJob ingestJob) {
|
synchronized void setIngestJob(IngestJob ingestJob) {
|
||||||
this.ingestJob = ingestJob;
|
this.ingestJob = ingestJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
// RJCTODO: Consider moving this class into AIM and making this private.
|
|
||||||
// Or move the AID into a separate package. Or do not worry about it.
|
|
||||||
synchronized IngestJob getIngestJob() {
|
synchronized IngestJob getIngestJob() {
|
||||||
return this.ingestJob;
|
return this.ingestJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
synchronized void cancel() {
|
synchronized void cancel() {
|
||||||
setStage(Stage.CANCELLING);
|
setStage(Stage.CANCELLING);
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
@ -280,26 +241,15 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
synchronized boolean isCancelled() {
|
synchronized boolean isCancelled() {
|
||||||
return cancelled;
|
return cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
synchronized void setCompleted() {
|
synchronized void setCompleted() {
|
||||||
setStage(Stage.COMPLETED);
|
setStage(Stage.COMPLETED);
|
||||||
completed = true;
|
completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
synchronized boolean isCompleted() {
|
synchronized boolean isCompleted() {
|
||||||
return completed;
|
return completed;
|
||||||
}
|
}
|
||||||
@ -321,7 +271,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
* @return True or false.
|
* @return True or false.
|
||||||
*/
|
*/
|
||||||
synchronized Date getCompletedDate() {
|
synchronized Date getCompletedDate() {
|
||||||
return completedDate; // RJCTODO: Consider returning null if == 0 (epoch)
|
return completedDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -342,23 +292,10 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
return this.errorsOccurred;
|
return this.errorsOccurred;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO Gets name of the node associated with the job, possibly a remote
|
|
||||||
* hose if the job is in progress.
|
|
||||||
*
|
|
||||||
* @return The node name.
|
|
||||||
*/
|
|
||||||
String getNodeName() {
|
String getNodeName() {
|
||||||
return nodeName;
|
return nodeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param obj
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof AutoIngestJob)) {
|
if (!(obj instanceof AutoIngestJob)) {
|
||||||
@ -370,26 +307,12 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
return this.getManifest().getFilePath().equals(((AutoIngestJob) obj).getManifest().getFilePath());
|
return this.getManifest().getFilePath().equals(((AutoIngestJob) obj).getManifest().getFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
// RJCTODO: Update this
|
int hash = 71 * (Objects.hashCode(this.caseDirectoryPath));
|
||||||
int hash = 7;
|
|
||||||
// hash = 71 * hash + Objects.hashCode(this.dateCreated);
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO Default sorting is by ready file creation date, descending
|
|
||||||
*
|
|
||||||
* @param o
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(AutoIngestJob o) {
|
public int compareTo(AutoIngestJob o) {
|
||||||
return -this.getManifest().getDateFileCreated().compareTo(o.getManifest().getDateFileCreated());
|
return -this.getManifest().getDateFileCreated().compareTo(o.getManifest().getDateFileCreated());
|
||||||
@ -401,14 +324,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
*/
|
*/
|
||||||
static class ReverseDateCompletedComparator implements Comparator<AutoIngestJob> {
|
static class ReverseDateCompletedComparator implements Comparator<AutoIngestJob> {
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param o1
|
|
||||||
* @param o2
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
|
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
|
||||||
return -o1.getStageStartDate().compareTo(o2.getStageStartDate());
|
return -o1.getStageStartDate().compareTo(o2.getStageStartDate());
|
||||||
@ -420,14 +335,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
*/
|
*/
|
||||||
public static class PriorityComparator implements Comparator<AutoIngestJob> {
|
public static class PriorityComparator implements Comparator<AutoIngestJob> {
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param job
|
|
||||||
* @param anotherJob
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(AutoIngestJob job, AutoIngestJob anotherJob) {
|
public int compare(AutoIngestJob job, AutoIngestJob anotherJob) {
|
||||||
return -(job.getPriority().compareTo(anotherJob.getPriority()));
|
return -(job.getPriority().compareTo(anotherJob.getPriority()));
|
||||||
@ -442,14 +349,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
*/
|
*/
|
||||||
static class AlphabeticalComparator implements Comparator<AutoIngestJob> {
|
static class AlphabeticalComparator implements Comparator<AutoIngestJob> {
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param o1
|
|
||||||
* @param o2
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
|
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
|
||||||
if (o1.getNodeName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
|
if (o1.getNodeName().equalsIgnoreCase(LOCAL_HOST_NAME)) {
|
||||||
@ -462,10 +361,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
// RJCTODO: Combine this enum with StageDetails to make a single class.
|
|
||||||
enum Stage {
|
enum Stage {
|
||||||
|
|
||||||
PENDING("Pending"),
|
PENDING("Pending"),
|
||||||
@ -494,40 +389,21 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
@Immutable
|
@Immutable
|
||||||
static final class StageDetails {
|
static final class StageDetails {
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
private final Date startDate;
|
private final Date startDate;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param description
|
|
||||||
* @param startDate
|
|
||||||
*/
|
|
||||||
private StageDetails(String description, Date startDate) {
|
private StageDetails(String description, Date startDate) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.startDate = startDate;
|
this.startDate = startDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
String getDescription() {
|
String getDescription() {
|
||||||
return this.description;
|
return this.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
Date getStartDate() {
|
Date getStartDate() {
|
||||||
return this.startDate;
|
return this.startDate;
|
||||||
}
|
}
|
||||||
|
@ -22,28 +22,17 @@ import java.io.Serializable;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
@Immutable
|
@Immutable
|
||||||
abstract class AutoIngestJobEvent extends AutopsyEvent implements Serializable {
|
abstract class AutoIngestJobEvent extends AutopsyEvent implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final AutoIngestJob job;
|
private final AutoIngestJob job;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
AutoIngestJobEvent(AutoIngestManager.Event eventSubType, AutoIngestJob job) {
|
AutoIngestJobEvent(AutoIngestManager.Event eventSubType, AutoIngestJob job) {
|
||||||
super(eventSubType.toString(), null, null);
|
super(eventSubType.toString(), null, null);
|
||||||
this.job = job;
|
this.job = job;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
AutoIngestJob getJob() {
|
AutoIngestJob getJob() {
|
||||||
return this.job;
|
return this.job;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ final class AutoIngestJobLogger {
|
|||||||
* to acquire an exclusive lock on the
|
* to acquire an exclusive lock on the
|
||||||
* log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceProcessorCancelled() throws AutoIngestJobLoggerException, InterruptedException { // RJCTODO: Is this used now?
|
void logDataSourceProcessorCancelled() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, "Cancelled adding data source to case");
|
log(MessageCategory.WARNING, "Cancelled adding data source to case");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +28,6 @@ public final class AutoIngestJobStartedEvent extends AutoIngestJobEvent implemen
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
public AutoIngestJobStartedEvent(AutoIngestJob job) {
|
public AutoIngestJobStartedEvent(AutoIngestJob job) {
|
||||||
super(AutoIngestManager.Event.JOB_STARTED, job);
|
super(AutoIngestManager.Event.JOB_STARTED, job);
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,6 @@ public final class AutoIngestJobStatusEvent extends AutoIngestJobEvent implement
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
public AutoIngestJobStatusEvent(AutoIngestJob job) {
|
public AutoIngestJobStatusEvent(AutoIngestJob job) {
|
||||||
super(AutoIngestManager.Event.JOB_STATUS_UPDATED, job);
|
super(AutoIngestManager.Event.JOB_STATUS_UPDATED, job);
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
|
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
|
||||||
@ -38,9 +36,6 @@ import java.sql.Connection;
|
|||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import org.sleuthkit.autopsy.modules.vmextractor.VirtualMachineFinder;
|
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
|
||||||
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -54,13 +49,13 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -69,65 +64,50 @@ import java.util.stream.Collectors;
|
|||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.swing.filechooser.FileFilter;
|
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import org.openide.util.Lookup;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.xpath.XPath;
|
|
||||||
import javax.xml.xpath.XPathConstants;
|
|
||||||
import javax.xml.xpath.XPathExpression;
|
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
|
||||||
import javax.xml.xpath.XPathFactory;
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
|
||||||
import org.openide.modules.InstalledFileLocator;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||||
import org.sleuthkit.autopsy.casemodule.GeneralFilter;
|
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||||
import org.sleuthkit.autopsy.casemodule.ImageDSProcessor;
|
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
|
||||||
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
|
||||||
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
||||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.openide.util.Lookup;
|
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
||||||
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.LocalFilesDSProcessor;
|
|
||||||
import org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException;
|
import org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException;
|
||||||
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
|
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
||||||
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
||||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
|
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestAlertFile.AutoIngestAlertFileException;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleError;
|
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJobLogger.AutoIngestJobLoggerException;
|
||||||
import org.sleuthkit.autopsy.experimental.autoingest.FileExporter.FileExportException;
|
import org.sleuthkit.autopsy.experimental.autoingest.FileExporter.FileExportException;
|
||||||
import org.sleuthkit.autopsy.experimental.autoingest.ManifestFileParser.ManifestFileParserException;
|
import org.sleuthkit.autopsy.experimental.autoingest.ManifestFileParser.ManifestFileParserException;
|
||||||
import org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus;
|
import org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus;
|
||||||
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.PENDING;
|
|
||||||
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.PROCESSING;
|
|
||||||
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.COMPLETED;
|
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.COMPLETED;
|
||||||
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.DELETED;
|
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.DELETED;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
|
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.PENDING;
|
||||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.PROCESSING;
|
||||||
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestAlertFile.AutoIngestAlertFileException;
|
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
||||||
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJobLogger.AutoIngestJobLoggerException;
|
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
|
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutoIngestDataSourceProcessor;
|
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleError;
|
||||||
|
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An auto ingest manager is responsible for processing auto ingest jobs defined
|
* An auto ingest manager is responsible for processing auto ingest jobs defined
|
||||||
@ -240,7 +220,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
eventPublisher.openRemoteEventChannel(EVENT_CHANNEL_NAME);
|
eventPublisher.openRemoteEventChannel(EVENT_CHANNEL_NAME);
|
||||||
SYS_LOGGER.log(Level.INFO, "Opened auto ingest event channel");
|
SYS_LOGGER.log(Level.INFO, "Opened auto ingest event channel");
|
||||||
} catch (AutopsyEventException ex) {
|
} catch (AutopsyEventException ex) {
|
||||||
throw new AutoIngestManagerStartupException("Failed to open aut ingest event channel", ex);
|
SYS_LOGGER.log(Level.SEVERE, "Failed to open auto ingest event channel", ex);
|
||||||
|
throw new AutoIngestManagerStartupException("Failed to open auto ingest event channel", ex);
|
||||||
}
|
}
|
||||||
rootInputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeImageFolder());
|
rootInputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeImageFolder());
|
||||||
rootOutputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeResultsFolder());
|
rootOutputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeResultsFolder());
|
||||||
@ -249,7 +230,13 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
jobProcessingTaskFuture = jobProcessingExecutor.submit(jobProcessingTask);
|
jobProcessingTaskFuture = jobProcessingExecutor.submit(jobProcessingTask);
|
||||||
jobStatusPublishingExecutor.scheduleAtFixedRate(new PeriodicJobStatusEventTask(), JOB_STATUS_EVENT_INTERVAL_SECONDS, JOB_STATUS_EVENT_INTERVAL_SECONDS, TimeUnit.SECONDS);
|
jobStatusPublishingExecutor.scheduleAtFixedRate(new PeriodicJobStatusEventTask(), JOB_STATUS_EVENT_INTERVAL_SECONDS, JOB_STATUS_EVENT_INTERVAL_SECONDS, TimeUnit.SECONDS);
|
||||||
eventPublisher.addSubscriber(EVENT_LIST, instance);
|
eventPublisher.addSubscriber(EVENT_LIST, instance);
|
||||||
|
try {
|
||||||
RuntimeProperties.setRunningWithGUI(false);
|
RuntimeProperties.setRunningWithGUI(false);
|
||||||
|
SYS_LOGGER.log(Level.INFO, "Set running with desktop GUI runtime property to false");
|
||||||
|
} catch (RuntimeProperties.RuntimePropertiesException ex) {
|
||||||
|
SYS_LOGGER.log(Level.SEVERE, "Failed to set running with desktop GUI runtime property to false", ex);
|
||||||
|
throw new AutoIngestManagerStartupException("Failed to set running with desktop GUI runtime property to false", ex);
|
||||||
|
}
|
||||||
state = State.RUNNING;
|
state = State.RUNNING;
|
||||||
errorState = ErrorState.NONE;
|
errorState = ErrorState.NONE;
|
||||||
}
|
}
|
||||||
@ -483,7 +470,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
}
|
}
|
||||||
for (AutoIngestJob job : hostNamesToRunningJobs.values()) {
|
for (AutoIngestJob job : hostNamesToRunningJobs.values()) {
|
||||||
runningJobs.add(job);
|
runningJobs.add(job);
|
||||||
runningJobs.sort(new AutoIngestJob.AlphabeticalComparator()); // RJCTODO: This sort should be done in the AID
|
runningJobs.sort(new AutoIngestJob.AlphabeticalComparator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (null != completedJobs) {
|
if (null != completedJobs) {
|
||||||
@ -684,18 +671,22 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Acquire an exclusive lock on the case so it can be safely deleted.
|
|
||||||
* This will fail if the case is open for review or a deletion operation
|
|
||||||
* on this case is already in progress on another node.
|
|
||||||
*/
|
|
||||||
CaseDeletionResult result = CaseDeletionResult.FULLY_DELETED;
|
CaseDeletionResult result = CaseDeletionResult.FULLY_DELETED;
|
||||||
List<Lock> manifestFileLocks = new ArrayList<>();
|
List<Lock> manifestFileLocks = new ArrayList<>();
|
||||||
try (Lock caseLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())) {
|
try {
|
||||||
if (null == caseLock) {
|
synchronized (jobsLock) {
|
||||||
|
/*
|
||||||
|
* Get the case metadata.
|
||||||
|
*/
|
||||||
|
CaseMetadata metaData;
|
||||||
|
Path caseMetaDataFilePath = Paths.get(caseDirectoryPath.toString(), caseName + CaseMetadata.getFileExtension());
|
||||||
|
try {
|
||||||
|
metaData = new CaseMetadata(caseMetaDataFilePath);
|
||||||
|
} catch (CaseMetadata.CaseMetadataException ex) {
|
||||||
|
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to get case metadata file %s for case %s at %s", caseMetaDataFilePath, caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
synchronized (jobsLock) {
|
|
||||||
/*
|
/*
|
||||||
* Do a fresh input directory scan.
|
* Do a fresh input directory scan.
|
||||||
*/
|
*/
|
||||||
@ -703,12 +694,14 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
scanner.scan();
|
scanner.scan();
|
||||||
Set<Path> manifestPaths = casesToManifests.get(caseName);
|
Set<Path> manifestPaths = casesToManifests.get(caseName);
|
||||||
if (null == manifestPaths) {
|
if (null == manifestPaths) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, "No manifest paths found for case {0}", caseName);
|
SYS_LOGGER.log(Level.SEVERE, String.format("No manifest paths found for case %s at %s", caseName, caseDirectoryPath));
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get all of the required manifest locks.
|
* Get exclusive locks on all of the manifests for the case.
|
||||||
|
* This will exclude other auot ingest nodes from doing anything
|
||||||
|
* with the case.
|
||||||
*/
|
*/
|
||||||
for (Path manifestPath : manifestPaths) {
|
for (Path manifestPath : manifestPaths) {
|
||||||
try {
|
try {
|
||||||
@ -719,20 +712,18 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to acquire manifest lock for %s for case %s", manifestPath, caseName), ex);
|
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to acquire manifest lock for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the case metadata.
|
|
||||||
*/
|
|
||||||
CaseMetadata metaData;
|
|
||||||
Path caseMetaDataFilePath = Paths.get(caseDirectoryPath.toString(), caseName + CaseMetadata.getFileExtension());
|
|
||||||
try {
|
try {
|
||||||
metaData = new CaseMetadata(caseMetaDataFilePath);
|
/*
|
||||||
} catch (CaseMetadata.CaseMetadataException ex) {
|
* Physically delete the case.
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to delete case metadata file %s for case %s", caseMetaDataFilePath, caseName));
|
*/
|
||||||
|
Case.deleteCase(metaData);
|
||||||
|
} catch (CaseActionException ex) {
|
||||||
|
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to physically delete case %s at %s", caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.FAILED;
|
return CaseDeletionResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,56 +736,11 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
nodeData.setStatus(ManifestNodeData.ProcessingStatus.DELETED);
|
nodeData.setStatus(ManifestNodeData.ProcessingStatus.DELETED);
|
||||||
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString(), nodeData.toArray());
|
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString(), nodeData.toArray());
|
||||||
} catch (InterruptedException | CoordinationServiceException ex) {
|
} catch (InterruptedException | CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set delete flag on manifest data for %s for case %s", manifestPath, caseName), ex);
|
SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set delete flag on manifest data for %s for case %s at %s", manifestPath, caseName, caseDirectoryPath), ex);
|
||||||
return CaseDeletionResult.PARTIALLY_DELETED;
|
return CaseDeletionResult.PARTIALLY_DELETED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to unload/delete the Solr core from the Solr server. Do
|
|
||||||
* this before deleting the case directory because the index
|
|
||||||
* files are in the case directory and the deletion will fail if
|
|
||||||
* the core is not unloaded first.
|
|
||||||
*/
|
|
||||||
String textIndexName = metaData.getTextIndexName();
|
|
||||||
try {
|
|
||||||
unloadSolrCore(metaData.getTextIndexName());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
/*
|
|
||||||
* Could be a problem, or it could be that the core was
|
|
||||||
* already unloaded (e.g., by the server due to resource
|
|
||||||
* constraints).
|
|
||||||
*/
|
|
||||||
SYS_LOGGER.log(Level.WARNING, String.format("Error deleting text index %s for %s", textIndexName, caseName), ex); //NON-NLS
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete the case database from the database server.
|
|
||||||
*/
|
|
||||||
String caseDatabaseName = metaData.getCaseDatabaseName();
|
|
||||||
try {
|
|
||||||
deleteCaseDatabase(caseDatabaseName);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Unable to delete case database %s for %s", caseDatabaseName, caseName), ex); //NON-NLS
|
|
||||||
result = CaseDeletionResult.PARTIALLY_DELETED;
|
|
||||||
} catch (UserPreferencesException ex) {
|
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error accessing case database connection info, unable to delete case database %s for %s", caseDatabaseName, caseName), ex); //NON-NLS
|
|
||||||
result = CaseDeletionResult.PARTIALLY_DELETED;
|
|
||||||
} catch (ClassNotFoundException ex) {
|
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Cannot load database driver, unable to delete case database %s for %s", caseDatabaseName, caseName), ex); //NON-NLS
|
|
||||||
result = CaseDeletionResult.PARTIALLY_DELETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete the case directory.
|
|
||||||
*/
|
|
||||||
File caseDirectory = caseDirectoryPath.toFile();
|
|
||||||
FileUtil.deleteDir(caseDirectory);
|
|
||||||
if (caseDirectory.exists()) {
|
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to delete case directory %s for case %s", caseDirectoryPath, caseName));
|
|
||||||
return CaseDeletionResult.PARTIALLY_DELETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove the jobs for the case from the pending jobs queue and
|
* Remove the jobs for the case from the pending jobs queue and
|
||||||
* completed jobs list.
|
* completed jobs list.
|
||||||
@ -809,16 +755,15 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
notifyObservers(Event.CASE_DELETED);
|
notifyObservers(Event.CASE_DELETED);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
} catch (CoordinationServiceException ex) {
|
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Error acquiring coordination service lock on case %s", caseName), ex);
|
|
||||||
return CaseDeletionResult.FAILED;
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
/*
|
||||||
|
* Always release the manifest locks, regardless of the outcome.
|
||||||
|
*/
|
||||||
for (Lock lock : manifestFileLocks) {
|
for (Lock lock : manifestFileLocks) {
|
||||||
try {
|
try {
|
||||||
lock.release();
|
lock.release();
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to release manifest file lock when deleting case %s", caseName), ex);
|
SYS_LOGGER.log(Level.SEVERE, String.format("Failed to release manifest file lock when deleting case %s at %s", caseName, caseDirectoryPath), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,6 +771,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current snapshot of the job lists.
|
* Get the current snapshot of the job lists.
|
||||||
|
*
|
||||||
* @return Snapshot of jobs lists
|
* @return Snapshot of jobs lists
|
||||||
*/
|
*/
|
||||||
JobsSnapshot getCurrentJobsSnapshot() {
|
JobsSnapshot getCurrentJobsSnapshot() {
|
||||||
@ -895,9 +841,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* Starts the process of cancelling the current job.
|
* Starts the process of cancelling the current job.
|
||||||
*
|
*
|
||||||
* Note that the current job is included in the running list for a while
|
* Note that the current job is included in the running list for a while
|
||||||
* because it can take some time
|
* because it can take some time for the automated ingest process for the
|
||||||
* for the automated ingest process for the job to be shut down in
|
* job to be shut down in an orderly fashion.
|
||||||
* an orderly fashion.
|
|
||||||
*/
|
*/
|
||||||
void cancelCurrentJob() {
|
void cancelCurrentJob() {
|
||||||
if (State.RUNNING != state) {
|
if (State.RUNNING != state) {
|
||||||
@ -1655,8 +1600,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* @throws CoordinationServiceException if there is an error while
|
* @throws CoordinationServiceException if there is an error while
|
||||||
* acquiring or releasing a
|
* acquiring or releasing a
|
||||||
* manifest file lock.
|
* manifest file lock.
|
||||||
* @throws InterruptedException if the thread is interrupted while
|
* @throws InterruptedException if the thread is interrupted
|
||||||
* reading the lock data
|
* while reading the lock data
|
||||||
*/
|
*/
|
||||||
private Lock dequeueAndLockNextJob() throws CoordinationServiceException, InterruptedException {
|
private Lock dequeueAndLockNextJob() throws CoordinationServiceException, InterruptedException {
|
||||||
SYS_LOGGER.log(Level.INFO, "Checking pending jobs queue for ready job, enforcing max jobs per case");
|
SYS_LOGGER.log(Level.INFO, "Checking pending jobs queue for ready job, enforcing max jobs per case");
|
||||||
@ -1694,8 +1639,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* @throws CoordinationServiceException if there is an error while
|
* @throws CoordinationServiceException if there is an error while
|
||||||
* acquiring or releasing a
|
* acquiring or releasing a
|
||||||
* manifest file lock.
|
* manifest file lock.
|
||||||
* @throws InterruptedException if the thread is interrupted while
|
* @throws InterruptedException if the thread is interrupted
|
||||||
* reading the lock data
|
* while reading the lock data
|
||||||
*/
|
*/
|
||||||
private Lock dequeueAndLockNextJob(boolean enforceMaxJobsPerCase) throws CoordinationServiceException, InterruptedException {
|
private Lock dequeueAndLockNextJob(boolean enforceMaxJobsPerCase) throws CoordinationServiceException, InterruptedException {
|
||||||
Lock manifestLock = null;
|
Lock manifestLock = null;
|
||||||
@ -1718,8 +1663,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
ManifestNodeData nodeData = new ManifestNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString()));
|
ManifestNodeData nodeData = new ManifestNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString()));
|
||||||
if (!nodeData.getStatus().equals(PENDING)) {
|
if (!nodeData.getStatus().equals(PENDING)) {
|
||||||
/*
|
/*
|
||||||
* Due to a timing issue or a missed event,
|
* Due to a timing issue or a missed event, a
|
||||||
* a non-pending job has ended up on the pending queue.
|
* non-pending job has ended up on the pending queue.
|
||||||
* Skip the job and remove it from the queue.
|
* Skip the job and remove it from the queue.
|
||||||
*/
|
*/
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
@ -1820,7 +1765,6 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
}
|
}
|
||||||
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath, nodeData.toArray());
|
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath, nodeData.toArray());
|
||||||
|
|
||||||
|
|
||||||
boolean retry = (!currentJob.isCancelled() && !currentJob.isCompleted());
|
boolean retry = (!currentJob.isCancelled() && !currentJob.isCompleted());
|
||||||
SYS_LOGGER.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry});
|
SYS_LOGGER.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry});
|
||||||
if (currentJob.isCancelled()) {
|
if (currentJob.isCancelled()) {
|
||||||
@ -1983,20 +1927,17 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
String caseName = manifest.getCaseName();
|
String caseName = manifest.getCaseName();
|
||||||
SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
|
SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
|
||||||
currentJob.setStage(AutoIngestJob.Stage.OPENING_CASE);
|
currentJob.setStage(AutoIngestJob.Stage.OPENING_CASE);
|
||||||
try (Lock caseLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, caseName, 12, TimeUnit.HOURS)) { // RJCTODO: New lock type!
|
|
||||||
if (null != caseLock) {
|
|
||||||
try {
|
try {
|
||||||
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, caseName);
|
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, caseName);
|
||||||
if (null != caseDirectoryPath) {
|
if (null != caseDirectoryPath) {
|
||||||
Path metadataFilePath = caseDirectoryPath.resolve(manifest.getCaseName() + CaseMetadata.getFileExtension());
|
Path metadataFilePath = caseDirectoryPath.resolve(manifest.getCaseName() + CaseMetadata.getFileExtension());
|
||||||
Case.openCurrentCase(metadataFilePath.toString());
|
Case.openAsCurrentCase(metadataFilePath.toString());
|
||||||
} else {
|
} else {
|
||||||
caseDirectoryPath = PathUtils.createCaseFolderPath(rootOutputDirectory, caseName);
|
caseDirectoryPath = PathUtils.createCaseFolderPath(rootOutputDirectory, caseName);
|
||||||
Case.createCurrentCase(caseDirectoryPath.toString(), currentJob.getManifest().getCaseName(), "", "", CaseType.MULTI_USER_CASE);
|
Case.createAsCurrentCase(caseDirectoryPath.toString(), currentJob.getManifest().getCaseName(), "", "", CaseType.MULTI_USER_CASE);
|
||||||
/*
|
/*
|
||||||
* Sleep a bit before releasing the lock to ensure
|
* Sleep a bit before releasing the lock to ensure that the
|
||||||
* that the new case folder is visible on the
|
* new case folder is visible on the network.
|
||||||
* network.
|
|
||||||
*/
|
*/
|
||||||
Thread.sleep(AutoIngestUserPreferences.getSecondsToSleepBetweenCases() * 1000);
|
Thread.sleep(AutoIngestUserPreferences.getSecondsToSleepBetweenCases() * 1000);
|
||||||
}
|
}
|
||||||
@ -2009,16 +1950,11 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
throw new CaseManagementException(String.format("Error creating or opening case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
|
throw new CaseManagementException(String.format("Error creating or opening case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
/*
|
/*
|
||||||
* Deal with the unfortunate fact that
|
* Deal with the unfortunate fact that Case.getCurrentCase
|
||||||
* Case.getCurrentCase throws IllegalStateException.
|
* throws IllegalStateException.
|
||||||
*/
|
*/
|
||||||
throw new CaseManagementException(String.format("Error getting current case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
|
throw new CaseManagementException(String.format("Error getting current case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new CaseManagementException(String.format("Timed out acquiring case name lock for %s for %s", manifest.getCaseName(), manifest.getFilePath()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2118,7 +2054,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* Sleep to allow ingest event subscribers to do their event
|
* Sleep to allow ingest event subscribers to do their event
|
||||||
* handling.
|
* handling.
|
||||||
*/
|
*/
|
||||||
Thread.sleep(AutoIngestUserPreferences.getSecondsToSleepBetweenCases() * 1000); // RJCTODO: Change the setting description to be more generic
|
Thread.sleep(AutoIngestUserPreferences.getSecondsToSleepBetweenCases() * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentJob.isCancelled() || jobProcessingTaskFuture.isCancelled()) {
|
if (currentJob.isCancelled() || jobProcessingTaskFuture.isCancelled()) {
|
||||||
@ -2370,7 +2306,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
*/
|
*/
|
||||||
ingestLock.wait();
|
ingestLock.wait();
|
||||||
IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot();
|
IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot();
|
||||||
for (IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot : jobSnapshot.getDataSourceSnapshots()) { // RJCTODO: Are "child" jobs IngestJobs or DataSourceIngestJobs?
|
for (IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot : jobSnapshot.getDataSourceSnapshots()) {
|
||||||
if (!snapshot.isCancelled()) {
|
if (!snapshot.isCancelled()) {
|
||||||
List<String> cancelledModules = snapshot.getCancelledDataSourceIngestModules();
|
List<String> cancelledModules = snapshot.getCancelledDataSourceIngestModules();
|
||||||
if (!cancelledModules.isEmpty()) {
|
if (!cancelledModules.isEmpty()) {
|
||||||
@ -2421,7 +2357,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventListener);
|
IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventListener);
|
||||||
currentJob.setIngestJob(null); // RJCTODO: Consider moving AutoIngestJob into AutoIngestManager so that this method can be made private
|
currentJob.setIngestJob(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2686,7 +2622,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* remote jobs. The auto ingest job status event is sent only if auto ingest
|
* remote jobs. The auto ingest job status event is sent only if auto ingest
|
||||||
* manager has a currently running auto ingest job.
|
* manager has a currently running auto ingest job.
|
||||||
*/
|
*/
|
||||||
private final class PeriodicJobStatusEventTask implements Runnable { // RJCTODO: Rename to StatusPublishingTask, especially when publishing to the system dashboard
|
private final class PeriodicJobStatusEventTask implements Runnable {
|
||||||
|
|
||||||
private final long MAX_SECONDS_WITHOUT_UPDATE = JOB_STATUS_EVENT_INTERVAL_SECONDS * MAX_MISSED_JOB_STATUS_UPDATES;
|
private final long MAX_SECONDS_WITHOUT_UPDATE = JOB_STATUS_EVENT_INTERVAL_SECONDS * MAX_MISSED_JOB_STATUS_UPDATES;
|
||||||
|
|
||||||
@ -2710,8 +2646,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
boolean isError = false;
|
boolean isError = false;
|
||||||
if (getErrorState().equals(ErrorState.NONE)) {
|
if (getErrorState().equals(ErrorState.NONE)) {
|
||||||
if (currentJob != null) {
|
if (currentJob != null) {
|
||||||
message = "Processing " + currentJob.getManifest().getDataSourceFileName() +
|
message = "Processing " + currentJob.getManifest().getDataSourceFileName()
|
||||||
" for case " + currentJob.getManifest().getCaseName();
|
+ " for case " + currentJob.getManifest().getCaseName();
|
||||||
} else {
|
} else {
|
||||||
message = "Paused or waiting for next case";
|
message = "Paused or waiting for next case";
|
||||||
}
|
}
|
||||||
@ -2778,7 +2714,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
/*
|
/*
|
||||||
* Events published by an auto ingest manager. The events are published
|
* Events published by an auto ingest manager. The events are published
|
||||||
* locally to auto ingest manager clients that register as observers and are
|
* locally to auto ingest manager clients that register as observers and are
|
||||||
* broadcast to other auto ingest nodes. // RJCTODO: Is this true?
|
* broadcast to other auto ingest nodes.
|
||||||
*/
|
*/
|
||||||
enum Event {
|
enum Event {
|
||||||
|
|
||||||
@ -2853,7 +2789,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* @return The jobs collection.
|
* @return The jobs collection.
|
||||||
*/
|
*/
|
||||||
List<AutoIngestJob> getPendingJobs() {
|
List<AutoIngestJob> getPendingJobs() {
|
||||||
return this.pendingJobs;
|
return Collections.unmodifiableList(this.pendingJobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2862,7 +2798,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* @return The jobs collection.
|
* @return The jobs collection.
|
||||||
*/
|
*/
|
||||||
List<AutoIngestJob> getRunningJobs() {
|
List<AutoIngestJob> getRunningJobs() {
|
||||||
return this.runningJobs;
|
return Collections.unmodifiableList(this.runningJobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2871,14 +2807,11 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
* @return The jobs collection.
|
* @return The jobs collection.
|
||||||
*/
|
*/
|
||||||
List<AutoIngestJob> getCompletedJobs() {
|
List<AutoIngestJob> getCompletedJobs() {
|
||||||
return this.completedJobs;
|
return Collections.unmodifiableList(this.completedJobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
enum CaseDeletionResult {
|
enum CaseDeletionResult {
|
||||||
FAILED,
|
FAILED,
|
||||||
PARTIALLY_DELETED,
|
PARTIALLY_DELETED,
|
||||||
|
@ -34,9 +34,6 @@ import org.w3c.dom.Document;
|
|||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@ServiceProvider(service = ManifestFileParser.class)
|
@ServiceProvider(service = ManifestFileParser.class)
|
||||||
public final class AutopsyManifestFileParser implements ManifestFileParser {
|
public final class AutopsyManifestFileParser implements ManifestFileParser {
|
||||||
@ -47,14 +44,6 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
|
|||||||
private static final String DEVICE_ID_XPATH = "/Manifest/Collection/Image/ID/text()";
|
private static final String DEVICE_ID_XPATH = "/Manifest/Collection/Image/ID/text()";
|
||||||
private static final String DATA_SOURCE_NAME_XPATH = "/Manifest/Collection/Image/Name/text()";
|
private static final String DATA_SOURCE_NAME_XPATH = "/Manifest/Collection/Image/Name/text()";
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fileIsManifest(Path filePath) {
|
public boolean fileIsManifest(Path filePath) {
|
||||||
boolean fileIsManifest = false;
|
boolean fileIsManifest = false;
|
||||||
@ -71,15 +60,6 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
|
|||||||
return fileIsManifest;
|
return fileIsManifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param filePath
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws org.sleuthkit.autopsy.experimental.autoingest.ManifestFileParser.ManifestFileParserException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Manifest parse(Path filePath) throws ManifestFileParserException {
|
public Manifest parse(Path filePath) throws ManifestFileParserException {
|
||||||
if (!fileIsManifest(filePath)) {
|
if (!fileIsManifest(filePath)) {
|
||||||
@ -102,17 +82,6 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param manifestFilePath
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws ParserConfigurationException
|
|
||||||
* @throws SAXException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private Document createManifestDOM(Path manifestFilePath) throws ParserConfigurationException, SAXException, IOException {
|
private Document createManifestDOM(Path manifestFilePath) throws ParserConfigurationException, SAXException, IOException {
|
||||||
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
|
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
|
||||||
|
@ -29,9 +29,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*/
|
|
||||||
@Immutable
|
@Immutable
|
||||||
public final class Manifest implements Serializable {
|
public final class Manifest implements Serializable {
|
||||||
|
|
||||||
@ -43,17 +40,6 @@ public final class Manifest implements Serializable {
|
|||||||
private final String dataSourcePath;
|
private final String dataSourcePath;
|
||||||
private final Map<String, String> manifestProperties;
|
private final Map<String, String> manifestProperties;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @param manifestFilePath
|
|
||||||
* @param caseName
|
|
||||||
* @param deviceId
|
|
||||||
* @param dataSourcePath
|
|
||||||
* @param manifestProperties
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public Manifest(Path manifestFilePath, String caseName, String deviceId, Path dataSourcePath, Map<String, String> manifestProperties) throws IOException {
|
public Manifest(Path manifestFilePath, String caseName, String deviceId, Path dataSourcePath, Map<String, String> manifestProperties) throws IOException {
|
||||||
this.filePath = manifestFilePath.toString();
|
this.filePath = manifestFilePath.toString();
|
||||||
BasicFileAttributes attrs = Files.readAttributes(manifestFilePath, BasicFileAttributes.class);
|
BasicFileAttributes attrs = Files.readAttributes(manifestFilePath, BasicFileAttributes.class);
|
||||||
@ -64,65 +50,30 @@ public final class Manifest implements Serializable {
|
|||||||
this.manifestProperties = new HashMap<>(manifestProperties);
|
this.manifestProperties = new HashMap<>(manifestProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Path getFilePath() {
|
public Path getFilePath() {
|
||||||
return Paths.get(this.filePath);
|
return Paths.get(this.filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public Date getDateFileCreated() {
|
public Date getDateFileCreated() {
|
||||||
return this.dateFileCreated;
|
return this.dateFileCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getCaseName() {
|
public String getCaseName() {
|
||||||
return caseName;
|
return caseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getDeviceId() {
|
public String getDeviceId() {
|
||||||
return deviceId;
|
return deviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Path getDataSourcePath() {
|
public Path getDataSourcePath() {
|
||||||
return Paths.get(dataSourcePath);
|
return Paths.get(dataSourcePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getDataSourceFileName() {
|
public String getDataSourceFileName() {
|
||||||
return Paths.get(dataSourcePath).getFileName().toString();
|
return Paths.get(dataSourcePath).getFileName().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Map<String, String> getManifestProperties() {
|
public Map<String, String> getManifestProperties() {
|
||||||
return new HashMap<>(manifestProperties);
|
return new HashMap<>(manifestProperties);
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,11 @@ package org.sleuthkit.autopsy.experimental.autoingest;
|
|||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
/**
|
|
||||||
* RJCTODO:
|
|
||||||
*/
|
|
||||||
public interface ManifestFileParser {
|
public interface ManifestFileParser {
|
||||||
|
|
||||||
boolean fileIsManifest(Path filePath);
|
boolean fileIsManifest(Path filePath);
|
||||||
Manifest parse(Path filePath) throws ManifestFileParserException;
|
Manifest parse(Path filePath) throws ManifestFileParserException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown if a manifest file cannot be parsed. RJCTODO
|
|
||||||
*/
|
|
||||||
public final static class ManifestFileParserException extends Exception {
|
public final static class ManifestFileParserException extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
@ -99,9 +99,6 @@ final class ManifestNodeData {
|
|||||||
*
|
*
|
||||||
* @return True or false.
|
* @return True or false.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: This is confusing, consider changing the API so that the use case is to
|
|
||||||
// check the length of the node data from the coordination service before
|
|
||||||
// constructing an instance of this object. That would be much more clear!
|
|
||||||
boolean coordSvcNodeDataWasSet() {
|
boolean coordSvcNodeDataWasSet() {
|
||||||
return this.coordSvcNodeDataWasSet;
|
return this.coordSvcNodeDataWasSet;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ final class PathUtils {
|
|||||||
*
|
*
|
||||||
* @return A list of the output case folder paths.
|
* @return A list of the output case folder paths.
|
||||||
*/
|
*/
|
||||||
static List<Path> findCaseFolders(Path folderToSearch) { // RJCTODO: Rename
|
static List<Path> findCaseFolders(Path folderToSearch) {
|
||||||
File searchFolder = new File(folderToSearch.toString());
|
File searchFolder = new File(folderToSearch.toString());
|
||||||
if (!searchFolder.isDirectory()) {
|
if (!searchFolder.isDirectory()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -135,7 +135,7 @@ final class PathUtils {
|
|||||||
*
|
*
|
||||||
* @return A case folder path with a time stamp suffix.
|
* @return A case folder path with a time stamp suffix.
|
||||||
*/
|
*/
|
||||||
static Path createCaseFolderPath(Path caseFoldersPath, String caseName) { // RJCTODO: Rename
|
static Path createCaseFolderPath(Path caseFoldersPath, String caseName) {
|
||||||
String folderName = caseName + "_" + TimeStampUtils.createTimeStamp();
|
String folderName = caseName + "_" + TimeStampUtils.createTimeStamp();
|
||||||
return Paths.get(caseFoldersPath.toString(), folderName);
|
return Paths.get(caseFoldersPath.toString(), folderName);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import java.util.regex.Pattern;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutopsyService;
|
import org.sleuthkit.autopsy.framework.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.UNCPathUtilities;
|
import org.sleuthkit.autopsy.coreutils.UNCPathUtilities;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
@ -26,7 +26,7 @@ import java.util.List;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
import org.openide.modules.InstalledFileLocator;
|
import org.openide.modules.InstalledFileLocator;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutopsyService;
|
import org.sleuthkit.autopsy.framework.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
@ -30,7 +30,7 @@ import org.openide.util.NbBundle;
|
|||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.openide.util.lookup.ServiceProviders;
|
import org.openide.util.lookup.ServiceProviders;
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.AutopsyService;
|
import org.sleuthkit.autopsy.framework.AutopsyService;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||||
@ -55,6 +55,14 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
|||||||
|
|
||||||
ArtifactTextExtractor extractor = new ArtifactTextExtractor();
|
ArtifactTextExtractor extractor = new ArtifactTextExtractor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an artifact to the keyword search text index as a concantenation of
|
||||||
|
* all of its attributes.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact to index.
|
||||||
|
*
|
||||||
|
* @throws org.sleuthkit.datamodel.TskCoreException
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException {
|
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException {
|
||||||
if (artifact == null) {
|
if (artifact == null) {
|
||||||
@ -77,21 +85,12 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if we can communicate with Solr using the passed-in host and port.
|
* Tries to connect to the keyword search service.
|
||||||
* Closes the connection upon exit. Throws if it cannot communicate with
|
|
||||||
* Solr.
|
|
||||||
*
|
*
|
||||||
* When issues occur, it attempts to diagnose them by looking at the
|
* @param host The hostname or IP address of the service.
|
||||||
* exception messages, returning the appropriate user-facing text for the
|
* @param port The port used by the service.
|
||||||
* exception received. This method expects the Exceptions messages to be in
|
|
||||||
* English and compares against English text.
|
|
||||||
*
|
|
||||||
* @param host the remote hostname or IP address of the Solr server
|
|
||||||
* @param port the remote port for Solr
|
|
||||||
*
|
|
||||||
* @throws
|
|
||||||
* org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException
|
|
||||||
*
|
*
|
||||||
|
* @throws KeywordSearchServiceException if cannot connect.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void tryConnect(String host, int port) throws KeywordSearchServiceException {
|
public void tryConnect(String host, int port) throws KeywordSearchServiceException {
|
||||||
@ -138,6 +137,24 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the keyword search text index for a case.
|
||||||
|
*
|
||||||
|
* @param textIndexName The text index name.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void deleteTextIndex(String textIndexName) {
|
||||||
|
/*
|
||||||
|
* Send a core unload request to the Solr server, with the parameters
|
||||||
|
* that request deleting the index and the instance directory
|
||||||
|
* (deleteInstanceDir removes everything related to the core, the index
|
||||||
|
* directory, the configuration files, etc.) set to true.
|
||||||
|
*/
|
||||||
|
// String url = "http://" + UserPreferences.getIndexingServerHost() + ":" + UserPreferences.getIndexingServerPort() + "/solr";
|
||||||
|
// HttpSolrServer solrServer = new HttpSolrServer(url);
|
||||||
|
// org.apache.solr.client.solrj.request.CoreAdminRequest.unloadCore(textIndexName, true, true, solrServer);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user