Bug fixes for multi-user case infrastructure

This commit is contained in:
Richard Cordovano 2017-01-22 17:20:38 -05:00
parent 18e3b39a3f
commit e8b74dd1db
58 changed files with 798 additions and 1085 deletions

View File

@ -242,6 +242,7 @@
<package>org.sleuthkit.autopsy.events</package>
<package>org.sleuthkit.autopsy.externalresults</package>
<package>org.sleuthkit.autopsy.filesearch</package>
<package>org.sleuthkit.autopsy.framework</package>
<package>org.sleuthkit.autopsy.ingest</package>
<package>org.sleuthkit.autopsy.keywordsearchservice</package>
<package>org.sleuthkit.autopsy.menuactions</package>

View File

@ -43,8 +43,7 @@ final public class ExitAction implements ActionListener {
try {
Case.closeCurrentCase();
} catch (CaseActionException ex) {
// RJCTODO: Pop up here
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Error closing the current case", ex); //NON-NLS
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Error closing the current case on exit", ex); //NON-NLS
} finally {
LifecycleManager.getDefault().exit();
}

View File

@ -98,12 +98,9 @@ AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules
AddImageWizardIterator.stepXofN=Step {0} of {1}
AddLocalFilesTask.localFileAdd.progress.text=Adding\: {0}/{1}
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.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.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.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\
@ -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.
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
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.updateExaminer.exception.msg=Error while trying to update the examiner.
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.jLabel2.text=Ingest Jobs
CaseInformationPanel.closeButton.text=Close
ProgressPanel.progressMessage.text=Message

View File

@ -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_CaseCloseAct=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u308b
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}
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.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\
{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.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\
\u4ee5\u524d\u3001\u30a4\u30e1\u30fc\u30b8\u306f\u6b21\u306b\u3042\u308a\u307e\u3057\u305f\uff1a\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
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.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.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

File diff suppressed because it is too large Load Diff

View File

@ -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() {
}
}

View File

@ -22,6 +22,7 @@ import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@ -38,6 +39,7 @@ import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
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 {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(CaseCloseAction.class.getName());
private final JButton toolbarButton = new JButton();
/**
@ -77,8 +80,8 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
*/
if (IngestManager.getInstance().isIngestRunning()) {
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO
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);
@ -105,7 +108,7 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
try {
get();
} 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));
StartupWindowProvider.getInstance().open();

View File

@ -169,45 +169,10 @@ public final class CaseMetadata {
*
* @return The case display name.
*/
// RJCTODO: Deal with the change
public String getCaseName() {
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.
*
@ -223,7 +188,6 @@ public final class CaseMetadata {
*
* @param caseName A case display name.
*/
// RJCTODO: Deal with the change
void setCaseDisplayName(String caseName) throws CaseMetadataException {
String oldCaseName = 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.
*
@ -349,7 +329,6 @@ public final class CaseMetadata {
* @throws CaseMetadataException If there is an error writing to the case
* metadata file.
*/
// RJCTODO: Should we have a backup copy of the file in case of error?
private void writeToFile() throws CaseMetadataException {
try {
/*

View File

@ -43,7 +43,9 @@ import org.sleuthkit.autopsy.coreutils.Version;
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)
public final class CaseOpenAction extends CallableSystemAction implements ActionListener {
@ -82,8 +84,8 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
*/
if (IngestManager.getInstance().isIngestRunning()) {
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning"), // RJCTODO
NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title"), // RJCTODO
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);
@ -116,7 +118,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
@Override
protected Void doInBackground() throws Exception {
Case.openCurrentCase(path);
Case.openAsCurrentCase(path);
return null;
}

View File

@ -77,15 +77,15 @@ class CasePropertiesForm extends javax.swing.JPanel {
*/
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
initComponents();
caseNameTextField.setText(currentCase.getName());
caseNameTextField.setText(currentCase.getDisplayName());
String caseNumber = currentCase.getNumber();
if (!caseNumber.equals("")) {
if (!caseNumber.isEmpty()) {
caseNumberField.setText(caseNumber);
} else {
caseNumberField.setText("N/A");
}
String examiner = currentCase.getExaminer();
if (!examiner.equals("")) {
if (!examiner.isEmpty()) {
examinerField.setText(examiner);
} else {
examinerField.setText("N/A");
@ -303,13 +303,13 @@ class CasePropertiesForm extends javax.swing.JPanel {
* @param evt The action event
*/
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();
// check if the old and new case name is not equal
if (!oldCaseName.equals(newCaseName)) {
// check if the case name is empty
if (newCaseName.trim().equals("")) {
if (newCaseName.trim().isEmpty()) {
JOptionPane.showMessageDialog(caller,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2015 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* 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
* nodes using progress bars, and monitors the health of key collaboration
* 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
* collaboration tasks broadcast by this node.
@ -91,9 +96,7 @@ final class CollaborationMonitor {
*/
eventPublisher = new AutopsyEventPublisher();
try {
Case openedCase = Case.getCurrentCase();
String channelPrefix = openedCase.getTextIndexName();
eventPublisher.openRemoteEventChannel(String.format(EVENT_CHANNEL_NAME, channelPrefix));
eventPublisher.openRemoteEventChannel(String.format(EVENT_CHANNEL_NAME, eventChannelPrefix));
} catch (AutopsyEventException ex) {
throw new CollaborationMonitorException("Failed to initialize", ex);
}

View File

@ -54,6 +54,7 @@ final class DeleteCurrentCaseAction extends CallableSystemAction {
try {
Case currentCase = Case.getCurrentCase();
String caseName = currentCase.getName();
String caseDirectory = currentCase.getCaseDirectory();
/*
* Do a confirmation dialog and close the current case if the user
@ -68,16 +69,15 @@ final class DeleteCurrentCaseAction extends CallableSystemAction {
NotifyDescriptor.NO_OPTION));
if (null != response && DialogDescriptor.YES_OPTION == response) {
try {
Case.deleteCurrentCase(); // RJCTODO: Test this!
Case.deleteCurrentCase();
} 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(
null,
Bundle.Case_deleteCaseFailureMessageBox_message(ex.getMessage()),
Bundle.Case_deleteCaseFailureMessageBox_title(),
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.
CasePropertiesAction.closeCasePropertiesWindow();
}

View File

@ -33,7 +33,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
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

View File

@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
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

View File

@ -29,7 +29,7 @@ import org.openide.util.lookup.ServiceProviders;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
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

View File

@ -27,9 +27,10 @@ import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
@ -37,7 +38,9 @@ import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.SystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* An action that creates and runs the new case wizard.
@ -50,13 +53,28 @@ final class NewCaseWizardAction extends CallableSystemAction {
@Override
public void performAction() {
if (CaseActionHelper.closeCaseAndContinueAction()) {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); // RJCTODO: Is this right?
runNewCaseWizard();
/*
* If ingest is running, give the user the option to abort changing
* 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() {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
final WizardDescriptor wizardDescriptor = new WizardDescriptor(getNewCaseWizardPanels());
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
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
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //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;
}
@ -84,16 +102,16 @@ final class NewCaseWizardAction extends CallableSystemAction {
addImageAction.actionPerformed(null);
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(
WindowManager.getDefault().getMainWindow(),
(ex instanceof ExecutionException ? ex.getCause().getMessage() : ex.getMessage()),
NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"), //NON-NLS
JOptionPane.ERROR_MESSAGE);
StartupWindowProvider.getInstance().close(); // RC: Why close and open?
StartupWindowProvider.getInstance().close();
StartupWindowProvider.getInstance().open();
});
doFailedCaseCleanup(wizardDescriptor);
} finally {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}.execute();
@ -107,11 +125,8 @@ final class NewCaseWizardAction extends CallableSystemAction {
private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor) {
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
if (createdDirectory != null) {
Case.deleteCaseDirectory(new File(createdDirectory));
FileUtil.deleteDir(new File(createdDirectory));
}
SwingUtilities.invokeLater(() -> {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
});
}
/**

View File

@ -35,6 +35,7 @@ import org.openide.WizardDescriptor;
import org.openide.WizardValidationException;
import org.openide.util.HelpCtx;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/**
@ -175,7 +176,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
createdDirectory = (String) settings.getProperty("createdDirectory"); //NON-NLS
if (createdDirectory != null && !createdDirectory.equals("")) {
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) {
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
if (new File(caseDirPath).exists()) {
Case.deleteCaseDirectory(new File(caseDirPath));
FileUtil.deleteDir(new File(caseDirPath));
}
String errorMsg = NbBundle.getMessage(this.getClass(),

View File

@ -124,7 +124,7 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
} else {
new Thread(() -> {
try {
Case.openCurrentCase(casePath);
Case.openAsCurrentCase(casePath);
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", casePath), ex); //NON-NLS
SwingUtilities.invokeLater(() -> {

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2014 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -30,13 +30,13 @@ import java.util.List;
import java.util.logging.Level;
import javax.swing.JMenuItem;
import org.apache.commons.lang.ArrayUtils;
import org.openide.filesystems.FileUtil;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
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.ModuleSettings;
/**
* 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 {
static final int LENGTH = 6;
static final String NAME_PROP_KEY = "LBL_RecentCase_Name"; //NON-NLS
static final String PATH_PROP_KEY = "LBL_RecentCase_Path"; //NON-NLS
static final RecentCase BLANK_RECENTCASE = new RecentCase("", "");
private final static RecentCases INSTANCE = new RecentCases();
private Deque<RecentCase> recentCases; // newest case is last case
private static final long serialVersionUID = 1L;
private static final int LENGTH = 6;
private static final String NAME_PROP_KEY = "LBL_RecentCase_Name"; //NON-NLS
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 Deque<RecentCase> recentCases; // newest case is last case
/**
* Gets the instance of the RecentCases singleton.
@ -61,8 +60,8 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
* @return INSTANCE the RecentCases singleton
*/
static public RecentCases getInstance() {
INSTANCE.refreshRecentCases();
return INSTANCE;
instance.refreshRecentCases();
return instance;
}
/**
@ -84,7 +83,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
}
// Load recentCases from properties
recentCases = new LinkedList<RecentCase>();
recentCases = new LinkedList<>();
for (int i = 0; i < LENGTH; i++) {
final RecentCase rc = new RecentCase(getName(i), getPath(i));
@ -256,7 +255,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
*/
@Override
public void actionPerformed(ActionEvent e) {
UpdateRecentCases.hasRecentCase = false;
UpdateRecentCases.setHasRecentCase(false);
recentCases.clear();
@ -375,7 +374,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
int i = 0;
String currentCaseName = null;
try {
currentCaseName = Case.getCurrentCase().getName();
currentCaseName = Case.getCurrentCase().getDisplayName();
} catch (IllegalStateException ex) {
// in case there is no current case.
}

View File

@ -25,14 +25,17 @@ import java.awt.event.ActionListener;
import java.io.File;
import java.util.logging.Level;
import javax.swing.JOptionPane;
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.IngestManager;
/**
* An action listener that opens a recent case.
*
* IMPORTANT: Must be called in the Swing Event Dispatch Thread (EDT).
* An action listener for a specific case, associated with a Recent Cases menu
* item for the case by a DynamicMenuContent content JMenuItem.
*/
class RecentItems implements ActionListener {
@ -41,7 +44,9 @@ class RecentItems implements ActionListener {
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 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
*/
@Override
public void actionPerformed(ActionEvent e) {
if (CaseActionHelper.closeCaseAndContinueAction()) {
if (caseName.isEmpty() || caseMetaDataFilePath.isEmpty() || (!new File(caseMetaDataFilePath).exists())) {
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text", caseName),
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
JOptionPane.ERROR_MESSAGE);
RecentCases.getInstance().removeRecentCase(caseName, caseMetaDataFilePath);
EventQueue.invokeLater(() -> {
StartupWindowProvider.getInstance().open();
});
} else {
/*
* If ingest is running, give the user the option to abort changing
* cases.
*/
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;
}
}
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
Case.openCurrentCase(caseMetaDataFilePath);
Case.openAsCurrentCase(caseMetaDataFilePath);
} catch (CaseActionException ex) {
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(
WindowManager.getDefault().getMainWindow(),
ex.getMessage(), // Should be user-friendly
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
JOptionPane.ERROR_MESSAGE);
StartupWindowProvider.getInstance().open();
}
}
} finally {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}

View File

@ -48,7 +48,7 @@ import org.sleuthkit.datamodel.TskData;
*/
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 DOTAUT = CaseMetadata.getFileExtension(); //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(),
CaseType.MULTI_USER_CASE,
icd.getNewCaseName(),
icd.getNewCaseName(), // RJCTODO
icd.getNewCaseName(),
oldCaseMetadata.getCaseNumber(),
oldCaseMetadata.getExaminer(),
dbName);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2015 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* 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 {
int length;
static boolean hasRecentCase = false;
private static final long serialVersionUID = 1L;
private static int NUM_CASES_TO_DISPLAY;
private static boolean hasRecentCase = false;
/**
* the constructor
*/
UpdateRecentCases() {
// 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() {
String[] caseName = RecentCases.getInstance().getRecentCaseNames();
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
for (int i = 0; i < length; i++) {
for (int i = 0; i < NUM_CASES_TO_DISPLAY; i++) {
if ((!caseName[i].equals(""))) {
JMenuItem menuItem = new JMenuItem(caseName[i]);
menuItem.setActionCommand(caseName[i].toUpperCase());
@ -68,11 +73,11 @@ class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
// if it has recent case, create clear menu
if (hasRecentCase) {
comps[length] = new JSeparator();
comps[NUM_CASES_TO_DISPLAY] = new JSeparator();
JMenuItem clearMenu = new JMenuItem(
NbBundle.getMessage(UpdateRecentCases.class, "UpdateRecentCases.menuItem.clearRecentCases.text"));
clearMenu.addActionListener(SystemAction.get(RecentCases.class));
comps[length + 1] = clearMenu;
comps[NUM_CASES_TO_DISPLAY + 1] = clearMenu;
} // otherwise, just create a disabled empty menu
else {
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
* processing.
* Updates the Recent Cases menu items.
*
* @param jcs the previously used menu items returned by previous call to
* getMenuPresenters() or synchMenuPresenters()
* @param menuItems A set of Recent Case menu items to be updated.
*
* @return menu a new set of items to show in menu. Can be either an updated
* old set of instances or a completely new one.
* @return A updated set of recent case menu items to show in the Recent
* Cases menu.
*/
@Override
public JComponent[] synchMenuPresenters(JComponent[] jcs) {
public JComponent[] synchMenuPresenters(JComponent[] menuItems) {
return getMenuPresenters();
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2015 Basis Technology Corp.
* Copyright 2013-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* 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 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 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);
}
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);
}
}

View File

@ -46,7 +46,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
public class Installer extends ModuleInstall {
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;
public synchronized static Installer getDefault() {
@ -82,10 +82,9 @@ public class Installer extends ModuleInstall {
final String caseFile = argsProcessor.getDefaultArg();
if (caseFile != null && !caseFile.isEmpty() && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
try {
Case.openCurrentCase(caseFile);
Case.openAsCurrentCase(caseFile);
} 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;
}
@ -105,7 +104,7 @@ public class Installer extends ModuleInstall {
try {
Case.closeCurrentCase();
} 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 {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} 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
@ -140,7 +139,7 @@ public class Installer extends ModuleInstall {
try {
UIManager.setLookAndFeel(info.getClassName());
} 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;
}

View File

@ -16,9 +16,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
package org.sleuthkit.autopsy.framework;
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

View File

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
package org.sleuthkit.autopsy.framework;
import org.sleuthkit.autopsy.casemodule.Case;

View File

@ -16,16 +16,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
package org.sleuthkit.autopsy.framework;
import java.util.logging.Level;
import org.sleuthkit.autopsy.corecomponentinterfaces.ProgressIndicator;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* 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 int totalWorkUnits;

View File

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
package org.sleuthkit.autopsy.framework;
import java.awt.Dialog;
import java.awt.event.ActionListener;
@ -24,7 +24,7 @@ import javax.swing.SwingUtilities;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
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

View File

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* 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

View File

@ -42,7 +42,7 @@
<Component class="javax.swing.JLabel" name="progressMessage">
<Properties>
<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, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/framework/Bundle.properties" key="ProgressPanel.progressMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>

View File

@ -16,27 +16,20 @@
* See the License for the specific language governing permissions and
* 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 {
private static final long serialVersionUID = 1L;
/**
* RJCTODO
*/
ProgressPanel() {
initComponents();
this.progressBar.setMinimum(0);
}
/**
* RJCTODO
* @param message
*/
void setMessage(String message) {
this.progressMessage.setText(message);
}

View File

@ -379,7 +379,7 @@ public class IngestManager {
* Case.getTextIndexName() API.
*/
Case openedCase = Case.getCurrentCase();
String channelPrefix = openedCase.getTextIndexName();
String channelPrefix = openedCase.getName();
if (Case.CaseType.MULTI_USER_CASE == openedCase.getCaseType()) {
jobEventPublisher.openRemoteEventChannel(String.format(JOB_EVENT_CHANNEL_NAME, channelPrefix));
moduleEventPublisher.openRemoteEventChannel(String.format(MODULE_EVENT_CHANNEL_NAME, channelPrefix));

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -19,36 +19,42 @@
package org.sleuthkit.autopsy.keywordsearchservice;
import java.io.Closeable;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifact;
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.
*/
public interface KeywordSearchService extends Closeable {
/**
* Takes a Blackboard artifact and adds all of its attributes to the keyword
* search index.
* Tries to connect to the keyword search service server.
*
* @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
*/
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException;
/**
* Checks if we can communicate with the KeywordSearchService using the
* passed-in host and port. Closes the connection upon exit. Throws if it
* cannot communicate.
* Deletes the keyword search text index for a case.
*
* @param host the remote hostname or IP address of the server
* @param port the remote port of the server
*
* @throws KeywordSearchServiceException
* @param textIndexName The text index name.
*/
public void tryConnect(String host, int port) throws KeywordSearchServiceException;
public void deleteTextIndex(String textIndexName);
}

View File

@ -18,7 +18,7 @@
*/
package org.sleuthkit.autopsy.modules.hashdatabase;
import org.sleuthkit.autopsy.corecomponentinterfaces.ProgressIndicator;
import org.sleuthkit.autopsy.framework.ProgressIndicator;
/**
* A "silent" or "null" progress indicator.

View File

@ -301,7 +301,7 @@ class ReportExcel implements TableReportModule {
row = sheet.createRow(rowIndex);
row.setRowStyle(setStyle);
row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseName"));
row.createCell(1).setCellValue(currentCase.getName());
row.createCell(1).setCellValue(currentCase.getDisplayName());
++rowIndex;
row = sheet.createRow(rowIndex);

View File

@ -93,7 +93,7 @@ class ReportGenerator {
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new 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<>();

View File

@ -857,7 +857,7 @@ class ReportHTML implements TableReportModule {
iconPath = "favicon.ico";
}
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
index.append("<link rel=\"icon\" type=\"image/ico\" href=\"")
.append(iconPath).append("\" />\n"); //NON-NLS
@ -1017,7 +1017,7 @@ class ReportHTML implements TableReportModule {
Date date = new Date();
String datetime = datetimeFormat.format(date);
String caseName = currentCase.getName();
String caseName = currentCase.getDisplayName();
String caseNumber = currentCase.getNumber();
String examiner = currentCase.getExaminer();
int imagecount;

View File

@ -90,7 +90,7 @@ public class AddTaggedHashesToHashDb implements GeneralReportModule {
if (content instanceof AbstractFile) {
if (null != ((AbstractFile) content).getMd5Hash()) {
try {
hashSet.addHashes(tag.getContent(), Case.getCurrentCase().getName());
hashSet.addHashes(tag.getContent(), Case.getCurrentCase().getDisplayName());
} 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);
failedExports.add(tag.getContent().getName());

View File

@ -20,14 +20,14 @@ package org.sleuthkit.autopsy.test;
import java.util.logging.Level;
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.framework.AutopsyService;
import org.sleuthkit.autopsy.framework.ProgressIndicator;
/**
* An implementation of the Autopsy service interface used for test purposes.
*/
@ServiceProvider(service = AutopsyService.class)
//@ServiceProvider(service = AutopsyService.class)
public class TestAutopsyService implements AutopsyService {
private static final Logger LOGGER = Logger.getLogger(TestAutopsyService.class.getName());

View File

@ -100,7 +100,7 @@ public class SaveSnapshotAsReport extends Action {
setEventHandler(actionEvent -> {
//capture generation date and use to make default report name
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);
//prompt user to pick report name

View File

@ -46,7 +46,6 @@ class AutoIngestCase implements Comparable<AutoIngestCase> {
*
* @param caseDirectoryPath The case directory path.
*/
// RJCTODO: Throw instead of reporting error, let client decide what to do.
AutoIngestCase(Path caseDirectoryPath) {
this.caseDirectoryPath = caseDirectoryPath;
caseName = PathUtils.caseNameFromCaseDirectoryPath(caseDirectoryPath);
@ -100,7 +99,6 @@ class AutoIngestCase implements Comparable<AutoIngestCase> {
*
* @return The last accessed date.
*/
// RJCTODO: Throw instead of reporting error, let client decide what to do.
Date getLastAccessedDate() {
try {
BasicFileAttributes fileAttrs = Files.readAttributes(metadataFilePath, BasicFileAttributes.class);

View File

@ -45,20 +45,10 @@ final class AutoIngestCaseDeletedEvent extends AutopsyEvent implements Serializa
this.nodeName = nodeName;
}
/**
* RJCTODO
*
* @return
*/
String getCaseName() {
return caseName;
}
/**
* RJCTODO
*
* @return
*/
String getNodeName() {
return nodeName;
}

View File

@ -72,7 +72,6 @@ final class AutoIngestCaseManager {
* this machine, but review mode is only for looking at cases created by
* automated ingest.
*/
// RJCTODO: Write a story about this.
FileObject root = FileUtil.getConfigRoot();
FileObject openRecentCasesMenu = root.getFileObject("Menu/Case/OpenRecentCase");
if (openRecentCasesMenu != null) {
@ -108,7 +107,7 @@ final class AutoIngestCaseManager {
/*
* Open the case.
*/
Case.openCurrentCase(caseMetadataFilePath.toString());
Case.openAsCurrentCase(caseMetadataFilePath.toString());
/**
* 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
* have to do the same thing here to maintain the order of execution.
*/
// RJCTODO: Write a story about this.
SwingUtilities.invokeLater(() -> {
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
});

View File

@ -25,7 +25,7 @@ import org.sleuthkit.autopsy.events.AutopsyEvent;
* Event published when an automated ingest manager prioritizes all or part of a
* 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 final String caseName;

View File

@ -24,6 +24,7 @@ import java.nio.file.Paths;
import java.time.Instant;
import java.util.Comparator;
import java.util.Date;
import java.util.Objects;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
@ -55,9 +56,9 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
@GuardedBy("this")
transient private IngestJob ingestJob;
@GuardedBy("this")
transient private boolean cancelled; // RJCTODO: Document
transient private boolean cancelled;
@GuardedBy("this")
transient private boolean completed; // RJCTODO: Document
transient private boolean completed;
@GuardedBy("this")
private Date completedDate;
@GuardedBy("this")
@ -81,7 +82,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
* indicate the the job is not completed, i.e., new
* 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) {
this.manifest = manifest;
if (null != caseDirectoryPath) {
@ -112,7 +112,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
*
* @return True or false
*/
// RJCTODO: Use this or lose this
synchronized boolean hasCaseDirectoryPath() {
return (false == this.caseDirectoryPath.isEmpty());
}
@ -161,21 +160,10 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
return this.priority;
}
/**
* RJCTODO
*
* @param newStage
*/
synchronized void setStage(Stage newStage) {
setStage(newStage, Date.from(Instant.now()));
}
/**
* RJCTODO
*
* @param state
* @param stateStartedDate
*/
synchronized void setStage(Stage newState, Date stateStartedDate) {
if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newState) {
return;
@ -184,29 +172,14 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
this.stageStartDate = stateStartedDate;
}
/**
* RJCTODO:
*
* @return
*/
synchronized Stage getStage() {
return this.stage;
}
/**
* RJCTODO
*
* @return
*/
synchronized Date getStageStartDate() {
return this.stageStartDate;
}
/**
* RJCTODO
*
* @return
*/
synchronized StageDetails getStageDetails() {
String description;
Date startDate;
@ -223,7 +196,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
if (!ingestModuleHandle.isCancelled()) {
description = ingestModuleHandle.displayName();
} else {
description = String.format(Stage.CANCELLING_MODULE.getDisplayText(), ingestModuleHandle.displayName()); // RJCTODO: FIx this
description = String.format(Stage.CANCELLING_MODULE.getDisplayText(), ingestModuleHandle.displayName());
}
} else {
/**
@ -248,26 +221,14 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
this.dataSourceProcessor = dataSourceProcessor;
}
/**
* RJCTODO
*/
// RJCTODO: Consider moving this class into AIM and making this private
synchronized void setIngestJob(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() {
return this.ingestJob;
}
/**
* RJCTODO
*/
synchronized void cancel() {
setStage(Stage.CANCELLING);
cancelled = true;
@ -280,26 +241,15 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
}
}
/**
* RJCTODO
*/
synchronized boolean isCancelled() {
return cancelled;
}
/**
* RJCTODO
*/
synchronized void setCompleted() {
setStage(Stage.COMPLETED);
completed = true;
}
/**
* RJCTODO
*
* @return
*/
synchronized boolean isCompleted() {
return completed;
}
@ -321,7 +271,7 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
* @return True or false.
*/
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;
}
/**
* 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() {
return nodeName;
}
/**
* RJCTODO
*
* @param obj
*
* @return
*/
@Override
public boolean equals(Object obj) {
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());
}
/**
* RJCTODO
*
* @return
*/
@Override
public int hashCode() {
// RJCTODO: Update this
int hash = 7;
// hash = 71 * hash + Objects.hashCode(this.dateCreated);
int hash = 71 * (Objects.hashCode(this.caseDirectoryPath));
return hash;
}
/**
* RJCTODO Default sorting is by ready file creation date, descending
*
* @param o
*
* @return
*/
@Override
public int compareTo(AutoIngestJob o) {
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> {
/**
* RJCTODO
*
* @param o1
* @param o2
*
* @return
*/
@Override
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
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> {
/**
* RJCTODO
*
* @param job
* @param anotherJob
*
* @return
*/
@Override
public int compare(AutoIngestJob job, AutoIngestJob anotherJob) {
return -(job.getPriority().compareTo(anotherJob.getPriority()));
@ -442,14 +349,6 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
*/
static class AlphabeticalComparator implements Comparator<AutoIngestJob> {
/**
* RJCTODO
*
* @param o1
* @param o2
*
* @return
*/
@Override
public int compare(AutoIngestJob o1, AutoIngestJob o2) {
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 {
PENDING("Pending"),
@ -494,40 +389,21 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
}
/**
* RJCTODO
*/
@Immutable
static final class StageDetails {
private final String description;
private final Date startDate;
/**
* RJCTODO
*
* @param description
* @param startDate
*/
private StageDetails(String description, Date startDate) {
this.description = description;
this.startDate = startDate;
}
/**
* RJCTODO
*
* @return
*/
String getDescription() {
return this.description;
}
/**
* RJCTODO
*
* @return
*/
Date getStartDate() {
return this.startDate;
}

View File

@ -22,28 +22,17 @@ import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
import org.sleuthkit.autopsy.events.AutopsyEvent;
/**
* RJCTODO
*/
@Immutable
abstract class AutoIngestJobEvent extends AutopsyEvent implements Serializable {
private static final long serialVersionUID = 1L;
private final AutoIngestJob job;
/**
* RJCTODO
*
*/
AutoIngestJobEvent(AutoIngestManager.Event eventSubType, AutoIngestJob job) {
super(eventSubType.toString(), null, null);
this.job = job;
}
/**
* RJCTODO
* @return
*/
AutoIngestJob getJob() {
return this.job;
}

View File

@ -192,7 +192,7 @@ final class AutoIngestJobLogger {
* to acquire an exclusive lock on the
* 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");
}

View File

@ -28,9 +28,6 @@ public final class AutoIngestJobStartedEvent extends AutoIngestJobEvent implemen
private static final long serialVersionUID = 1L;
/**
* RJCTODO
*/
public AutoIngestJobStartedEvent(AutoIngestJob job) {
super(AutoIngestManager.Event.JOB_STARTED, job);
}

View File

@ -28,9 +28,6 @@ public final class AutoIngestJobStatusEvent extends AutoIngestJobEvent implement
private static final long serialVersionUID = 1L;
/**
* RJCTODO
*/
public AutoIngestJobStatusEvent(AutoIngestJob job) {
super(AutoIngestManager.Event.JOB_STATUS_UPDATED, job);
}

View File

@ -18,11 +18,9 @@
*/
package org.sleuthkit.autopsy.experimental.autoingest;
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
import java.io.File;
import java.io.IOException;
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
@ -38,9 +36,6 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
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.Instant;
import java.util.ArrayList;
@ -54,13 +49,13 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
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.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@ -69,65 +64,50 @@ import java.util.stream.Collectors;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import javax.swing.filechooser.FileFilter;
import javax.xml.parsers.DocumentBuilder;
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.apache.solr.client.solrj.impl.HttpSolrServer;
import org.openide.util.Lookup;
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.GeneralFilter;
import org.sleuthkit.autopsy.casemodule.ImageDSProcessor;
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.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
import org.sleuthkit.autopsy.casemodule.LocalFilesDSProcessor;
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
import org.sleuthkit.autopsy.core.RuntimeProperties;
import org.sleuthkit.autopsy.core.ServicesMonitor;
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.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.ingest.IngestJob.CancellationReason;
import org.sleuthkit.autopsy.ingest.IngestJobStartResult;
import org.sleuthkit.autopsy.ingest.IngestModuleError;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestAlertFile.AutoIngestAlertFileException;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJobLogger.AutoIngestJobLoggerException;
import org.sleuthkit.autopsy.experimental.autoingest.FileExporter.FileExportException;
import org.sleuthkit.autopsy.experimental.autoingest.ManifestFileParser.ManifestFileParserException;
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.DELETED;
import org.sleuthkit.autopsy.corecomponentinterfaces.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestAlertFile.AutoIngestAlertFileException;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJobLogger.AutoIngestJobLoggerException;
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.PENDING;
import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.ProcessingStatus.PROCESSING;
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
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.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
@ -240,7 +220,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
eventPublisher.openRemoteEventChannel(EVENT_CHANNEL_NAME);
SYS_LOGGER.log(Level.INFO, "Opened auto ingest event channel");
} 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());
rootOutputDirectory = Paths.get(AutoIngestUserPreferences.getAutoModeResultsFolder());
@ -249,7 +230,13 @@ public final class AutoIngestManager extends Observable implements PropertyChang
jobProcessingTaskFuture = jobProcessingExecutor.submit(jobProcessingTask);
jobStatusPublishingExecutor.scheduleAtFixedRate(new PeriodicJobStatusEventTask(), JOB_STATUS_EVENT_INTERVAL_SECONDS, JOB_STATUS_EVENT_INTERVAL_SECONDS, TimeUnit.SECONDS);
eventPublisher.addSubscriber(EVENT_LIST, instance);
try {
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;
errorState = ErrorState.NONE;
}
@ -483,7 +470,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
for (AutoIngestJob job : hostNamesToRunningJobs.values()) {
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) {
@ -684,18 +671,22 @@ public final class AutoIngestManager extends Observable implements PropertyChang
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;
List<Lock> manifestFileLocks = new ArrayList<>();
try (Lock caseLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())) {
if (null == caseLock) {
try {
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;
}
synchronized (jobsLock) {
/*
* Do a fresh input directory scan.
*/
@ -703,12 +694,14 @@ public final class AutoIngestManager extends Observable implements PropertyChang
scanner.scan();
Set<Path> manifestPaths = casesToManifests.get(caseName);
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;
}
/*
* 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) {
try {
@ -719,20 +712,18 @@ public final class AutoIngestManager extends Observable implements PropertyChang
return CaseDeletionResult.FAILED;
}
} 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;
}
}
/*
* 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 delete case metadata file %s for case %s", caseMetaDataFilePath, caseName));
/*
* Physically delete the case.
*/
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;
}
@ -745,56 +736,11 @@ public final class AutoIngestManager extends Observable implements PropertyChang
nodeData.setStatus(ManifestNodeData.ProcessingStatus.DELETED);
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString(), nodeData.toArray());
} 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;
}
}
/*
* 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
* completed jobs list.
@ -809,16 +755,15 @@ public final class AutoIngestManager extends Observable implements PropertyChang
notifyObservers(Event.CASE_DELETED);
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 {
/*
* Always release the manifest locks, regardless of the outcome.
*/
for (Lock lock : manifestFileLocks) {
try {
lock.release();
} 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.
*
* @return Snapshot of jobs lists
*/
JobsSnapshot getCurrentJobsSnapshot() {
@ -895,9 +841,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
* Starts the process of cancelling the current job.
*
* Note that the current job is included in the running list for a while
* because it can take some time
* for the automated ingest process for the job to be shut down in
* an orderly fashion.
* because it can take some time for the automated ingest process for the
* job to be shut down in an orderly fashion.
*/
void cancelCurrentJob() {
if (State.RUNNING != state) {
@ -1655,8 +1600,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
* @throws CoordinationServiceException if there is an error while
* acquiring or releasing a
* manifest file lock.
* @throws InterruptedException if the thread is interrupted while
* reading the lock data
* @throws InterruptedException if the thread is interrupted
* while reading the lock data
*/
private Lock dequeueAndLockNextJob() throws CoordinationServiceException, InterruptedException {
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
* acquiring or releasing a
* manifest file lock.
* @throws InterruptedException if the thread is interrupted while
* reading the lock data
* @throws InterruptedException if the thread is interrupted
* while reading the lock data
*/
private Lock dequeueAndLockNextJob(boolean enforceMaxJobsPerCase) throws CoordinationServiceException, InterruptedException {
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()));
if (!nodeData.getStatus().equals(PENDING)) {
/*
* Due to a timing issue or a missed event,
* a non-pending job has ended up on the pending queue.
* Due to a timing issue or a missed event, a
* non-pending job has ended up on the pending queue.
* Skip the job and remove it from the queue.
*/
iterator.remove();
@ -1820,7 +1765,6 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath, nodeData.toArray());
boolean retry = (!currentJob.isCancelled() && !currentJob.isCompleted());
SYS_LOGGER.log(Level.INFO, "Completed processing of {0}, retry = {1}", new Object[]{manifestPath, retry});
if (currentJob.isCancelled()) {
@ -1983,20 +1927,17 @@ public final class AutoIngestManager extends Observable implements PropertyChang
String caseName = manifest.getCaseName();
SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()});
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 {
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, caseName);
if (null != caseDirectoryPath) {
Path metadataFilePath = caseDirectoryPath.resolve(manifest.getCaseName() + CaseMetadata.getFileExtension());
Case.openCurrentCase(metadataFilePath.toString());
Case.openAsCurrentCase(metadataFilePath.toString());
} else {
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
* that the new case folder is visible on the
* network.
* Sleep a bit before releasing the lock to ensure that the
* new case folder is visible on the network.
*/
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);
} catch (IllegalStateException ex) {
/*
* Deal with the unfortunate fact that
* Case.getCurrentCase throws IllegalStateException.
* Deal with the unfortunate fact that Case.getCurrentCase
* throws IllegalStateException.
*/
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
* 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()) {
@ -2370,7 +2306,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
*/
ingestLock.wait();
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()) {
List<String> cancelledModules = snapshot.getCancelledDataSourceIngestModules();
if (!cancelledModules.isEmpty()) {
@ -2421,7 +2357,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
} finally {
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
* 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;
@ -2710,8 +2646,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
boolean isError = false;
if (getErrorState().equals(ErrorState.NONE)) {
if (currentJob != null) {
message = "Processing " + currentJob.getManifest().getDataSourceFileName() +
" for case " + currentJob.getManifest().getCaseName();
message = "Processing " + currentJob.getManifest().getDataSourceFileName()
+ " for case " + currentJob.getManifest().getCaseName();
} else {
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
* 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 {
@ -2853,7 +2789,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
* @return The jobs collection.
*/
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.
*/
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.
*/
List<AutoIngestJob> getCompletedJobs() {
return this.completedJobs;
return Collections.unmodifiableList(this.completedJobs);
}
}
/**
* RJCTODO
*/
enum CaseDeletionResult {
FAILED,
PARTIALLY_DELETED,

View File

@ -34,9 +34,6 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* RJCTODO
*/
@Immutable
@ServiceProvider(service = ManifestFileParser.class)
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 DATA_SOURCE_NAME_XPATH = "/Manifest/Collection/Image/Name/text()";
/**
* RJCTODO
*
* @param filePath
*
* @return
*/
@Override
public boolean fileIsManifest(Path filePath) {
boolean fileIsManifest = false;
@ -71,15 +60,6 @@ public final class AutopsyManifestFileParser implements ManifestFileParser {
return fileIsManifest;
}
/**
* RJCTODO
*
* @param filePath
*
* @return
*
* @throws org.sleuthkit.autopsy.experimental.autoingest.ManifestFileParser.ManifestFileParserException
*/
@Override
public Manifest parse(Path filePath) throws ManifestFileParserException {
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 {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

View File

@ -29,9 +29,6 @@ import java.util.HashMap;
import java.util.Map;
import javax.annotation.concurrent.Immutable;
/**
* RJCTODO
*/
@Immutable
public final class Manifest implements Serializable {
@ -43,17 +40,6 @@ public final class Manifest implements Serializable {
private final String dataSourcePath;
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 {
this.filePath = manifestFilePath.toString();
BasicFileAttributes attrs = Files.readAttributes(manifestFilePath, BasicFileAttributes.class);
@ -64,65 +50,30 @@ public final class Manifest implements Serializable {
this.manifestProperties = new HashMap<>(manifestProperties);
}
/**
* RJCTODO
*
* @return
*/
public Path getFilePath() {
return Paths.get(this.filePath);
}
/**
* RJCTODO
*
* @return
* @throws IOException
*/
public Date getDateFileCreated() {
return this.dateFileCreated;
}
/**
* RJCTODO
*
* @return
*/
public String getCaseName() {
return caseName;
}
/**
* RJCTODO
*
* @return
*/
public String getDeviceId() {
return deviceId;
}
/**
* RJCTODO
*
* @return
*/
public Path getDataSourcePath() {
return Paths.get(dataSourcePath);
}
/**
* RJCTODO
* @return
*/
public String getDataSourceFileName() {
return Paths.get(dataSourcePath).getFileName().toString();
}
/**
* RJCTODO
*
* @return
*/
public Map<String, String> getManifestProperties() {
return new HashMap<>(manifestProperties);
}

View File

@ -20,17 +20,11 @@ package org.sleuthkit.autopsy.experimental.autoingest;
import java.nio.file.Path;
/**
* RJCTODO:
*/
public interface ManifestFileParser {
boolean fileIsManifest(Path filePath);
Manifest parse(Path filePath) throws ManifestFileParserException;
/**
* Exception thrown if a manifest file cannot be parsed. RJCTODO
*/
public final static class ManifestFileParserException extends Exception {
private static final long serialVersionUID = 1L;

View File

@ -99,9 +99,6 @@ final class ManifestNodeData {
*
* @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() {
return this.coordSvcNodeDataWasSet;
}

View File

@ -69,7 +69,7 @@ final class PathUtils {
*
* @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());
if (!searchFolder.isDirectory()) {
return Collections.emptyList();
@ -135,7 +135,7 @@ final class PathUtils {
*
* @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();
return Paths.get(caseFoldersPath.toString(), folderName);
}

View File

@ -31,7 +31,7 @@ import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.math.NumberUtils;
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.UNCPathUtilities;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;

View File

@ -26,7 +26,7 @@ import java.util.List;
import java.util.logging.Level;
import org.apache.commons.lang.math.NumberUtils;
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.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;

View File

@ -30,7 +30,7 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.openide.util.lookup.ServiceProviders;
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.MessageNotifyUtil;
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
@ -55,6 +55,14 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
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
public void indexArtifact(BlackboardArtifact artifact) throws TskCoreException {
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.
* Closes the connection upon exit. Throws if it cannot communicate with
* Solr.
* Tries to connect to the keyword search service.
*
* When issues occur, it attempts to diagnose them by looking at the
* exception messages, returning the appropriate user-facing text for the
* 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
* @param host The hostname or IP address of the service.
* @param port The port used by the service.
*
* @throws KeywordSearchServiceException if cannot connect.
*/
@Override
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
public void close() throws IOException {
}