Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 2094-ExportImportFilesSets

This commit is contained in:
William Schaefer 2017-03-02 15:07:46 -05:00
commit f0ea129bde
852 changed files with 148620 additions and 6217 deletions

View File

@ -258,6 +258,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

@ -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");

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");

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");
@ -25,27 +25,37 @@ import org.openide.LifecycleManager;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* The action associated with the Case/Exit menu item. It closes the current
* case, if any, and shuts down the application.
*/
@ActionRegistration(displayName = "Exit", iconInMenu = true)
@ActionReference(path = "Menu/Case", position = 1000, separatorBefore = 999)
@ActionID(id = "org.sleuthkit.autopsy.casemodule.ExitAction", category = "Case")
final public class ExitAction implements ActionListener {
@NbBundle.Messages({
"ExitAction.confirmationDialog.title=Ingest is Running",
"ExitAction.confirmationDialog.message=Ingest is running, are you sure you want to exit?"
})
@Override
public void actionPerformed(ActionEvent e) {
try {
Case currentCase = Case.getCurrentCase();
if (currentCase != null) {
currentCase.closeCase();
}
} catch (Exception ex) {
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Had a problem closing the case.", ex); //NON-NLS
} finally {
LifecycleManager.getDefault().exit();
if (IngestRunningCheck.checkAndConfirmProceed(Bundle.ExitAction_confirmationDialog_title(), Bundle.ExitAction_confirmationDialog_message())) {
new Thread(() -> {
try {
Case.closeCurrentCase();
} catch (CaseActionException ex) {
Logger.getLogger(ExitAction.class.getName()).log(Level.SEVERE, "Error closing the current case on exit", ex); //NON-NLS
} finally {
LifecycleManager.getDefault().exit();
}
}).start();
}
}
}

View File

@ -0,0 +1,53 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.actions;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* A helper for actions that checks to see if ingest is running. If it is,
* prompts the user to confirm they want to proceed with whatever operation was
* initiated (e.g., closing the case).
*/
public class IngestRunningCheck {
/**
* Checks to see if ingest is running. If it is, prompts the user to confirm
* they want to proceed with whatever operation was initiated (e.g., closing
* the case).
*
* @param optionsDlgTitle The title for the options dialog used to confirm
* the iser's intentions.
* @param optionsDlgMessage The message for the options dialog used to
* confirm the iser's intentions.
*
* @return True to proceed, false otherwise.
*/
public static boolean checkAndConfirmProceed(String optionsDlgTitle, String optionsDlgMessage) {
if (IngestManager.getInstance().isIngestRunning()) {
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
optionsDlgMessage,
optionsDlgTitle,
NotifyDescriptor.YES_NO_OPTION,
NotifyDescriptor.WARNING_MESSAGE);
descriptor.setValue(NotifyDescriptor.NO_OPTION);
Object response = DialogDisplayer.getDefault().notify(descriptor);
return (DialogDescriptor.YES_OPTION == response);
} else {
return true;
}
}
/**
* Private contructor to prevent instantiation of a utility class.
*/
private IngestRunningCheck() {
}
}

View File

@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014-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");
* 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.
@ -18,9 +18,9 @@
*/
package org.sleuthkit.autopsy.actions;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
@ -35,37 +35,58 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Action in menu to open the folder containing the log files
* The action associated with the Help/Open Log Folder menu item. It opens a
* file explorer window for either the log subdirectory for the currently open
* case, or the log subdirectory of the user directory, if there is no current
* case.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionRegistration(
displayName = "#CTL_OpenLogFolder", iconInMenu = true)
@ActionRegistration(displayName = "#CTL_OpenLogFolder", iconInMenu = true)
@ActionReference(path = "Menu/Help", position = 1750)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenLogFolderAction", category = "Help")
public final class OpenLogFolderAction implements ActionListener {
private static final Logger logger = Logger.getLogger(OpenLogFolderAction.class.getName());
@Override
public void actionPerformed(ActionEvent e) {
try {
File logDir;
if (Case.isCaseOpen()) {
logDir = new File(Case.getCurrentCase().getLogDirectoryPath());
} else {
File logDir;
if (Case.isCaseOpen()) {
try {
/*
* Open the log directory for the case.
*/
Case currentCase = Case.getCurrentCase();
logDir = new File(currentCase.getLogDirectoryPath());
} catch (IllegalStateException ex) {
/*
* There is no open case, open the application level log
* directory.
*/
logDir = new File(Places.getUserDirectory().getAbsolutePath() + File.separator + "var" + File.separator + "log");
}
if (logDir.exists() == false) {
NotifyDescriptor d
= new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenLogFolder.error1", logDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(d);
} else {
} else {
logDir = new File(Places.getUserDirectory().getAbsolutePath() + File.separator + "var" + File.separator + "log");
}
try {
if (logDir.exists()) {
Desktop.getDesktop().open(logDir);
} else {
logger.log(Level.SEVERE, String.format("The log directory %s does not exist", logDir));
NotifyDescriptor notifyDescriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenLogFolder.error1", logDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDescriptor);
}
} catch (IOException ex) {
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "OpenLogFolder.CouldNotOpenLogFolder"), ex); //NON-NLS
logger.log(Level.SEVERE, String.format("Could not open log directory %s", logDir), ex);
NotifyDescriptor notifyDescriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenLogFolder.CouldNotOpenLogFolder", logDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDescriptor);
}
}
}

View File

@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
* 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.
@ -35,37 +35,45 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Action in menu to open the folder containing the output files
* The action associated with the Tools/Open Output Folder menu item. It opens a
* file explorer window for the root output directory for the currently open
* case. If the case is a single-user case, this is the case directory. If the
* case is a multi-user case, this is a subdirectory of the case directory
* specific to the host machine.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionRegistration(
displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy=true)
@ActionRegistration(displayName = "#CTL_OpenOutputFolder", iconInMenu = true, lazy = false)
@ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenOutputFolderAction", category = "Help")
public final class OpenOutputFolderAction extends CallableSystemAction {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(OpenOutputFolderAction.class.getName());
@Override
public void performAction() {
File outputDir;
try {
File outputDir;
if (Case.isCaseOpen()) {
outputDir = new File(Case.getCurrentCase().getOutputDirectory());
if (outputDir.exists() == false) {
NotifyDescriptor d
= new NotifyDescriptor.Message(NbBundle.getMessage(this.getClass(),
"OpenOutputFolder.error1", outputDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(d);
} else {
Case currentCase = Case.getCurrentCase();
outputDir = new File(currentCase.getOutputDirectory());
if (outputDir.exists()) {
try {
Desktop.getDesktop().open(outputDir);
} catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Failed to open output folder %s", outputDir), ex); //NON-NLS
NotifyDescriptor descriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(descriptor);
}
} else {
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "OpenOutputFolder.noCaseOpen"));
NotifyDescriptor descriptor = new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenOutputFolder.error1", outputDir.getAbsolutePath()), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(descriptor);
}
} catch (IOException ex) {
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "OpenOutputFolder.CouldNotOpenOutputFolder"), ex); //NON-NLS
} catch (IllegalStateException ex) {
logger.log(Level.SEVERE, "OpenOutputFolderAction enabled with no current case", ex); //NON-NLS
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(), "OpenOutputFolder.noCaseOpen"));
}
}
@ -81,8 +89,9 @@ public final class OpenOutputFolderAction extends CallableSystemAction {
@Override
public boolean asynchronous() {
return false; // run on edt
return false;
}
@Override
public String getName() {
return NbBundle.getMessage(OpenOutputFolderAction.class, "CTL_OpenOutputFolder");

View File

@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
* 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.
@ -29,23 +29,24 @@ import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
@ActionID(
category = "Help",
id = "org.sleuthkit.autopsy.actions.ShowIngestProgressSnapshotAction"
)
@ActionRegistration(
displayName = "#CTL_ShowIngestProgressSnapshotAction",
lazy = false
)
/**
* The action associated with the Help/Get Ingest Progress Snapshot menu item.
* It opens a the Ingest Progress Snapshot dialog.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionID(category = "Help", id = "org.sleuthkit.autopsy.actions.ShowIngestProgressSnapshotAction")
@ActionRegistration(displayName = "#CTL_ShowIngestProgressSnapshotAction", lazy = false)
@ActionReference(path = "Menu/Help", position = 1125)
@Messages("CTL_ShowIngestProgressSnapshotAction=Ingest Status Details")
public final class ShowIngestProgressSnapshotAction extends CallableSystemAction implements ActionListener {
private static final String ACTION_NAME = NbBundle.getMessage(ShowIngestProgressSnapshotAction.class, "ShowIngestProgressSnapshotAction.actionName.text");
private static final long serialVersionUID = 1L;
@Override
public void performAction() {
IngestProgressSnapshotDialog dialog = new IngestProgressSnapshotDialog();
new IngestProgressSnapshotDialog();
}
@Override
@ -65,6 +66,6 @@ public final class ShowIngestProgressSnapshotAction extends CallableSystemAction
@Override
public boolean asynchronous() {
return false; // run on edt
return false;
}
}

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");
@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
@ -28,7 +29,6 @@ import java.util.logging.Level;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -44,26 +44,26 @@ import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.Image;
/**
* The action to add an image to the current Case. This action should be
* disabled on creation and it will be enabled on new case creation or case
* opened.
* An action that invokes the Add Data Source wizard.
*
* @author jantonius
* This action should only be invoked in the event dispatch thread (EDT).
*/
// TODO: need annotation because there's a "Lookup.getDefault().lookup(AddImageAction.class)"
// used in AddImageWizardPanel1 (among other places). It really shouldn't be done like that.
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.AddImageAction")
@ActionRegistration(displayName = "#CTL_AddImage", lazy = false)
@ActionReferences(value = {
@ActionReference(path = "Toolbars/Case", position = 100)})
@ActionReferences(value = {@ActionReference(path = "Toolbars/Case", position = 100)})
@ServiceProvider(service = AddImageAction.class)
public final class AddImageAction extends CallableSystemAction implements Presenter.Toolbar {
private static final long serialVersionUID = 1L;
private static final Dimension SIZE = new Dimension(875, 550);
private final ChangeSupport cleanupSupport = new ChangeSupport(this);
// Keys into the WizardDescriptor properties that pass information between stages of the wizard
// <TYPE>: <DESCRIPTION>
// String: time zone that the image is from
@ -84,15 +84,13 @@ public final class AddImageAction extends CallableSystemAction implements Presen
static final String NOFATORPHANS_PROP = "nofatorphans"; //NON-NLS
static final Logger logger = Logger.getLogger(AddImageAction.class.getName());
static final Dimension SIZE = new Dimension(875, 550);
private WizardDescriptor wizardDescriptor;
private WizardDescriptor.Iterator<WizardDescriptor> iterator;
private Dialog dialog;
private JButton toolbarButton = new JButton();
private final JButton toolbarButton = new JButton();
/**
* The constructor for AddImageAction class
* Constructs an action that invokes the Add Data Source wizard.
*/
public AddImageAction() {
putValue(Action.NAME, NbBundle.getMessage(AddImageAction.class, "CTL_AddImage")); // set the action Name
@ -106,44 +104,39 @@ public final class AddImageAction extends CallableSystemAction implements Presen
}
});
this.setEnabled(false); // disable this action class
/*
* Disable this action until a case is opened. Currently, the Case class
* enables the action.
*/
this.setEnabled(false);
}
/**
* Pop-up the "Add Image" wizard panel.
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
if (IngestManager.getInstance().isIngestRunning()) {
final String msg = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg");
if (JOptionPane.showConfirmDialog(null, msg,
NbBundle.getMessage(this.getClass(),
"AddImageAction.ingestConfig.ongoingIngest.title"),
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
return;
String optionsDlgTitle = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.title");
String optionsDlgMessage = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg");
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
iterator = new AddImageWizardIterator(this);
wizardDescriptor = new WizardDescriptor(iterator);
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "AddImageAction.wizard.title"));
wizardDescriptor.putProperty(NAME, e);
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
if (dialog != null) {
dialog.setVisible(false); // hide the old one
}
dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
Dimension d = dialog.getSize();
dialog.setSize(SIZE);
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
dialog.setVisible(true);
dialog.toFront();
// Do any cleanup that needs to happen (potentially: stopping the
//add-image process, reverting an image)
runCleanupTasks();
}
iterator = new AddImageWizardIterator(this);
wizardDescriptor = new WizardDescriptor(iterator);
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "AddImageAction.wizard.title"));
wizardDescriptor.putProperty(NAME, e);
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
if (dialog != null) {
dialog.setVisible(false); // hide the old one
}
dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
Dimension d = dialog.getSize();
dialog.setSize(SIZE);
dialog.setVisible(true);
dialog.toFront();
// Do any cleanup that needs to happen (potentially: stopping the
//add-image process, reverting an image)
runCleanupTasks();
}
/**
@ -172,12 +165,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
void runTask(Image newImage);
}
/**
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
* instead of this method.
*/
@Override
public void performAction() {
actionPerformed(null);
}
/**
@ -191,9 +181,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
}
/**
* Gets the HelpCtx associated with implementing object
* Gets the help context for this action.
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
* @return The help context.
*/
@Override
public HelpCtx getHelpCtx() {
@ -201,9 +191,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
}
/**
* Returns the toolbar component of this action
* Gets the toolbar component for this action.
*
* @return component the toolbar button
* @return The toolbar button
*/
@Override
public Component getToolbarPresenter() {
@ -214,7 +204,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
}
/**
* Set this action to be enabled/disabled
* Enables and disables this action.
*
* @param value whether to enable this action or not
*/
@ -236,8 +226,8 @@ public final class AddImageAction extends CallableSystemAction implements Presen
public void requestFocusButton(String buttonText) {
// get all buttons on this wizard panel
Object[] wizardButtons = wizardDescriptor.getOptions();
for (int i = 0; i < wizardButtons.length; i++) {
JButton tempButton = (JButton) wizardButtons[i];
for (Object wizardButton : wizardButtons) {
JButton tempButton = (JButton) wizardButton;
if (tempButton.getText().equals(buttonText)) {
tempButton.setDefaultCapable(true);
tempButton.requestFocus();
@ -254,8 +244,6 @@ public final class AddImageAction extends CallableSystemAction implements Presen
cleanupSupport.fireChange();
}
ChangeSupport cleanupSupport = new ChangeSupport(this);
/**
* Instances of this class implement the cleanup() method to run cleanup
* code when the wizard exits.

View File

@ -15,12 +15,6 @@ NewCaseVisualPanel1.caseNameTextField.text_1=
NewCaseVisualPanel1.jLabel2.text_1=Case data will be stored in the following directory:
NewCaseVisualPanel1.caseParentDirTextField.text=
NewCaseVisualPanel1.caseDirTextField.text_1=
CasePropertiesForm.caseDirLabel.text=Case Directory:
CasePropertiesForm.crDateLabel.text=Created Date:
CasePropertiesForm.caseNameLabel.text=Case Name:
CasePropertiesForm.caseNameTextField.text=
CasePropertiesForm.updateCaseNameButton.text=Update Name
CasePropertiesForm.deleteCaseButton.text=Delete Case
CueBannerPanel.autopsyLogo.text=
CueBannerPanel.createNewLabel.text=Create New Case
CueBannerPanel.openLabel.text=Open Existing Case
@ -31,8 +25,6 @@ CueBannerPanel.openCaseButton.text=
CueBannerPanel.openRecentButton.text=
OpenRecentCasePanel.cancelButton.text=Cancel
OpenRecentCasePanel.jLabel1.text=Recent Cases
CasePropertiesForm.caseNumberLabel.text=Case Number:
CasePropertiesForm.examinerLabel.text=Examiner:
NewCaseVisualPanel2.caseNumberTextField.text=
NewCaseVisualPanel2.examinerLabel.text=Examiner:
NewCaseVisualPanel2.caseNumberLabel.text=Case Number:
@ -98,12 +90,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 +102,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.
@ -133,7 +119,6 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type
Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted.
Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}
Case.exception.errorLocking=Unable to open case being updated by another user.
CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\
Case Name\: {0}\n\
Case Directory\: {1}
@ -225,8 +210,6 @@ NewCaseVisualPanel1.caseParentDirWarningLabel.text=
NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user
NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user
NewCaseVisualPanel1.caseTypeLabel.text=Case Type:
CasePropertiesForm.lbDbType.text=Case Type:
CasePropertiesForm.lbDbName.text=Database Name:
SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
SingleUserCaseConverter.AlreadyMultiUser=Case is already multi-user!
SingleUserCaseConverter.NonUniqueDatabaseName=Database name not unique.
@ -241,3 +224,13 @@ LocalFilesPanel.displayNameLabel.text=Logical File Set Display Name: Default
IngestJobInfoPanel.jLabel1.text=Ingest Modules
IngestJobInfoPanel.jLabel2.text=Ingest Jobs
CaseInformationPanel.closeButton.text=Close
CasePropertiesPanel.updateCaseNameButton.text=Update Name
CasePropertiesPanel.caseNameTextField.text=
CasePropertiesPanel.caseDirLabel.text=Case Directory:
CasePropertiesPanel.crDateLabel.text=Created Date:
CasePropertiesPanel.caseNameLabel.text=Case Name:
CasePropertiesPanel.lbDbName.text=Database Name:
CasePropertiesPanel.lbDbType.text=Case Type:
CasePropertiesPanel.examinerLabel.text=Examiner:
CasePropertiesPanel.caseNumberLabel.text=Case Number:
CasePropertiesPanel.deleteCaseButton.text=Delete Case

View File

@ -1,4 +1,3 @@
CTL_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...
@ -12,19 +11,12 @@ NewCaseVisualPanel1.caseNameLabel.text_1=\u30b1\u30fc\u30b9\u540d\uff1a
NewCaseVisualPanel1.caseDirLabel.text=\u30d9\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\uff1a
NewCaseVisualPanel1.caseDirBrowseButton.text=\u95b2\u89a7
NewCaseVisualPanel1.jLabel2.text_1=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u306f\u6b21\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u4fdd\u5b58\u3055\u308c\u307e\u3059\uff1a
CasePropertiesForm.caseDirLabel.text=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\uff1a
CasePropertiesForm.crDateLabel.text=\u4f5c\u6210\u65e5\uff1a
CasePropertiesForm.caseNameLabel.text=\u30b1\u30fc\u30b9\u540d\uff1a
CasePropertiesForm.updateCaseNameButton.text=\u66f4\u65b0
CasePropertiesForm.deleteCaseButton.text=\u30b1\u30fc\u30b9\u3092\u524a\u9664
CueBannerPanel.createNewLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u6210
CueBannerPanel.openLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.closeButton.text=\u9589\u3058\u308b
CueBannerPanel.openRecentLabel.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
OpenRecentCasePanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
OpenRecentCasePanel.jLabel1.text=\u6700\u8fd1\u958b\u3044\u305f\u30d5\u30a1\u30a4\u30eb
CasePropertiesForm.caseNumberLabel.text=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
CasePropertiesForm.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
NewCaseVisualPanel2.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
NewCaseVisualPanel2.caseNumberLabel.text=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
NewCaseVisualPanel2.optionalLabel.text=\u30aa\u30d7\u30b7\u30e7\u30ca\u30eb\uff1a\u30b1\u30fc\u30b9\u756a\u53f7\u304a\u3088\u3073\u8abf\u67fb\u62c5\u5f53\u8005\u3092\u8a2d\u5b9a
@ -80,21 +72,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
@ -203,8 +189,6 @@ CollaborationMonitor.addingDataSourceStatus.msg={0}\u304c\u30c7\u30fc\u30bf\u30d
CollaborationMonitor.analyzingDataSourceStatus.msg={0}\u304c{1}\u3092\u89e3\u6790\u4e2d
NewCaseVisualPanel1.multiUserCaseRadioButton.text=\u8907\u6570\u30e6\u30fc\u30b6\u30fc
NewCaseVisualPanel1.singleUserCaseRadioButton.text=\u5358\u6570\u30e6\u30fc\u30b6\u30fc
CasePropertiesForm.lbDbType.text=\u30b1\u30fc\u30b9\u30bf\u30a4\u30d7\uff1a
CasePropertiesForm.lbDbName.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\uff1a
SingleUserCaseConverter.BadDatabaseFileName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\uff01
SingleUserCaseConverter.AlreadyMultiUser=\u30b1\u30fc\u30b9\u306f\u65e2\u306b\u8907\u6570\u30e6\u30fc\u30b6\u30fc\u3067\u3059\uff01
SingleUserCaseConverter.NonUniqueDatabaseName=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\u304c\u30e6\u30cb\u30fc\u30af\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
@ -216,3 +200,12 @@ Case_caseType_multiUser=\u8907\u6570\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9
Case_caseType_singleUser=\u5358\u6570\u30e6\u30fc\u30b6\u30fc\u30b1\u30fc\u30b9
CasePropertiesForm.imagesTable.columnModel.title0=\u30d1\u30b9
CasePropertiesForm.imagesTable.columnModel.title1=\u524a\u9664
CasePropertiesPanel.updateCaseNameButton.text=\u66f4\u65b0
CasePropertiesPanel.caseDirLabel.text=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\uff1a
CasePropertiesPanel.crDateLabel.text=\u4f5c\u6210\u65e5\uff1a
CasePropertiesPanel.caseNameLabel.text=\u30b1\u30fc\u30b9\u540d\uff1a
CasePropertiesPanel.lbDbName.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u540d\uff1a
CasePropertiesPanel.lbDbType.text=\u30b1\u30fc\u30b9\u30bf\u30a4\u30d7\uff1a
CasePropertiesPanel.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
CasePropertiesPanel.caseNumberLabel.text=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
CasePropertiesPanel.deleteCaseButton.text=\u30b1\u30fc\u30b9\u3092\u524a\u9664

File diff suppressed because it is too large Load Diff

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");
@ -19,31 +19,33 @@
package org.sleuthkit.autopsy.casemodule;
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;
import javax.swing.SwingWorker;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import java.util.logging.Level;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.windows.WindowManager;
import java.awt.Cursor;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionRegistration;
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.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
/**
* The action to close the current Case. This class should be disabled on
* creation and it will be enabled on new case creation or case opened.
* The action associated with the Case/Close Case menu item and the Close Case
* toolbar button. It closes the current case and pops up the start up window
* that allows a user to open another case.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.casemodule.CaseCloseAction")
@ActionRegistration(displayName = "#CTL_CaseCloseAct", lazy = false)
@ -51,87 +53,69 @@ import org.openide.awt.ActionRegistration;
@ActionReference(path = "Toolbars/Case", position = 104)})
public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar {
JButton toolbarButton = new JButton();
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(CaseCloseAction.class.getName());
private final JButton toolbarButton = new JButton();
/**
* The constructor for this class
* Constructs the action associated with the Case/Close Case menu item and
* the Close Case toolbar button.
*/
public CaseCloseAction() {
putValue("iconBase", "org/sleuthkit/autopsy/images/close-icon.png"); // put the icon NON-NLS
putValue(Action.NAME, NbBundle.getMessage(CaseCloseAction.class, "CTL_CaseCloseAct")); // put the action Name
// set action of the toolbar button
putValue("iconBase", "org/sleuthkit/autopsy/images/close-icon.png"); //NON-NLS
putValue(Action.NAME, NbBundle.getMessage(CaseCloseAction.class, "CTL_CaseCloseAct")); //NON-NLS
toolbarButton.addActionListener(CaseCloseAction.this::actionPerformed);
this.setEnabled(false);
}
/**
* Closes the current opened case.
* Closes the current case.
*
* @param e the action event for this method
* @param e The action event.
*/
@Override
public void actionPerformed(ActionEvent e) {
String optionsDlgTitle = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title");
String optionsDlgMessage = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning");
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
new SwingWorker<Void, Void>() {
// if ingest is ongoing, warn and get confirmaion before opening a different case
if (IngestManager.getInstance().isIngestRunning()) {
// show the confirmation first to close the current case and open the "New Case" wizard panel
String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning");
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(closeCurrentCase,
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
descriptor.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(descriptor);
if (res != null && res == DialogDescriptor.YES_OPTION) {
try {
Case.getCurrentCase().closeCase(); // close the current case
} catch (Exception ex) {
Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.WARNING, "Error closing case.", ex); //NON-NLS
@Override
protected Void doInBackground() throws Exception {
Case.closeCurrentCase();
return null;
}
} else {
return;
}
}
if (Case.isCaseOpen() == false) {
return;
}
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
try {
Case result = Case.getCurrentCase();
result.closeCase();
} catch (CaseActionException | IllegalStateException unused) {
// Already logged.
@Override
protected void done() {
try {
get();
} catch (InterruptedException ex) {
logger.log(Level.SEVERE, "Unexpected interrupt closing the current case", ex);
} catch (ExecutionException ex) {
logger.log(Level.SEVERE, "Error closing the current case", ex);
MessageNotifyUtil.Message.error(Bundle.Case_closeException_couldNotCloseCase(ex.getMessage()));
}
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
StartupWindowProvider.getInstance().open();
}
return null;
}
@Override
protected void done() {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
StartupWindowProvider.getInstance().open();
}
}.execute();
}.execute();
}
}
/**
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
* instead of this method.
* Closes the current case.
*/
@Override
public void performAction() {
actionPerformed(null);
}
/**
* Gets the name of this action. This may be presented as an item in a menu.
* Gets the action name.
*
* @return actionName
* @return The action name.
*/
@Override
public String getName() {
@ -139,9 +123,9 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
}
/**
* Gets the HelpCtx associated with implementing object
* Gets the help context.
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
* @return The help context.
*/
@Override
public HelpCtx getHelpCtx() {
@ -149,9 +133,9 @@ public final class CaseCloseAction extends CallableSystemAction implements Prese
}
/**
* Returns the toolbar component of this action
* Returns the toolbar component of this action.
*
* @return component the toolbar button
* @return The toolbar button
*/
@Override
public Component getToolbarPresenter() {

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");
@ -19,138 +19,106 @@
package org.sleuthkit.autopsy.casemodule;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
/**
* The action to delete the current Case. This class should be disabled on
* creation and it will be enabled on new case creation or case opened.
* The action associated with the Delete button of the Case Properties panel. It
* deletes the current case.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
final class CaseDeleteAction extends CallableSystemAction {
private JPanel caller; // for error handling
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(CaseDeleteAction.class.getName());
/**
* The constructor for this class
*/
public CaseDeleteAction() {
putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction")); // put the action Name
CaseDeleteAction() {
putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction"));
this.setEnabled(false);
}
/**
* Deletes the current opened case.
*
* @param e
*/
@Override
@Messages({
"Case.deleteCaseConfirmationDialog.title=Delete Current Case?",
"Case.deleteCaseConfirmationDialog.message=Are you sure you want to close and delete the current case?",
"Case.deleteCaseFailureMessageBox.title=Failed to Delete Case",
"# {0} - exception message", "Case.deleteCaseFailureMessageBox.message=Error deleting case: {0}",})
public void actionPerformed(ActionEvent e) {
Case currentCase = Case.getCurrentCase();
File caseFolder = new File(currentCase.getCaseDirectory());
String caseName = currentCase.getName();
if (!caseFolder.exists()) {
// throw an error
try {
Case currentCase = Case.getCurrentCase();
String caseName = currentCase.getName();
String caseDirectory = currentCase.getCaseDirectory();
logger.log(Level.WARNING, "Couldn't delete case.", new Exception("The case directory doesn't exist.")); //NON-NLS
} else {
// show the confirmation first to close the current case and open the "New Case" wizard panel
String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CaseDeleteAction.closeConfMsg.text", caseName, caseFolder.getPath());
NotifyDescriptor d = new NotifyDescriptor.Confirmation(closeCurrentCase,
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.closeConfMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
/*
* Do a confirmation dialog and close the current case if the user
* confirms he/she wants to proceed.
*/
Object response = DialogDisplayer.getDefault().notify(new NotifyDescriptor(
Bundle.Case_deleteCaseConfirmationDialog_message(),
Bundle.Case_deleteCaseConfirmationDialog_title(),
NotifyDescriptor.YES_NO_OPTION,
NotifyDescriptor.WARNING_MESSAGE,
null,
NotifyDescriptor.NO_OPTION));
if (null != response && DialogDescriptor.YES_OPTION == response) {
Object res = DialogDisplayer.getDefault().notify(d);
if (res != null && res == DialogDescriptor.YES_OPTION) {
boolean success = false;
new SwingWorker<Void, Void>() {
try {
Case.getCurrentCase().deleteCase(caseFolder); // delete the current case
success = true;
} catch (CaseActionException ex) {
logger.log(Level.WARNING, "Could not delete the case folder: " + caseFolder); //NON-NLS
}
@Override
protected Void doInBackground() throws Exception {
Case.deleteCurrentCase();
return null;
}
// show notification whether the case has been deleted or it failed to delete...
if (!success) {
JOptionPane.showMessageDialog(caller,
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.fileInUse.msg"),
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.fileInUse.title"),
JOptionPane.ERROR_MESSAGE); // throw an error
} else {
CasePropertiesAction.closeCasePropertiesWindow(); // because the "Delete Case" button is in the "CaseProperties" window, we have to close that window when we delete the case.
JOptionPane.showMessageDialog(caller, NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.caseDelete.msg",
caseName));
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException | ExecutionException 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);
}
/*
* Close the Case Properties dialog that is the parent
* of the Delete button that invokes this action.
*/
CasePropertiesAction.closeCasePropertiesWindow();
}
}.execute();
}
} catch (IllegalStateException ex) {
logger.log(Level.SEVERE, "Case delete action called with no current case", ex);
}
}
/**
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
* instead of this method.
*/
@Override
public void performAction() {
// Note: I use the actionPerformed above instead of this method
}
/**
* Gets the name of this action. This may be presented as an item in a menu.
*
* @return actionName
*/
@Override
public String getName() {
return NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction");
}
/**
* Gets the HelpCtx associated with implementing object
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
*/
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
}

View File

@ -54,7 +54,7 @@ class CaseInformationPanel extends javax.swing.JPanel {
// put the image paths information into hashmap
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
CasePropertiesForm cpf = new CasePropertiesForm(currentCase, crDate, caseDir, imgPaths);
CasePropertiesPanel cpf = new CasePropertiesPanel(currentCase, crDate, caseDir, imgPaths);
cpf.setSize(cpf.getPreferredSize());
this.tabbedPane.addTab(Bundle.CaseInformationPanel_caseDetails_header(), cpf);
this.tabbedPane.addTab(Bundle.CaseInformationPanel_ingestJobInfo_header(), new IngestJobInfoPanel());

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");
@ -54,10 +54,11 @@ public final class CaseMetadata {
private static final String FILE_EXTENSION = ".aut";
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
private static final String SCHEMA_VERSION_ONE = "1.0";
private final static String AUTOPSY_CREATED_VERSION_ELEMENT_NAME = "AutopsyCreatedVersion"; //NON-NLS
private static final String SCHEMA_VERSION_TWO = "2.0";
private final static String AUTOPSY_VERSION_ELEMENT_NAME = "AutopsyCreatedVersion"; //NON-NLS
private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS
private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS
private static final String CURRENT_SCHEMA_VERSION = "2.0";
private static final String CURRENT_SCHEMA_VERSION = "3.0";
private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS
private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS
private final static String CREATED_DATE_ELEMENT_NAME = "CreatedDate"; //NON-NLS
@ -66,6 +67,7 @@ public final class CaseMetadata {
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
private final static String CASE_ELEMENT_NAME = "Case"; //NON-NLS
private final static String CASE_NAME_ELEMENT_NAME = "Name"; //NON-NLS
private final static String CASE_DISPLAY_NAME_ELEMENT_NAME = "DisplayName"; //NON-NLS
private final static String CASE_NUMBER_ELEMENT_NAME = "Number"; //NON-NLS
private final static String EXAMINER_ELEMENT_NAME = "Examiner"; //NON-NLS
private final static String CASE_TYPE_ELEMENT_NAME = "CaseType"; //NON-NLS
@ -74,9 +76,10 @@ public final class CaseMetadata {
private final Path metadataFilePath;
private Case.CaseType caseType;
private String caseName;
private String caseDisplayName;
private String caseNumber;
private String examiner;
private String caseDatabase;
private String caseDatabaseName;
private String textIndexName;
private String createdDate;
private String createdByVersion;
@ -94,27 +97,28 @@ public final class CaseMetadata {
* Constructs an object that provides access to the case metadata stored in
* a new case metadata file that is created using the supplied metadata.
*
* @param caseDirectory The case directory.
* @param caseType The type of case.
* @param caseName The name of the case.
* @param caseNumber The case number.
* @param examiner The name of the case examiner.
* @param caseDatabase For a single-user case, the full path to the
* case database file. For a multi-user case, the
* case database name.
* @param caseTextIndexName The text index name.
* @param caseDirectory The case directory.
* @param caseType The type of case.
* @param caseName The immutable name of the case.
* @param caseDisplayName The display name of the case, can be changed by a
* user.
* @param caseNumber The case number.
* @param examiner The name of the case examiner.
* @param caseDatabase For a single-user case, the full path to the case
* database file. For a multi-user case, the case
* database name.
*
* @throws CaseMetadataException If the new case metadata file cannot be
* created.
*/
CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseNumber, String examiner, String caseDatabase, String caseTextIndexName) throws CaseMetadataException {
CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseDisplayName, String caseNumber, String examiner, String caseDatabase) throws CaseMetadataException {
metadataFilePath = Paths.get(caseDirectory, caseName + FILE_EXTENSION);
this.caseType = caseType;
this.caseName = caseName;
this.caseDisplayName = caseDisplayName;
this.caseNumber = caseNumber;
this.examiner = examiner;
this.caseDatabase = caseDatabase;
this.textIndexName = caseTextIndexName;
this.caseDatabaseName = caseDatabase;
createdByVersion = Version.getVersion();
createdDate = CaseMetadata.DATE_FORMAT.format(new Date());
writeToFile();
@ -162,7 +166,7 @@ public final class CaseMetadata {
}
/**
* Gets the case display name.
* Gets the immutable case name, set at case creation.
*
* @return The case display name.
*/
@ -170,19 +174,28 @@ public final class CaseMetadata {
return caseName;
}
/**
* Gets the case display name.
*
* @return The case display name.
*/
public String getCaseDisplayName() {
return this.caseDisplayName;
}
/**
* 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.
*/
void setCaseName(String caseName) throws CaseMetadataException {
void setCaseDisplayName(String caseName) throws CaseMetadataException {
String oldCaseName = caseName;
this.caseName = caseName;
this.caseDisplayName = caseName;
try {
writeToFile();
} catch (CaseMetadataException ex) {
this.caseName = oldCaseName;
this.caseDisplayName = oldCaseName;
throw ex;
}
}
@ -206,31 +219,27 @@ public final class CaseMetadata {
}
/**
* Gets the name of the case case database.
* Gets the name of the case database.
*
* @return The case database name.
*/
public String getCaseDatabaseName() {
if (caseType == Case.CaseType.MULTI_USER_CASE) {
return caseDatabase;
} else {
return Paths.get(caseDatabase).getFileName().toString();
}
return caseDatabaseName;
}
/**
* Gets the full path to the case database file if the case is a single-user
* case.
* Sets the text index name.
*
* @return The full path to the case database file for a single-user case.
*
* @throws UnsupportedOperationException If called for a multi-user case.
* @param caseTextIndexName The text index name.
*/
public String getCaseDatabasePath() throws UnsupportedOperationException {
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
return caseDatabase;
} else {
throw new UnsupportedOperationException();
void setTextIndexName(String caseTextIndexName) throws CaseMetadataException {
String oldIndexName = caseTextIndexName;
this.textIndexName = caseTextIndexName;
try {
writeToFile();
} catch (CaseMetadataException ex) {
this.textIndexName = oldIndexName;
throw ex;
}
}
@ -355,10 +364,11 @@ public final class CaseMetadata {
* Create the children of the case element.
*/
createChildElement(doc, caseElement, CASE_NAME_ELEMENT_NAME, caseName);
createChildElement(doc, caseElement, CASE_DISPLAY_NAME_ELEMENT_NAME, caseDisplayName);
createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseNumber);
createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, examiner);
createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString());
createChildElement(doc, caseElement, CASE_DATABASE_ELEMENT_NAME, caseDatabase);
createChildElement(doc, caseElement, CASE_DATABASE_ELEMENT_NAME, caseDatabaseName);
createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName);
}
@ -402,7 +412,7 @@ public final class CaseMetadata {
String schemaVersion = getElementTextContent(rootElement, SCHEMA_VERSION_ELEMENT_NAME, true);
this.createdDate = getElementTextContent(rootElement, CREATED_DATE_ELEMENT_NAME, true);
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_CREATED_VERSION_ELEMENT_NAME, true);
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_VERSION_ELEMENT_NAME, true);
} else {
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_CREATED_BY_ELEMENT_NAME, true);
}
@ -416,6 +426,11 @@ public final class CaseMetadata {
}
Element caseElement = (Element) caseElements.item(0);
this.caseName = getElementTextContent(caseElement, CASE_NAME_ELEMENT_NAME, true);
if (schemaVersion.equals(SCHEMA_VERSION_ONE) || schemaVersion.equals(SCHEMA_VERSION_TWO)) {
this.caseDisplayName = caseName;
} else {
this.caseDisplayName = getElementTextContent(caseElement, CASE_DISPLAY_NAME_ELEMENT_NAME, true);
}
this.caseNumber = getElementTextContent(caseElement, CASE_NUMBER_ELEMENT_NAME, false);
this.examiner = getElementTextContent(caseElement, EXAMINER_ELEMENT_NAME, false);
this.caseType = Case.CaseType.fromString(getElementTextContent(caseElement, CASE_TYPE_ELEMENT_NAME, true));
@ -423,11 +438,21 @@ public final class CaseMetadata {
throw new CaseMetadataException("Case metadata file corrupted");
}
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
this.caseDatabase = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
} else {
this.caseDatabase = getElementTextContent(caseElement, CASE_DATABASE_ELEMENT_NAME, true);
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, true);
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_ELEMENT_NAME, true);
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
}
/*
* Fix up the case database name due to a bug that for a time caused
* the absolute paths of single-user case databases to be stored.
*/
Path possibleAbsoluteCaseDbPath = Paths.get(this.caseDatabaseName);
if (possibleAbsoluteCaseDbPath.getNameCount() > 1) {
Path caseDirectoryPath = Paths.get(getCaseDirectory());
this.caseDatabaseName = caseDirectoryPath.relativize(possibleAbsoluteCaseDbPath).toString();
}
/*
@ -483,4 +508,22 @@ public final class CaseMetadata {
}
}
/**
* Gets the full path to the case database file if the case is a single-user
* case.
*
* @return The full path to the case database file for a single-user case.
*
* @throws UnsupportedOperationException If called for a multi-user case.
* @deprecated
*/
@Deprecated
public String getCaseDatabasePath() throws UnsupportedOperationException {
if (Case.CaseType.SINGLE_USER_CASE == caseType) {
return Paths.get(getCaseDirectory(), caseDatabaseName).toString();
} else {
throw new UnsupportedOperationException();
}
}
}

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");
@ -26,27 +26,25 @@ import org.openide.util.actions.SystemAction;
import org.openide.util.lookup.ServiceProvider;
/**
* The action to create a new case. This action class is always enabled.
*
* @author jantonius
* The action associated with the Case/New Case menu item and the Create New
* Case button of the start up window that allows a user to open a case. It
* invokes the New Case wizard.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ServiceProvider(service = CaseNewActionInterface.class)
public final class CaseNewAction extends CallableSystemAction implements CaseNewActionInterface {
private NewCaseWizardAction wizard = SystemAction.get(NewCaseWizardAction.class);
private static final long serialVersionUID = 1L;
/**
* Calls the "New Case" wizard panel action.
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
wizard.performAction();
SystemAction.get(NewCaseWizardAction.class).performAction();
}
@Override
public void performAction() {
actionPerformed(null);
}
@Override

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");
@ -22,39 +22,45 @@ import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.Version;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.sleuthkit.autopsy.coreutils.Logger;
import java.util.logging.Level;
import org.openide.util.HelpCtx;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* An action that opens an existing case.
* The action associated with the Case/Open Case menu item via the layer.xml
* file, a toolbar button, and the Create New Case button of the start up window
* that allows a user to open a case. It opens an existing case.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ServiceProvider(service = CaseOpenAction.class)
public final class CaseOpenAction extends CallableSystemAction implements ActionListener {
private static final Logger logger = Logger.getLogger(CaseOpenAction.class.getName());
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
private static final long serialVersionUID = 1L;
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
private static final Logger logger = Logger.getLogger(CaseOpenAction.class.getName());
private final JFileChooser fileChooser = new JFileChooser();
private final FileFilter caseMetadataFileFilter;
/**
* Constructs an action that opens an existing case.
* Constructs the action associated with the Case/Open Case menu item via
* the layer.xml file, a toolbar button, and the Create New Case button of
* the start up window that allows a user to open a case. It opens an
* existing case.
*
*/
public CaseOpenAction() {
caseMetadataFileFilter = new FileNameExtensionFilter(NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(), CaseMetadata.getFileExtension()), CaseMetadata.getFileExtension().substring(1));
@ -75,77 +81,60 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
*/
@Override
public void actionPerformed(ActionEvent e) {
/*
* If ingest is running, do a dialog to warn the user and confirm the
* intent to close the current case and leave the ingest process
* incomplete.
*/
if (IngestManager.getInstance().isIngestRunning()) {
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning"),
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
descriptor.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(descriptor);
if (res != null && res == DialogDescriptor.YES_OPTION) {
Case currentCase = null;
try {
currentCase = Case.getCurrentCase();
currentCase.closeCase();
} catch (IllegalStateException ignored) {
/*
* No current case.
*/
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error closing case at %s while ingest was running", (null != currentCase ? currentCase.getCaseDirectory() : "?")), ex); //NON-NLS
}
} else {
return;
}
}
/**
* Pop up a file chooser to allow the user to select a case meta data
* file (.aut file).
*/
int retval = fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow());
if (retval == JFileChooser.APPROVE_OPTION) {
/*
* Close the startup window, if it is open.
String optionsDlgTitle = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title");
String optionsDlgMessage = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning");
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
/**
* Pop up a file chooser to allow the user to select a case metadata
* file (.aut file).
*/
StartupWindowProvider.getInstance().close();
int retval = fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow());
if (retval == JFileChooser.APPROVE_OPTION) {
/*
* Close the startup window, if it is open.
*/
StartupWindowProvider.getInstance().close();
/*
* Try to open the case associated with the case metadata file the
* user selected.
*/
final String path = fileChooser.getSelectedFile().getPath();
String dirPath = fileChooser.getSelectedFile().getParent();
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator)));
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
new Thread(() -> {
try {
Case.open(path);
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
SwingUtilities.invokeLater(() -> {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
JOptionPane.showMessageDialog(
WindowManager.getDefault().getMainWindow(),
ex.getMessage(), // Should be user-friendly
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
JOptionPane.ERROR_MESSAGE);
if (!Case.isCaseOpen()) {
/*
* Try to open the case associated with the case metadata file
* the user selected.
*/
final String path = fileChooser.getSelectedFile().getPath();
String dirPath = fileChooser.getSelectedFile().getParent();
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator)));
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
Case.openAsCurrentCase(path);
return null;
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
JOptionPane.showMessageDialog(
WindowManager.getDefault().getMainWindow(),
ex.getMessage(),
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
JOptionPane.ERROR_MESSAGE);
StartupWindowProvider.getInstance().open();
}
});
}
}).start();
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}.execute();
}
}
}
@Override
public void performAction() {
actionPerformed(null);
}
@Override

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");
@ -23,98 +23,70 @@ import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* The action to pop up the Case Properties Form window. By using this form,
* user can update the case properties (for example: updates the case name and
* removes the image from the current case)
*
* @author jantonius
* The action associated with the Case/Case Properties menu item. It invokes the
* Case Properties dialog.
*/
final class CasePropertiesAction extends CallableSystemAction {
private static JDialog popUpWindow;
private static final long serialVersionUID = 1L;
private static JDialog casePropertiesDialog;
/**
* The CasePropertiesAction constructor
*/
CasePropertiesAction() {
putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction")); // put the action Name
putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction"));
this.setEnabled(false);
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
popUpWindow = null;
setEnabled(null != evt.getNewValue());
}
});
}
/**
* Pop-up the Case Properties Form window where user can change the case
* properties (example: update case name and remove the image from the case)
*/
@Override
public void performAction() {
if (popUpWindow == null) {
// create the popUp window for it
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
popUpWindow = new JDialog((JFrame) WindowManager.getDefault().getMainWindow(), title, false);
try {
SwingUtilities.invokeLater(() -> {
if (null == casePropertiesDialog) {
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
casePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), title, false);
CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
caseInformationPanel.addCloseButtonAction((ActionEvent e) -> {
popUpWindow.dispose();
casePropertiesDialog.setVisible(false);
});
casePropertiesDialog.add(caseInformationPanel);
casePropertiesDialog.setResizable(true);
casePropertiesDialog.pack();
popUpWindow.add(caseInformationPanel);
popUpWindow.setResizable(true);
popUpWindow.pack();
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double w = popUpWindow.getSize().getWidth();
double h = popUpWindow.getSize().getHeight();
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
popUpWindow.setVisible(true);
} catch (Exception ex) {
Logger.getLogger(CasePropertiesAction.class.getName()).log(Level.WARNING, "Error displaying Case Properties window.", ex); //NON-NLS
double w = casePropertiesDialog.getSize().getWidth();
double h = casePropertiesDialog.getSize().getHeight();
casePropertiesDialog.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
casePropertiesDialog.setVisible(true);
}
}
popUpWindow.setVisible(true);
popUpWindow.toFront();
casePropertiesDialog.setVisible(true);
casePropertiesDialog.toFront();
});
}
/**
* Gets the name of this action. This may be presented as an item in a menu.
*
* @return actionName
*/
@Override
public String getName() {
return NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction");
}
/**
* Gets the HelpCtx associated with implementing object
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
*/
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
static void closeCasePropertiesWindow() {
popUpWindow.dispose();
casePropertiesDialog.setVisible(false);
}
}

View File

@ -161,7 +161,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -173,7 +173,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.crDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.crDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -185,7 +185,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -197,12 +197,9 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="caseNameTextFieldActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="updateCaseNameButton">
<Properties>
@ -212,7 +209,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.updateCaseNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.updateCaseNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
@ -227,7 +224,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.deleteCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.deleteCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
@ -242,7 +239,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -254,7 +251,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.examinerLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.examinerLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -266,7 +263,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.lbDbType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.lbDbType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -278,7 +275,7 @@
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.lbDbName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.lbDbName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>

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");
@ -17,14 +17,9 @@
* limitations under the License.
*/
/*
* CasePropertiesForm.java
*
* Created on Mar 14, 2011, 1:48:20 PM
*/
package org.sleuthkit.autopsy.casemodule;
import java.io.File;
import java.nio.file.Paths;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.JOptionPane;
@ -37,55 +32,26 @@ import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* The form where user can change / update the properties of the current case
* metadata.
* A panel that allows the user to view various properties of the current case
* and change the display name of the case.
*/
class CasePropertiesForm extends javax.swing.JPanel {
class CasePropertiesPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private Case current = null;
private static JPanel caller; // panel for error
// Shrink a path to fit in targetLength (if necessary), by replaceing part
// of the path with "...". Ex: "C:\Users\bob\...\folder\other\Image.img"
private String shrinkPath(String path, int targetLength) {
if (path.length() > targetLength) {
String fill = "...";
int partsLength = targetLength - fill.length();
String front = path.substring(0, partsLength / 4);
int frontSep = front.lastIndexOf(File.separatorChar);
if (frontSep != -1) {
front = front.substring(0, frontSep + 1);
}
String back = path.substring(partsLength * 3 / 4);
int backSep = back.indexOf(File.separatorChar);
if (backSep != -1) {
back = back.substring(backSep);
}
return back + fill + front;
} else {
return path;
}
}
/**
* Creates new form CasePropertiesForm
*/
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
CasePropertiesPanel(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");
@ -93,10 +59,10 @@ class CasePropertiesForm extends javax.swing.JPanel {
crDateField.setText(crDate);
caseDirField.setText(caseDir);
current = currentCase;
CaseMetadata caseMetadata = currentCase.getCaseMetadata();
if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) {
dbNameField.setText(caseMetadata.getCaseDatabasePath());
dbNameField.setText(Paths.get(caseMetadata.getCaseDirectory(), caseMetadata.getCaseDatabaseName()).toString());
} else {
dbNameField.setText(caseMetadata.getCaseDatabaseName());
}
@ -152,24 +118,19 @@ class CasePropertiesForm extends javax.swing.JPanel {
jScrollPane1.setViewportView(jTextArea1);
caseNameLabel.setFont(caseNameLabel.getFont().deriveFont(caseNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNameLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameLabel.text")); // NOI18N
caseNameLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.caseNameLabel.text")); // NOI18N
crDateLabel.setFont(crDateLabel.getFont().deriveFont(crDateLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
crDateLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.crDateLabel.text")); // NOI18N
crDateLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.crDateLabel.text")); // NOI18N
caseDirLabel.setFont(caseDirLabel.getFont().deriveFont(caseDirLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseDirLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseDirLabel.text")); // NOI18N
caseDirLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.caseDirLabel.text")); // NOI18N
caseNameTextField.setFont(caseNameTextField.getFont().deriveFont(caseNameTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNameTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameTextField.text")); // NOI18N
caseNameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
caseNameTextFieldActionPerformed(evt);
}
});
caseNameTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.caseNameTextField.text")); // NOI18N
updateCaseNameButton.setFont(updateCaseNameButton.getFont().deriveFont(updateCaseNameButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
updateCaseNameButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.updateCaseNameButton.text")); // NOI18N
updateCaseNameButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.updateCaseNameButton.text")); // NOI18N
updateCaseNameButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
updateCaseNameButtonActionPerformed(evt);
@ -177,7 +138,7 @@ class CasePropertiesForm extends javax.swing.JPanel {
});
deleteCaseButton.setFont(deleteCaseButton.getFont().deriveFont(deleteCaseButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
deleteCaseButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.deleteCaseButton.text")); // NOI18N
deleteCaseButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.deleteCaseButton.text")); // NOI18N
deleteCaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deleteCaseButtonActionPerformed(evt);
@ -185,16 +146,16 @@ class CasePropertiesForm extends javax.swing.JPanel {
});
caseNumberLabel.setFont(caseNumberLabel.getFont().deriveFont(caseNumberLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
caseNumberLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNumberLabel.text")); // NOI18N
caseNumberLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.caseNumberLabel.text")); // NOI18N
examinerLabel.setFont(examinerLabel.getFont().deriveFont(examinerLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
examinerLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.examinerLabel.text")); // NOI18N
examinerLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.examinerLabel.text")); // NOI18N
lbDbType.setFont(lbDbType.getFont().deriveFont(lbDbType.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
lbDbType.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.lbDbType.text")); // NOI18N
lbDbType.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbDbType.text")); // NOI18N
lbDbName.setFont(lbDbName.getFont().deriveFont(lbDbName.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
lbDbName.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.lbDbName.text")); // NOI18N
lbDbName.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbDbName.text")); // NOI18N
caseDirField.setMinimumSize(new java.awt.Dimension(25, 14));
@ -303,13 +264,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"),
@ -318,34 +279,36 @@ class CasePropertiesForm extends javax.swing.JPanel {
JOptionPane.ERROR_MESSAGE);
} else // check if case Name contain one of this following symbol:
// \ / : * ? " < > |
if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":")
|| newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"")
|| newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) {
String errorMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg");
JOptionPane.showMessageDialog(caller, errorMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
JOptionPane.ERROR_MESSAGE);
} else {
// ask for the confirmation first
String confMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName,
newCaseName);
NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if (res != null && res == DialogDescriptor.YES_OPTION) {
// if user select "Yes"
String oldPath = current.getCaseMetadata().getFilePath().toString();
try {
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
} catch (Exception ex) {
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
{
if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":")
|| newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"")
|| newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) {
String errorMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg");
JOptionPane.showMessageDialog(caller, errorMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
JOptionPane.ERROR_MESSAGE);
} else {
// ask for the confirmation first
String confMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName,
newCaseName);
NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if (res != null && res == DialogDescriptor.YES_OPTION) {
// if user select "Yes"
String oldPath = current.getCaseMetadata().getFilePath().toString();
try {
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
} catch (CaseActionException ex) {
Logger.getLogger(CasePropertiesPanel.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
}
}
}
}
@ -356,10 +319,6 @@ class CasePropertiesForm extends javax.swing.JPanel {
CallableSystemAction.get(CaseDeleteAction.class).actionPerformed(evt);
}//GEN-LAST:event_deleteCaseButtonActionPerformed
private void caseNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseNameTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_caseNameTextFieldActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel caseDirField;

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

@ -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");
@ -18,34 +18,41 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.*;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
/**
*
/*
* The panel in the default Autopsy startup window.
*/
public class CueBannerPanel extends javax.swing.JPanel {
final private static String title = NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.title.text");
final private static JFrame frame = new JFrame(title);
final static JDialog recentCasesWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
private static final long serialVersionUID = 1L;
/*
* This is field is static for the sake of the closeOpenRecentCasesWindow
* method.
*/
private static JDialog recentCasesWindow;
// for error handling
private static JPanel caller = new JPanel();
public static void closeOpenRecentCasesWindow() {
if (null != recentCasesWindow) {
recentCasesWindow.setVisible(false);
}
}
public CueBannerPanel() {
initComponents();
refresh();
customizeComponents();
enableComponents();
}
public CueBannerPanel(String welcomeLogo) {
@ -55,7 +62,53 @@ public class CueBannerPanel extends javax.swing.JPanel {
ImageIcon icon = new ImageIcon(cl.getResource(welcomeLogo));
autopsyLogo.setIcon(icon);
}
refresh();
customizeComponents();
enableComponents();
}
public void setCloseButtonActionListener(ActionListener e) {
closeButton.addActionListener(e);
}
public void setCloseButtonText(String text) {
closeButton.setText(text);
}
public void refresh() {
enableComponents();
}
private void customizeComponents() {
recentCasesWindow = new JDialog(
WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.title.text"),
Dialog.ModalityType.APPLICATION_MODAL);
recentCasesWindow.setSize(new Dimension(750, 400));
recentCasesWindow.getRootPane().registerKeyboardAction(
e -> {
recentCasesWindow.setVisible(false);
},
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
OpenRecentCasePanel recentCasesPanel = OpenRecentCasePanel.getInstance();
recentCasesPanel.setCloseButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
recentCasesWindow.setVisible(false);
}
});
recentCasesWindow.add(recentCasesPanel);
recentCasesWindow.pack();
recentCasesWindow.setResizable(false);
}
private void enableComponents() {
if (RecentCases.getInstance().getTotalRecentCases() == 0) {
openRecentButton.setEnabled(false);
openRecentLabel.setEnabled(false);
} else {
openRecentButton.setEnabled(true);
openRecentLabel.setEnabled(true);
}
}
/**
@ -180,15 +233,6 @@ public class CueBannerPanel extends javax.swing.JPanel {
);
}// </editor-fold>//GEN-END:initComponents
public void refresh() {
if (RecentCases.getInstance().getTotalRecentCases() == 0) {
openRecentButton.setEnabled(false);
openRecentLabel.setEnabled(false);
} else {
openRecentButton.setEnabled(true);
openRecentLabel.setEnabled(true);
}
}
private void newCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newCaseButtonActionPerformed
Lookup.getDefault().lookup(CaseNewActionInterface.class).actionPerformed(evt);
}//GEN-LAST:event_newCaseButtonActionPerformed
@ -198,37 +242,8 @@ public class CueBannerPanel extends javax.swing.JPanel {
}//GEN-LAST:event_openCaseButtonActionPerformed
private void openRecentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRecentButtonActionPerformed
// open the recent cases dialog
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
recentCasesWindow.setSize(750, 400);
int w = recentCasesWindow.getSize().width;
int h = recentCasesWindow.getSize().height;
// set the location of the popUp Window on the center of the screen
recentCasesWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
recentCasesWindow.setLocationRelativeTo(this);
recentCasesWindow.getRootPane().registerKeyboardAction(e -> {
recentCasesWindow.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
OpenRecentCasePanel welcomeWindow = OpenRecentCasePanel.getInstance();
// add the command to close the window to the button on the Volume Detail Panel
welcomeWindow.setCloseButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
recentCasesWindow.dispose();
}
});
recentCasesWindow.add(welcomeWindow);
recentCasesWindow.pack();
recentCasesWindow.setResizable(false);
recentCasesWindow.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
recentCasesWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
OpenRecentCasePanel.getInstance(); //refreshes the recent cases table
recentCasesWindow.setVisible(true);
}//GEN-LAST:event_openRecentButtonActionPerformed
@ -244,29 +259,4 @@ public class CueBannerPanel extends javax.swing.JPanel {
private javax.swing.JLabel openRecentLabel;
// End of variables declaration//GEN-END:variables
/**
* Sets the Close button action listener.
*
* @param e the action listener
*/
public void setCloseButtonActionListener(ActionListener e) {
closeButton.addActionListener(e);
}
/**
* Sets the Close button label (default is "Close").
*
* @param text The new label for the button.
*/
public void setCloseButtonText(String text) {
closeButton.setText(text);
}
/**
* Close the open recent cases window.
*/
public static void closeOpenRecentCasesWindow() {
//startupWindow.setVisible(false);
recentCasesWindow.dispose();
}
}

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

@ -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,31 +19,33 @@
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dialog;
import java.io.File;
import java.text.MessageFormat;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.SwingUtilities;
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;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.SystemAction;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JOptionPane;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.openide.windows.WindowManager;
import java.awt.Cursor;
import java.util.concurrent.ExecutionException;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* An action that creates and runs the new case wizard.
* The action associated with the Case/New Case menu item, t toolbar button, and
* the button in the start up window that allows users to open cases action. It
* runs first the New Case wizard, then the Add Data Source wizard.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
final class NewCaseWizardAction extends CallableSystemAction {
@ -53,39 +55,15 @@ final class NewCaseWizardAction extends CallableSystemAction {
@Override
public void performAction() {
/*
* If ingest is running, do a dialog to warn the user and confirm the
* intent to close the current case and leave the ingest process
* incomplete.
*/
if (IngestManager.getInstance().isIngestRunning()) {
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning"),
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
descriptor.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(descriptor);
if (res != null && res == DialogDescriptor.YES_OPTION) {
Case currentCase = null;
try {
currentCase = Case.getCurrentCase();
currentCase.closeCase();
} catch (IllegalStateException ignored) {
/*
* No current case.
*/
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error closing case at %s while ingest was running", (null != currentCase ? currentCase.getCaseDirectory() : "?")), ex); //NON-NLS
}
} else {
return;
}
String optionsDlgTitle = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title");
String optionsDlgMessage = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning");
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
runNewCaseWizard();
}
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
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"));
@ -101,7 +79,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.create(createdDirectory, caseName, caseNumber, examiner, caseType);
Case.createAsCurrentCase(createdDirectory, caseName, caseNumber, examiner, caseType);
return null;
}
@ -109,26 +87,29 @@ final class NewCaseWizardAction extends CallableSystemAction {
protected void done() {
try {
get();
/*
* Run the Add Data Source wizard by invoking the Add
* Data Source wizard.
*/
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
addImageAction.actionPerformed(null);
} catch (Exception ex) {
} 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?
if (!Case.isCaseOpen()) {
StartupWindowProvider.getInstance().open();
}
});
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();
StartupWindowProvider.getInstance().open();
doFailedCaseCleanup(wizardDescriptor);
} finally {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}.execute();
} else {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
new Thread(() -> {
doFailedCaseCleanup(wizardDescriptor);
}).start();
@ -138,11 +119,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

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 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");
@ -23,9 +23,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.DialogDescriptor;
@ -34,7 +31,10 @@ import org.openide.NotifyDescriptor;
import org.openide.WizardDescriptor;
import org.openide.WizardValidationException;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/**
@ -101,7 +101,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
// fireChangeEvent();
// and uncomment the complicated stuff below.
}
private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
/**
* Adds a listener to changes of the panel's validity.
@ -134,7 +134,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
protected final void fireChangeEvent() {
Iterator<ChangeListener> it;
synchronized (listeners) {
it = new HashSet<ChangeListener>(listeners).iterator();
it = new HashSet<>(listeners).iterator();
}
ChangeEvent ev = new ChangeEvent(this);
while (it.hasNext()) {
@ -167,15 +167,15 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
*/
@Override
public void readSettings(WizardDescriptor settings) {
NewCaseVisualPanel1 component = getComponent();
NewCaseVisualPanel1 panel = getComponent();
try {
String lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE);
component.setCaseParentDir(lastBaseDirectory);
component.readSettings();
panel.setCaseParentDir(lastBaseDirectory);
panel.readSettings();
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));
if (createdDirectory != null && !createdDirectory.isEmpty()) {
logger.log(Level.INFO, "Deleting a case dir in readSettings(): {0}", createdDirectory); //NON-NLS
FileUtil.deleteDir(new File(createdDirectory));
}
} catch (Exception e) {
logger.log(Level.WARNING, "Could not read wizard settings in NewCaseWizardPanel1, ", e); //NON-NLS
@ -242,7 +242,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
// if user says yes
try {
createDirectory(caseDirPath, getComponent().getCaseType());
} catch (Exception ex) {
} catch (WizardValidationException ex) {
String errorMsg = NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg",
caseParentDir);
@ -259,7 +259,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
} else {
try {
createDirectory(caseDirPath, getComponent().getCaseType());
} catch (Exception ex) {
} catch (WizardValidationException ex) {
String errorMsg = NbBundle
.getMessage(this.getClass(), "NewCaseWizardPanel1.validate.errMsg.cantCreateDir");
logger.log(Level.WARNING, errorMsg, ex);
@ -298,7 +298,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(),
@ -316,7 +316,6 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
logger.log(Level.WARNING, "Startup window didn't close as expected.", ex); //NON-NLS
}
}
}
}

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");
@ -27,9 +27,8 @@ import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.openide.windows.WindowManager;
import java.awt.Cursor;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Panel used by the the open recent case option of the start window.
@ -103,7 +102,7 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
}
final String casePath = casePaths[imagesTable.getSelectedRow()];
final String caseName = caseNames[imagesTable.getSelectedRow()];
if (!casePath.equals("")) {
if (!casePath.isEmpty()) {
try {
StartupWindowProvider.getInstance().close();
CueBannerPanel.closeOpenRecentCasesWindow();
@ -114,34 +113,26 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
/*
* Open the case.
*/
if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
if (caseName.isEmpty() || casePath.isEmpty() || (!new File(casePath).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, casePath); // remove the recent case if it doesn't exist anymore
if (Case.isCaseOpen() == false) {
StartupWindowProvider.getInstance().open();
}
StartupWindowProvider.getInstance().open();
} else {
SwingUtilities.invokeLater(() -> {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
});
new Thread(() -> {
try {
Case.open(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(() -> {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", casePath), 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(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
JOptionPane.ERROR_MESSAGE);
if (!Case.isCaseOpen()) {
StartupWindowProvider.getInstance().open();
}
JOptionPane.ERROR_MESSAGE);
StartupWindowProvider.getInstance().open();
});
}
}).start();
@ -160,7 +151,7 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
public int getRowCount() {
int count = 0;
for (String s : caseNames) {
if (!s.equals("")) {
if (!s.isEmpty()) {
count++;
}
}

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));
@ -175,7 +174,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
* @return true if the case exists, false otherwise
*/
boolean exists() {
return !(name.equals("") || path.equals("") || !new File(path).exists());
return !(name.isEmpty() || path.isEmpty() || !new File(path).exists());
}
// netbeans autogenerated hashCode
@ -211,7 +210,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
* exist.
*/
private void refreshRecentCases() {
List<RecentCase> toDelete = new ArrayList<RecentCase>();
List<RecentCase> toDelete = new ArrayList<>();
for (RecentCase rc : recentCases) {
if (!rc.exists()) {
toDelete.add(rc);
@ -256,14 +255,14 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
*/
@Override
public void actionPerformed(ActionEvent e) {
UpdateRecentCases.hasRecentCase = false;
UpdateRecentCases.setHasRecentCase(false);
recentCases.clear();
try {
// clear the properties file
storeRecentCases();
} catch (Exception ex) {
} catch (IOException ex) {
Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not clear the properties file.", ex); //NON-NLS
}
}
@ -297,7 +296,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
try {
storeRecentCases();
} catch (Exception ex) {
} catch (IOException ex) {
Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex); //NON-NLS
}
}
@ -325,7 +324,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
try {
storeRecentCases();
} catch (Exception ex) {
} catch (IOException ex) {
Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex); //NON-NLS
}
}
@ -357,7 +356,7 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
// write the properties file
try {
storeRecentCases();
} catch (Exception ex) {
} catch (IOException ex) {
Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex); //NON-NLS
}
}
@ -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

@ -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");
@ -18,111 +18,61 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import java.awt.Cursor;
import java.util.logging.Level;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* An action listener that opens a recent case.
* An action listener for a specific case, associated with a Recent Cases menu
* item for the case by a DynamicMenuContent content JMenuItem.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
class RecentItems implements ActionListener {
private static final Logger logger = Logger.getLogger(RecentItems.class.getName());
private final String caseName;
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.
*/
public RecentItems(String caseName, String caseMetaDataFilePath) {
this.caseName = caseName;
RecentItems(String caseName, String caseMetaDataFilePath) {
this.caseMetaDataFilePath = caseMetaDataFilePath;
}
/**
* Opens the recent case.
* Opens the case associated with the action.
*
* @param e the action event
*/
@Override
public void actionPerformed(ActionEvent e) {
/*
* If ingest is running, do a dialog to warn the user and confirm the
* intent to close the current case and leave the ingest process
* incomplete.
*/
if (IngestManager.getInstance().isIngestRunning()) {
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning"),
NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
descriptor.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(descriptor);
if (res != null && res == DialogDescriptor.YES_OPTION) {
Case currentCase = null;
try {
currentCase = Case.getCurrentCase();
currentCase.closeCase();
} catch (IllegalStateException ignored) {
/*
* No current case.
*/
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error closing case at %s while ingest was running", (null!= currentCase ? currentCase.getCaseDirectory() : "?")),ex); //NON-NLS
}
} else {
return;
}
}
/*
* Open the case.
*/
if (caseName.equals("") || caseMetaDataFilePath.equals("") || (!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);
if (Case.isCaseOpen() == false) {
EventQueue.invokeLater(() -> {
StartupWindowProvider.getInstance().open();
});
}
} else {
SwingUtilities.invokeLater(() -> {
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
});
String optionsDlgTitle = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning.title");
String optionsDlgMessage = NbBundle.getMessage(Case.class, "CloseCaseWhileIngesting.Warning");
if (IngestRunningCheck.checkAndConfirmProceed(optionsDlgTitle, optionsDlgMessage)) {
new Thread(() -> {
try {
Case.open(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
SwingUtilities.invokeLater(() -> {
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
ex.getMessage(),
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
JOptionPane.ERROR_MESSAGE);
if (!Case.isCaseOpen()) {
StartupWindowProvider.getInstance().open();
}
StartupWindowProvider.getInstance().open();
});
}
}).start();

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
@ -34,19 +34,21 @@ import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import static org.sleuthkit.autopsy.casemodule.Case.MODULE_FOLDER;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.core.UserPreferencesException;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.datamodel.TskData;
/**
* Import a case from single-user to multi-user.
*
* DO NOT USE, NEEDS TO BE UPDATED
*/
public class SingleUserCaseConverter {
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
@ -176,7 +178,6 @@ public class SingleUserCaseConverter {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss"); //NON-NLS
Date date = new Date();
String dbName = Case.sanitizeCaseName(icd.getNewCaseName()) + "_" + dateFormat.format(date); //NON-NLS
String solrName = dbName;
icd.setPostgreSQLDbName(dbName);
// Copy items to new hostname folder structure
@ -195,9 +196,10 @@ public class SingleUserCaseConverter {
CaseMetadata newCaseMetadata = new CaseMetadata(icd.getCaseOutputFolder().toString(),
CaseType.MULTI_USER_CASE,
icd.getNewCaseName(),
icd.getNewCaseName(),
oldCaseMetadata.getCaseNumber(),
oldCaseMetadata.getExaminer(),
dbName, solrName);
dbName);
// Set created date. This calls writefile, no need to call it again
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
newCaseMetadata.setCreatedByVersion(oldCaseMetadata.getCreatedByVersion());

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");
@ -18,51 +18,43 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
* This class enables capturing errors and batching them for reporting on a
* no-more-than-x number of seconds basis. When created, you specify the minimum
* time between user notifications. When the time between notifications has
* expired, the next error encountered will cause a report to be shown to the
* user.
* Acts as a bridge between the Sleuthkit Java bindings classes and Autopsy by
* implementing the SleuthkitCase$ErrorObserver interface. All errors are
* written to the Autopsy logs. If a GUI is running, errors are also batched up
* and reported periodically to the user via the notification area in the lower
* right hand corner of the main application window.
*/
class IntervalErrorReportData {
class SleuthkitErrorReporter implements SleuthkitCase.ErrorObserver {
private final Case currentCase;
private static final Logger LOGGER = Logger.getLogger(SleuthkitErrorReporter.class.getName());
private final int milliSecondsBetweenReports;
private final String message;
private long newProblems;
private long totalProblems;
private long lastReportedDate;
private final int milliSecondsBetweenReports;
private final String message;
/**
* Create a new IntervalErrorReprotData instance and subscribe for TSK error
* notifications for the current case.
*
* @param currentCase Case for which TSK errors should be tracked
* and displayed.
* @param secondsBetweenReports Minimum number of seconds between reports.
* It will not warn more frequently than this.
* @param message The message that will be shown when warning
* the user
* the user.
*/
IntervalErrorReportData(Case currentCase, int secondsBetweenReports, String message) {
SleuthkitErrorReporter(int secondsBetweenReports, String message) {
this.newProblems = 0;
this.totalProblems = 0;
this.lastReportedDate = 0; // arm the first warning by choosing zero
this.milliSecondsBetweenReports = secondsBetweenReports * 1000; // convert to milliseconds
this.message = message;
this.currentCase = currentCase;
this.currentCase.getSleuthkitCase().addErrorObserver(this.currentCase);
}
/**
* Un-subscribe from TSK error notifications for current case.
*/
void shutdown() {
this.currentCase.getSleuthkitCase().removeErrorObserver(this.currentCase);
}
/**
@ -73,18 +65,19 @@ class IntervalErrorReportData {
* @param context The context in which the error occurred.
* @param errorMessage A description of the error that occurred.
*/
void addProblems(String context, String errorMessage) {
@Override
public void receiveError(String context, String errorMessage) {
LOGGER.log(Level.SEVERE, String.format("%s error in the SleuthKit layer: %s", context, errorMessage));
this.newProblems += 1;
this.totalProblems += newProblems;
long currentTimeStamp = System.currentTimeMillis();
if ((currentTimeStamp - lastReportedDate) > milliSecondsBetweenReports) {
this.lastReportedDate = currentTimeStamp;
MessageNotifyUtil.Notify.error(message, context + ", " + errorMessage + " "
+ this.newProblems + " "
+ NbBundle.getMessage(IntervalErrorReportData.class, "IntervalErrorReport.NewIssues")
+ NbBundle.getMessage(SleuthkitErrorReporter.class, "IntervalErrorReport.NewIssues")
+ " " + this.totalProblems + " "
+ NbBundle.getMessage(IntervalErrorReportData.class, "IntervalErrorReport.TotalIssues")
+ NbBundle.getMessage(SleuthkitErrorReporter.class, "IntervalErrorReport.TotalIssues")
+ ".");
this.newProblems = 0;
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 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,25 +19,22 @@
package org.sleuthkit.autopsy.casemodule;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.WindowManager;
/**
* The default implementation of the Autopsy startup window
* The default implementation of the Autopsy startup window.
*/
@ServiceProvider(service = StartupWindowInterface.class)
public final class StartupWindow extends JDialog implements StartupWindowInterface {
private static StartupWindow instance;
private static final long serialVersionUID = 1L;
private static final String TITLE = NbBundle.getMessage(StartupWindow.class, "StartupWindow.title.text");
private static Dimension DIMENSIONS = new Dimension(750, 400);
private static final Dimension DIMENSIONS = new Dimension(750, 400);
private static CueBannerPanel welcomeWindow;
public StartupWindow() {
@ -45,37 +42,18 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
init();
}
/**
* Shows the startup window.
*/
private void init() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
setSize(DIMENSIONS);
int w = this.getSize().width;
int h = this.getSize().height;
// set the location of the popUp Window on the center of the screen
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
welcomeWindow = new CueBannerPanel();
// add the command to close the window to the button on the Volume Detail Panel
welcomeWindow.setCloseButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
close();
}
});
add(welcomeWindow);
pack();
setResizable(false);
}
@Override
@ -85,9 +63,6 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
setVisible(true);
}
/**
* Closes the startup window.
*/
@Override
public void close() {
this.setVisible(false);

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,17 +30,22 @@ 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;
}
/**
* Creates main menu/popup menu items. Null values will be later replaced by
* JSeparators. This method is called for popups and for menus. It's called
@ -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

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
@ -18,129 +18,89 @@
*/
package org.sleuthkit.autopsy.coordinationservice;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.curator.RetryPolicy;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.sleuthkit.autopsy.core.UserPreferences;
import java.io.IOException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException.NoNodeException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.sleuthkit.autopsy.core.UserPreferences;
/**
* A centralized service for maintaining configuration information and providing
* distributed synchronization using a shared hierarchical namespace of nodes.
* A coordination service for maintaining configuration information and
* providing distributed synchronization using a shared hierarchical namespace
* of nodes.
*
* TODO (JIRA 2205): Simple refactoring for general use.
*/
public final class CoordinationService {
/**
* Category nodes are the immediate children of the root node of a shared
* hierarchical namespace managed by the coordination service.
*/
public enum CategoryNode { // RJCTODO: Move this to CoordinationServiceNamespace
CASES("cases"),
MANIFESTS("manifests"),
CONFIG("config"),
RESOURCE("resource");
private final String displayName;
private CategoryNode(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}
/**
* Exception type thrown by the coordination service.
*/
public final static class CoordinationServiceException extends Exception {
private static final long serialVersionUID = 1L;
private CoordinationServiceException(String message) {
super(message);
}
private CoordinationServiceException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* An opaque encapsulation of a lock for use in distributed synchronization.
* Instances are obtained by calling a get lock method and must be passed to
* a release lock method.
*/
public static class Lock implements AutoCloseable {
/**
* This implementation uses the Curator read/write lock. see
* http://curator.apache.org/curator-recipes/shared-reentrant-read-write-lock.html
*/
private final InterProcessMutex interProcessLock;
private final String nodePath;
private Lock(String nodePath, InterProcessMutex lock) {
this.nodePath = nodePath;
this.interProcessLock = lock;
}
public String getNodePath() {
return nodePath;
}
public void release() throws CoordinationServiceException {
try {
this.interProcessLock.release();
} catch (Exception ex) {
throw new CoordinationServiceException(String.format("Failed to release the lock on %s", nodePath), ex);
}
}
@Override
public void close() throws CoordinationServiceException {
release();
}
}
private static CuratorFramework curator = null;
private static final Map<String, CoordinationService> rootNodesToServices = new HashMap<>();
private final Map<String, String> categoryNodeToPath = new HashMap<>();
private static final int SESSION_TIMEOUT_MILLISECONDS = 300000;
private static final int CONNECTION_TIMEOUT_MILLISECONDS = 300000;
private static final int ZOOKEEPER_SESSION_TIMEOUT_MILLIS = 3000;
private static final int ZOOKEEPER_CONNECTION_TIMEOUT_MILLIS = 15000;
private static final int PORT_OFFSET = 1000;
private static final int PORT_OFFSET = 1000; // When run in Solr, ZooKeeper defaults to Solr port + 1000
private final Map<String, String> categoryNodeToPath = new HashMap<>();
/**
* Gets an instance of the centralized coordination service for a specific
* namespace.
* Determines if ZooKeeper is accessible with the current settings. Closes
* the connection prior to returning.
*
* @return true if a connection was achieved, false otherwise
*
* @throws InterruptedException
* @throws IOException
*/
private static boolean isZooKeeperAccessible() throws InterruptedException, IOException {
boolean result = false;
Object workerThreadWaitNotifyLock = new Object();
int zooKeeperServerPort = Integer.valueOf(UserPreferences.getIndexingServerPort()) + PORT_OFFSET;
String connectString = UserPreferences.getIndexingServerHost() + ":" + zooKeeperServerPort;
ZooKeeper zooKeeper = new ZooKeeper(connectString, ZOOKEEPER_SESSION_TIMEOUT_MILLIS,
(WatchedEvent event) -> {
synchronized (workerThreadWaitNotifyLock) {
workerThreadWaitNotifyLock.notify();
}
});
synchronized (workerThreadWaitNotifyLock) {
workerThreadWaitNotifyLock.wait(ZOOKEEPER_CONNECTION_TIMEOUT_MILLIS);
}
ZooKeeper.States state = zooKeeper.getState();
if (state == ZooKeeper.States.CONNECTED || state == ZooKeeper.States.CONNECTEDREADONLY) {
result = true;
}
zooKeeper.close();
return result;
}
/**
* Gets a coordination service for a specific namespace.
*
* @param rootNode The name of the root node that defines the namespace.
*
* @return The service for the namespace defined by the root node name.
* @return The coordination service.
*
* @throws CoordinationServiceException If an instaNce of the coordination
* @throws CoordinationServiceException If an instance of the coordination
* service cannot be created.
*/
public static synchronized CoordinationService getInstance(String rootNode) throws CoordinationServiceException {
public static synchronized CoordinationService getServiceForNamespace(String rootNode) throws CoordinationServiceException {
/*
* Connect to ZooKeeper via Curator.
*/
if (null == curator) {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
// When run in Solr, ZooKeeper defaults to Solr port + 1000
int zooKeeperServerPort = Integer.valueOf(UserPreferences.getIndexingServerPort()) + PORT_OFFSET;
String connectString = UserPreferences.getIndexingServerHost() + ":" + zooKeeperServerPort;
curator = CuratorFrameworkFactory.newClient(connectString, SESSION_TIMEOUT_MILLISECONDS, CONNECTION_TIMEOUT_MILLISECONDS, retryPolicy);
@ -157,7 +117,7 @@ public final class CoordinationService {
CoordinationService service;
try {
service = new CoordinationService(rootNode);
} catch (Exception ex) {
} catch (IOException | InterruptedException | KeeperException | CoordinationServiceException ex) {
curator = null;
throw new CoordinationServiceException("Failed to create coordination service", ex);
}
@ -167,15 +127,18 @@ public final class CoordinationService {
}
/**
* Constructs an instance of the centralized coordination service for a
* specific namespace.
* Constructs an instance of the coordination service for a specific
* namespace.
*
* @param rootNodeName The name of the root node that defines the namespace.
*
* @throws Exception (calls Curator methods that throw Exception instead of
* more specific exceptions)
*/
private CoordinationService(String rootNodeName) throws Exception {
private CoordinationService(String rootNodeName) throws InterruptedException, IOException, KeeperException, CoordinationServiceException {
if (false == isZooKeeperAccessible()) {
throw new Exception("Unable to access ZooKeeper");
throw new CoordinationServiceException("Unable to access ZooKeeper");
}
String rootNode = rootNodeName;
@ -191,6 +154,8 @@ public final class CoordinationService {
if (ex.code() != KeeperException.Code.NODEEXISTS) {
throw ex;
}
} catch (Exception ex) {
throw new CoordinationServiceException("Curator experienced an error", ex);
}
categoryNodeToPath.put(node.getDisplayName(), nodePath);
}
@ -201,6 +166,9 @@ public final class CoordinationService {
* in the namespace managed by this coordination service. Blocks until the
* lock is obtained or the time out expires.
*
* IMPORTANT: The lock needs to be released in the same thread in which it
* is acquired.
*
* @param category The desired category in the namespace.
* @param nodePath The node path to use as the basis for the lock.
* @param timeOut Length of the time out.
@ -236,6 +204,9 @@ public final class CoordinationService {
* in the namespace managed by this coordination service. Returns
* immediately if the lock can not be acquired.
*
* IMPORTANT: The lock needs to be released in the same thread in which it
* is acquired.
*
* @param category The desired category in the namespace.
* @param nodePath The node path to use as the basis for the lock.
*
@ -262,6 +233,9 @@ public final class CoordinationService {
* the namespace managed by this coordination service. Blocks until the lock
* is obtained or the time out expires.
*
* IMPORTANT: The lock needs to be released in the same thread in which it
* is acquired.
*
* @param category The desired category in the namespace.
* @param nodePath The node path to use as the basis for the lock.
* @param timeOut Length of the time out.
@ -297,6 +271,9 @@ public final class CoordinationService {
* the namespace managed by this coordination service. Returns immediately
* if the lock can not be acquired.
*
* IMPORTANT: The lock needs to be released in the same thread in which it
* is acquired.
*
* @param category The desired category in the namespace.
* @param nodePath The node path to use as the basis for the lock.
*
@ -385,35 +362,77 @@ public final class CoordinationService {
}
/**
* Determines if ZooKeeper is accessible with the current settings. Closes
* the connection prior to returning.
*
* @return true if a connection was achieved, false otherwise
* Exception type thrown by the coordination service.
*/
private static boolean isZooKeeperAccessible() {
boolean result = false;
Object workerThreadWaitNotifyLock = new Object();
int zooKeeperServerPort = Integer.valueOf(UserPreferences.getIndexingServerPort()) + PORT_OFFSET;
String connectString = UserPreferences.getIndexingServerHost() + ":" + zooKeeperServerPort;
public final static class CoordinationServiceException extends Exception {
try {
ZooKeeper zooKeeper = new ZooKeeper(connectString, ZOOKEEPER_SESSION_TIMEOUT_MILLIS,
(WatchedEvent event) -> {
private static final long serialVersionUID = 1L;
synchronized (workerThreadWaitNotifyLock) {
workerThreadWaitNotifyLock.notify();
}
});
synchronized (workerThreadWaitNotifyLock) {
workerThreadWaitNotifyLock.wait(ZOOKEEPER_CONNECTION_TIMEOUT_MILLIS);
}
ZooKeeper.States state = zooKeeper.getState();
if (state == ZooKeeper.States.CONNECTED || state == ZooKeeper.States.CONNECTEDREADONLY) {
result = true;
}
zooKeeper.close();
} catch (InterruptedException | IOException ignored) {
private CoordinationServiceException(String message) {
super(message);
}
private CoordinationServiceException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* An opaque encapsulation of a lock for use in distributed synchronization.
* Instances are obtained by calling a get lock method and must be passed to
* a release lock method.
*/
public static class Lock implements AutoCloseable {
/**
* This implementation uses the Curator read/write lock. see
* http://curator.apache.org/curator-recipes/shared-reentrant-read-write-lock.html
*/
private final InterProcessMutex interProcessLock;
private final String nodePath;
private Lock(String nodePath, InterProcessMutex lock) {
this.nodePath = nodePath;
this.interProcessLock = lock;
}
public String getNodePath() {
return nodePath;
}
public void release() throws CoordinationServiceException {
try {
this.interProcessLock.release();
} catch (Exception ex) {
throw new CoordinationServiceException(String.format("Failed to release the lock on %s", nodePath), ex);
}
}
@Override
public void close() throws CoordinationServiceException {
release();
}
}
/**
* Category nodes are the immediate children of the root node of a shared
* hierarchical namespace managed by a coordination service.
*/
public enum CategoryNode {
CASES("cases"),
MANIFESTS("manifests"),
CONFIG("config"),
RESOURCE("resource");
private final String displayName;
private CategoryNode(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
return result;
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Copyright 2016-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -19,7 +19,7 @@
package org.sleuthkit.autopsy.coordinationservice;
/**
* Namespace elements for auto ingest coordination service nodes.
* Root node for Autopsy coordination service namespace.
*/
public final class CoordinationServiceNamespace {
private static final String ROOT = "autopsy";

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");
@ -24,46 +24,70 @@ package org.sleuthkit.autopsy.core;
*/
public class RuntimeProperties {
private static boolean coreComponentsActive = true;
private static boolean coreComponentsActiveSet = false;
private static boolean runningWithGUI = true;
private static boolean runningWithGUIFlagHasBeenSet = false;
/**
* Sets or unsets a flag indicating whether or not the core Autopsy UI
* components and user interactions with those components via menus, message
* boxes, NetBeans progress handles, etc., are enabled.
* <p>
* This flag exists as a mechanism to allow use of Autopsy as a platform
* with the core Autopsy user interface disabled, until such time as the
* user interface is made separable and optional.
* Sets or unsets a flag indicating whether or not the application is
* running with a GUI. The flag can only be set once per application
* innvocation.
*
* @param coreComponentsActive True or false.
* @param runningWithGUI True or false.
*
* @throws RuntimePropertiesException if the flag has already been set.
*/
public synchronized static void setCoreComponentsActive(boolean coreComponentsActive) {
if (!coreComponentsActiveSet) {
RuntimeProperties.coreComponentsActive = coreComponentsActive;
coreComponentsActiveSet = true;
public synchronized static void setRunningWithGUI(boolean runningWithGUI) throws RuntimePropertiesException {
if (!runningWithGUIFlagHasBeenSet) {
RuntimeProperties.runningWithGUI = runningWithGUI;
runningWithGUIFlagHasBeenSet = true;
} else {
throw new RuntimePropertiesException("The runningWithGUI flag has already been set and cannot be changed");
}
}
/**
* Gets a flag indicating whether or not the core Autopsy UI components and
* user interactions with those components via menus, message boxes,
* NetBeans progress handles, etc., are enabled.
* <p>
* This flag exists as a mechanism to allow use of Autopsy as a platform
* with the core Autopsy user interface disabled, until such time as the
* user interface is made separable and optional.
* Gets a flag indicating whether or not the application is running with a
* GUI.
*
* @return True or false.
*/
public synchronized static boolean coreComponentsAreActive() {
return coreComponentsActive;
public synchronized static boolean runningWithGUI() {
return runningWithGUI;
}
/**
* Private constructor to prevent creation of instances of this class.
*/
private RuntimeProperties() {
}
/**
* 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;
/**
* 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);
}
/**
* 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

@ -1,7 +1,7 @@
CTL_DataContentAction=DataContent
CTL_DataContentTopComponent=Data Content
CTL_CustomAboutAction=About
OptionsCategory_Name_General=Autopsy
OptionsCategory_Name_General=View
OptionsCategory_Keywords_General=Autopsy Options
HINT_DataContentTopComponent=This is a DataContent window
HINT_NodeTableTopComponent=This is a DataResult window

View File

@ -1,5 +1,4 @@
CTL_DataContentAction=\u30c7\u30fc\u30bf\u30b3\u30f3\u30c6\u30f3\u30c4
OptionsCategory_Name_General=Autopsy
OptionsCategory_Keywords_General=Autopsy\u30aa\u30d7\u30b7\u30e7\u30f3
CTL_CustomAboutAction=Autopsy\u306b\u3064\u3044\u3066
CTL_DataContentTopComponent=\u30c7\u30fc\u30bf\u30b3\u30f3\u30c6\u30f3\u30c4

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 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");
@ -22,7 +22,6 @@ import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JTabbedPane;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
@ -30,6 +29,7 @@ import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Top component that organizes all of the data content viewers. Doing a lookup
@ -42,17 +42,18 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
//@TopComponent.OpenActionRegistration(displayName = "#CTL_DataContentAction", preferredID = "DataContentTopComponent")
public final class DataContentTopComponent extends TopComponent implements DataContent {
private static Logger logger = Logger.getLogger(DataContentTopComponent.class.getName());
private static final Logger logger = Logger.getLogger(DataContentTopComponent.class.getName());
// reference to the "default" TC that always stays open
private static DataContentTopComponent defaultInstance;
private static final long serialVersionUID = 1L;
// set to true if this is the TC that always stays open and is the default place to display content
private boolean isDefault;
private final boolean isDefault;
// the content panel holding tabs with content viewers
private final DataContentPanel dataContentPanel;
// contains a list of the undocked TCs
private static ArrayList<DataContentTopComponent> newWindowList = new ArrayList<DataContentTopComponent>();
private static final ArrayList<DataContentTopComponent> newWindowList = new ArrayList<>();
private static final String PREFERRED_ID = "DataContentTopComponent"; //NON-NLS
private static final String DEFAULT_NAME = NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent");
private static final String TOOLTIP_TEXT = NbBundle.getMessage(DataContentTopComponent.class, "HINT_DataContentTopComponent");
@ -67,8 +68,8 @@ public final class DataContentTopComponent extends TopComponent implements DataC
dataContentPanel = new DataContentPanel(isDefault);
add(dataContentPanel);
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.valueOf(isDefault)); // prevent option to close compoment in GUI
logger.log(Level.INFO, "Created DataContentTopComponent instance: " + this); //NON-NLS
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, isDefault); // prevent option to close compoment in GUI
logger.log(Level.INFO, "Created DataContentTopComponent instance: {0}", this); //NON-NLS
}
/**
@ -91,24 +92,13 @@ public final class DataContentTopComponent extends TopComponent implements DataC
return dctc;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
/**
* Gets default instance. Do not use directly: reserved for *.settings files
* only, i.e. deserialization routines; otherwise you could get a
* non-deserialized defaultInstance. To obtain the singleton instance, use
* {@link #findInstance}.
* findInstance.
*
* @return
*/
public static synchronized DataContentTopComponent getDefault() {
if (defaultInstance == null) {
@ -118,8 +108,10 @@ public final class DataContentTopComponent extends TopComponent implements DataC
}
/**
* Obtain the default DataContentTopComponent defaultInstance. Never call
* {@link #getDefault} directly!
* Obtain the default DataContentTopComponent default instance. Never call
* getDefault directly!
*
* @return The default DataContentTopComponent.
*/
public static synchronized DataContentTopComponent findInstance() {
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
@ -171,7 +163,12 @@ public final class DataContentTopComponent extends TopComponent implements DataC
@Override
public boolean canClose() {
return (!this.isDefault) || !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false; // only allow this window to be closed when there's no case opened or no image in this case
/*
* If this is the main content viewers top component in the bottom of
* the main window, only it to be closed when there's no case opened or
* no data sources in the open case.
*/
return (!this.isDefault) || !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false;
}
@Override
@ -195,4 +192,18 @@ public final class DataContentTopComponent extends TopComponent implements DataC
public static List<DataContentTopComponent> getNewWindowList() {
return newWindowList;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}

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");
@ -55,7 +55,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
private ExplorerManager explorerManager;
private ExplorerManagerNodeSelectionListener emNodeSelectionListener;
private Node rootNode;
// Different DataResultsViewers
@ -276,7 +276,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!Case.isCaseOpen()) {
try {
Case.getCurrentCase();
} catch (IllegalStateException ex) {
// Handle the in-between condition when case is being closed
// and legacy selection events are pumped.
return;
@ -334,7 +336,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
explorerManager.removePropertyChangeListener(emNodeSelectionListener);
explorerManager = null;
}
// clear all set nodes
for (UpdateWrapper drv : this.viewers) {
drv.setNode(null);
@ -443,7 +445,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
@Override
public List<DataResultViewer> getViewers() {
List<DataResultViewer> ret = new ArrayList<DataResultViewer>();
List<DataResultViewer> ret = new ArrayList<>();
for (UpdateWrapper w : viewers) {
ret.add(w.getViewer());
}
@ -452,7 +454,12 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
public boolean canClose() {
return (!this.isMain) || !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false; // only allow this window to be closed when there's no case opened or no image in this case
/*
* If this is the main results panel in the main top component in the
* upper right of the main window, only allow it to be closed when
* there's no case opened or no data sources in the open case.
*/
return (!this.isMain) || !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false;
}
@Override

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 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");
@ -314,7 +314,12 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
@Override
public boolean canClose() {
return (!this.isMain) || !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false; // only allow this window to be closed when there's no case opened or no image in this case
/*
* If this is the results top component in the upper right of the main
* window, only allow it to be closed when there's no case opened or no
* data sources in the open case.
*/
return (!this.isMain) || !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false;
}
/**

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");
@ -25,6 +25,7 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import javax.swing.BorderFactory;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
@ -32,7 +33,9 @@ import org.netbeans.spi.sendopts.OptionProcessor;
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
import org.openide.modules.ModuleInstall;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
@ -50,7 +53,7 @@ public class Installer extends ModuleInstall {
private static Installer instance;
public synchronized static Installer getDefault() {
if (instance == null) {
if (null == instance) {
instance = new Installer();
}
return instance;
@ -80,21 +83,18 @@ public class Installer extends ModuleInstall {
if (processor instanceof OpenFromArguments) {
OpenFromArguments argsProcessor = (OpenFromArguments) processor;
final String caseFile = argsProcessor.getDefaultArg();
if (caseFile != null && !caseFile.equals("") && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
new Thread(() -> {
try {
Case.open(caseFile);
} catch (Exception ex) {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseFile), ex); //NON-NLS
}
}).start();
if (caseFile != null && !caseFile.isEmpty() && caseFile.endsWith(CaseMetadata.getFileExtension()) && new File(caseFile).exists()) { //NON-NLS
try {
Case.openAsCurrentCase(caseFile);
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseFile), ex); //NON-NLS
}
return;
}
}
}
StartupWindowProvider.getInstance().open();
});
}
@Override
@ -105,19 +105,10 @@ public class Installer extends ModuleInstall {
@Override
public void close() {
new Thread(() -> {
String caseDirName = null;
try {
if (Case.isCaseOpen()) {
Case currentCase = Case.getCurrentCase();
caseDirName = currentCase.getCaseDirectory();
currentCase.closeCase();
}
Case.closeCurrentCase();
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error closing case with case directory %s", (null != caseDirName ? caseDirName : "?")), ex); //NON-NLS
} catch (IllegalStateException ignored) {
/*
* No current case. Case.isCaseOpen is not reliable.
*/
logger.log(Level.SEVERE, "Error closing current case", ex); //NON-NLS
}
}).start();
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-15 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");
@ -140,12 +140,12 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi
private void showErrorNode(String errorMessage, AbstractFile file) {
final Button externalViewerButton = new Button(Bundle.MediaViewImagePanel_externalViewerButton_text(), new ImageView(EXTERNAL));
externalViewerButton.setOnAction(actionEvent -> //fx ActionEvent
externalViewerButton.setOnAction(actionEvent
-> //fx ActionEvent
/*
* TODO: why is the name passed into the action constructor? it
* means we duplicate this string all over the place -jm
*/
new ExternalViewerAction(Bundle.MediaViewImagePanel_externalViewerButton_text(), new FileNode(file))
*/ new ExternalViewerAction(Bundle.MediaViewImagePanel_externalViewerButton_text(), new FileNode(file))
.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "")) //Swing ActionEvent
);
@ -171,11 +171,10 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi
}
readImageTask = ImageUtils.newReadImageTask(file);
readImageTask.setOnSucceeded(succeeded -> {
//Note that all error conditions are allready logged in readImageTask.succeeded()
if (!Case.isCaseOpen()) {
/*
* handle in-between condition when case is being closed and
* an image was previously selected
* Handle the in-between condition when case is being closed
* and an image was previously selected
*
* NOTE: I think this is unnecessary -jm
*/
@ -200,7 +199,7 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi
readImageTask.setOnFailed(failed -> {
if (!Case.isCaseOpen()) {
/*
* handle in-between condition when case is being closed and
* Handle in-between condition when case is being closed and
* an image was previously selected
*
* NOTE: I think this is unnecessary -jm

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");
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.corecomponents;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
/**
* A filter node that creates at most one layer of child nodes for the node it
@ -44,7 +45,7 @@ public class TableFilterNode extends FilterNode {
* The constructor should include column order key. (See getColumnOrderKey)
*/
public TableFilterNode(Node wrappedNode, boolean createChildren) {
super(wrappedNode, TableFilterChildren.createInstance(wrappedNode, createChildren));
super(wrappedNode, TableFilterChildren.createInstance(wrappedNode, createChildren) , Lookups.proxy(wrappedNode));
this.createChildren = createChildren;
}

View File

@ -315,4 +315,29 @@ public class UNCPathUtilities {
}
return driveMap;
}
/**
* Converts a path to UNC, if possible. This is accomplished by checking the
* mapped drives list the operating system maintains and substituting where
* required. If the drive of the path passed in does not exist in the cached
* mapped drives list, a rescan of the mapped drives list is forced, and
* mapping is attempted one more time.
*
* @param indexDir the String of the absolute path to be converted to UNC,
* if possible
*
* @return UNC path if able to convert to UNC, original input path otherwise
*/
synchronized public String convertPathToUNC(String indexDir) {
// if we can check for UNC paths, do so, otherwise just return the indexDir
String result = mappedDriveToUNC(indexDir);
if (result == null) {
rescanDrives();
result = mappedDriveToUNC(indexDir);
}
if (result == null) {
return indexDir;
}
return result;
}
}

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.datamodel;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.logging.Level;
import org.apache.commons.lang.StringUtils;
import org.openide.util.NbBundle;
@ -130,9 +131,11 @@ public class ArtifactStringContent implements StringContent {
case INTEGER:
case LONG:
case DOUBLE:
case BYTE:
buffer.append(attr.getDisplayString());
break;
case BYTE:
buffer.append(Arrays.toString(attr.getValueBytes()));
break;
case DATETIME:
long epoch = attr.getValueLong();
String time = "0000-00-00 00:00:00";

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");
@ -404,7 +404,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()
|| attributeTypeID == ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()) {
} else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
} else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
@ -452,13 +453,6 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
forLookup.add(content);
}
// if there is a text highlighted version, of the content, add it too
// currently happens from keyword search module
TextMarkupLookup highlight = getHighlightLookup(artifact, content);
if (highlight != null) {
forLookup.add(highlight);
}
return Lookups.fixed(forLookup.toArray(new Object[forLookup.size()]));
}
@ -472,39 +466,6 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.getAssocCont.exception.msg"));
}
private static TextMarkupLookup getHighlightLookup(BlackboardArtifact artifact, Content content) {
if (artifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
return null;
}
long objectId = content.getId();
Lookup lookup = Lookup.getDefault();
TextMarkupLookup highlightFactory = lookup.lookup(TextMarkupLookup.class);
try {
List<BlackboardAttribute> attributes = artifact.getAttributes();
String keyword = null;
String regexp = null;
for (BlackboardAttribute att : attributes) {
final int attributeTypeID = att.getAttributeType().getTypeID();
if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
keyword = att.getValueString();
} else if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()) {
regexp = att.getValueString();
} else if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
objectId = att.getValueLong();
}
}
if (keyword != null) {
boolean isRegexp = StringUtils.isNotBlank(regexp);
String origQuery = isRegexp ? regexp : keyword;
return highlightFactory.createInstance(objectId, keyword, isRegexp, origQuery);
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, "Failed to retrieve Blackboard Attributes", ex); //NON-NLS
}
return null;
}
@Override
public boolean isLeafTypeNode() {

View File

@ -1,55 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2015 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.datamodel;
/**
* This interface acts as a sort of bridge between the Autopsy Core NetBeans
* Module (NBM) and the Autopsy KeywordSearch NBM. It is used to get indexed
* text marked up with HTML to highlight search hits for a particular keyword.
*
* Here is an example of how it works. It is used to put highlighted markup into
* the Lookups of the BlackboardArtifactNodes for keyword search hit artifacts.
* The BlackboardArtifactNode code that populates the node's Lookup asks the
* default global Lookup for an instance of TextMarkupLookup. The
* org.sleuthkit.autopsy.keywordsearch.HighlightedText class is the sole
* implementation of the interface, so the BlackboardArtifactNode gets a default
* constructed instance of HighlightedText. This otherwise useless
* instance is then used to call createInstance with parameters that are used to
* employ the Solr highlighting capability to create the markup. The
* TextMarkupLookup object goes in the BlackboardArtifactNode Lookup for later
* use by the ExtractedContentViewer, a DataContentViewer in the KeywordSearch
* NBM.
*/
public interface TextMarkupLookup {
/**
* Factory method for getting an object that encapsulates indexed text
* marked up (HTML) to highlight search hits for a particular keyword.
*
* @param objectId ID of the object (file or artifact) that is the
* source of the indexed text.
* @param keyword The keyword to be highlighted in the text.
* @param isRegex Whether or not the query that follows is a regex.
* @param originalQuery The query that produces the keyword hit.
*
* @return An object that encapsulates indexed text marked up (HTML) to
* highlight search hits for a particular keyword.
*/
public TextMarkupLookup createInstance(long objectId, String keyword, boolean isRegex, String originalQuery);
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
@ -27,23 +27,19 @@ import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case;
@ActionID(
category = "Help",
id = "org.sleuthkit.autopsy.diagnostics.PerformancePanelAction"
)
@ActionRegistration(
displayName = "#CTL_PerformancePanelAction",
lazy=true
)
@ActionID(category = "Help", id = "org.sleuthkit.autopsy.diagnostics.PerformancePanelAction")
@ActionRegistration(displayName = "#CTL_PerformancePanelAction", lazy = true)
@ActionReference(path = "Menu/Help", position = 1437)
public final class PerformancePanelAction extends CallableSystemAction {
private static final long serialVersionUID = 1L;
@Override
public void performAction() {
JDialog dialog = new PerformancePanel();
dialog.setVisible(true);
}
@Override
public boolean isEnabled() {
return Case.isCaseOpen();
@ -56,8 +52,9 @@ public final class PerformancePanelAction extends CallableSystemAction {
@Override
public boolean asynchronous() {
return false; // run on edt
return false;
}
@Override
public String getName() {
return NbBundle.getMessage(PerformancePanelAction.class, "CTL_PerformancePanelAction");

View File

@ -353,97 +353,101 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
if (Case.isCaseOpen()) {
Case currentCase = Case.getCurrentCase();
Case currentCase = null;
try {
currentCase = Case.getCurrentCase();
} catch (IllegalStateException ex) {
/*
* No open case.
*/
}
// close the top component if there's no image in this case
if (currentCase.hasData() == false) {
//this.close();
((BeanTreeView) this.jScrollPane1).setRootVisible(false); // hide the root
} else {
// if there's at least one image, load the image and open the top component
List<Object> items = new ArrayList<>();
final SleuthkitCase tskCase = currentCase.getSleuthkitCase();
items.add(new DataSources());
items.add(new Views(tskCase));
items.add(new Results(tskCase));
items.add(new Tags());
items.add(new Reports());
contentChildren = new RootContentChildren(items);
// close the top component if there's no image in this case
if (null == currentCase || currentCase.hasData() == false) {
((TreeView) this.jScrollPane1).setRootVisible(false); // hide the root
} else {
// if there's at least one image, load the image and open the top component
List<Object> items = new ArrayList<>();
final SleuthkitCase tskCase = currentCase.getSleuthkitCase();
items.add(new DataSources());
items.add(new Views(tskCase));
items.add(new Results(tskCase));
items.add(new Tags());
items.add(new Reports());
contentChildren = new RootContentChildren(items);
Node root = new AbstractNode(contentChildren) {
/**
* to override the right click action in the white blank
* space area on the directory tree window
*/
@Override
public Action[] getActions(boolean popup) {
return new Action[]{};
}
// Overide the AbstractNode use of DefaultHandle to return
// a handle which can be serialized without a parent
@Override
public Node.Handle getHandle() {
return new Node.Handle() {
@Override
public Node getNode() throws IOException {
return em.getRootContext();
}
};
}
};
root = new DirectoryTreeFilterNode(root, true);
em.setRootContext(root);
em.getRootContext().setName(currentCase.getName());
em.getRootContext().setDisplayName(currentCase.getName());
((BeanTreeView) this.jScrollPane1).setRootVisible(false); // hide the root
// Reset the forward and back lists because we're resetting the root context
resetHistory();
Children childNodes = em.getRootContext().getChildren();
TreeView tree = getTree();
Node results = childNodes.findChild(ResultsNode.NAME);
tree.expandNode(results);
Children resultsChilds = results.getChildren();
tree.expandNode(resultsChilds.findChild(KeywordHits.NAME));
tree.expandNode(resultsChilds.findChild(ExtractedContent.NAME));
Accounts accounts = resultsChilds.findChild(Accounts.NAME).getLookup().lookup(Accounts.class);
showRejectedCheckBox.setAction(accounts.newToggleShowRejectedAction());
showRejectedCheckBox.setSelected(false);
Node views = childNodes.findChild(ViewsNode.NAME);
Children viewsChilds = views.getChildren();
for (Node n : viewsChilds.getNodes()) {
tree.expandNode(n);
Node root = new AbstractNode(contentChildren) {
/**
* to override the right click action in the white blank
* space area on the directory tree window
*/
@Override
public Action[] getActions(boolean popup) {
return new Action[]{};
}
tree.collapseNode(views);
// if the dataResult is not opened
if (!dataResult.isOpened()) {
dataResult.open(); // open the data result top component as well when the directory tree is opened
// Overide the AbstractNode use of DefaultHandle to return
// a handle which can be serialized without a parent
@Override
public Node.Handle getHandle() {
return new Node.Handle() {
@Override
public Node getNode() throws IOException {
return em.getRootContext();
}
};
}
};
// select the first image node, if there is one
// (this has to happen after dataResult is opened, because the event
// of changing the selected node fires a handler that tries to make
// dataResult active)
if (childNodes.getNodesCount() > 0) {
try {
em.setSelectedNodes(new Node[]{childNodes.getNodeAt(0)});
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error setting default selected node.", ex); //NON-NLS
}
}
root = new DirectoryTreeFilterNode(root, true);
em.setRootContext(root);
em.getRootContext().setName(currentCase.getName());
em.getRootContext().setDisplayName(currentCase.getName());
((TreeView) this.jScrollPane1).setRootVisible(false); // hide the root
// Reset the forward and back lists because we're resetting the root context
resetHistory();
Children childNodes = em.getRootContext().getChildren();
TreeView tree = getTree();
Node results = childNodes.findChild(ResultsNode.NAME);
tree.expandNode(results);
Children resultsChilds = results.getChildren();
tree.expandNode(resultsChilds.findChild(KeywordHits.NAME));
tree.expandNode(resultsChilds.findChild(ExtractedContent.NAME));
Accounts accounts = resultsChilds.findChild(Accounts.NAME).getLookup().lookup(Accounts.class);
showRejectedCheckBox.setAction(accounts.newToggleShowRejectedAction());
showRejectedCheckBox.setSelected(false);
Node views = childNodes.findChild(ViewsNode.NAME);
Children viewsChilds = views.getChildren();
for (Node n : viewsChilds.getNodes()) {
tree.expandNode(n);
}
tree.collapseNode(views);
// if the dataResult is not opened
if (!dataResult.isOpened()) {
dataResult.open(); // open the data result top component as well when the directory tree is opened
}
// select the first image node, if there is one
// (this has to happen after dataResult is opened, because the event
// of changing the selected node fires a handler that tries to make
// dataResult active)
if (childNodes.getNodesCount() > 0) {
try {
em.setSelectedNodes(new Node[]{childNodes.getNodeAt(0)});
} catch (PropertyVetoException ex) {
LOGGER.log(Level.SEVERE, "Error setting default selected node.", ex); //NON-NLS
}
}
}
} finally {
this.setCursor(null);
@ -494,7 +498,12 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
@Override
public boolean canClose() {
return !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false; // only allow this window to be closed when there's no case opened or no image in this case
/*
* Only allow the main tree view in the left side of the main window to
* be closed if there is no opne case or the open case has no data
* sources.
*/
return !Case.isCaseOpen() || Case.getCurrentCase().hasData() == false;
}
/**
@ -540,7 +549,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (RuntimeProperties.coreComponentsAreActive()) {
if (RuntimeProperties.runningWithGUI()) {
String changed = evt.getPropertyName();
if (changed.equals(Case.Events.CURRENT_CASE.toString())) { // changed current case
// When a case is closed, the old value of this property is the

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");
@ -94,7 +94,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
} catch (ParseException ex) {
// for now, no need to show the error message to the user here
}
if (!startDateValue.equals("")) {
if (!startDateValue.isEmpty()) {
if (startDate != null) {
fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
}
@ -114,7 +114,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
} catch (ParseException ex) {
// for now, no need to show the error message to the user here
}
if (!endDateValue.equals("")) {
if (!endDateValue.isEmpty()) {
if (endDate != null) {
toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
}
@ -166,7 +166,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
List<String> timeZones = new ArrayList<>();
if (Case.isCaseOpen()) {
try {
// get the latest case
Case currentCase = Case.getCurrentCase(); // get the most updated case
@ -195,6 +195,8 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id); //NON-NLS
timeZones.add(item);
}
} catch (IllegalStateException ex) {
// No current case.
}
return timeZones;
@ -207,7 +209,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
@Override
public boolean isValid() {
return this.getComponent().isValidSearch();
return this.getComponent().isValidSearch();
}
/**

View File

@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 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");
* 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.
@ -29,14 +29,13 @@ import org.sleuthkit.autopsy.directorytree.FileSearchProvider;
final class FileSearchAction extends CallableSystemAction implements FileSearchProvider {
private static final long serialVersionUID = 1L;
private static FileSearchAction instance = null;
FileSearchAction() {
super();
setEnabled(Case.isCaseOpen()); //no guarantee listener executed, so check here
setEnabled(Case.isCaseOpen());
Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {

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

@ -0,0 +1,171 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 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.framework;
import org.sleuthkit.autopsy.casemodule.Case;
/**
* An interface for services that report status and may manage case and
* application resources such a text index, a database, etc. A service provider
* may have resources of both types, of only one type, or no resources at all.
*/
public interface AutopsyService {
/**
* Gets the service name.
*
* @return The service name.
*/
String getServiceName();
// Status getStatus() {
//
// }
// default void openAppResources(ApplicationContext context) throws AutopsyServiceException {
// /*
// * Autopsy services may not have application-level resources.
// */
// }
/**
* Creates, opens or upgrades any case-level resources managed by the
* service.
*
* @param context The case context which includes things such as the case, a
* progress indicator for the operation, a cancellation
* request flag, etc.
* @throws org.sleuthkit.autopsy.framework.AutopsyService.AutopsyServiceException
*/
default void openCaseResources(CaseContext context) throws AutopsyServiceException {
/*
* Autopsy services may not have case-level resources.
*/
}
/**
* Closes any case-level resources managed by the service.
*
* @param context The case context which includes things such as the case, a
* progress indicator for the operation, a cancellation
* request flag, etc.
* @throws org.sleuthkit.autopsy.framework.AutopsyService.AutopsyServiceException
*/
default void closeCaseResources(CaseContext context) throws AutopsyServiceException {
/*
* Autopsy services may not have case-level resources.
*/
}
// default void closeAppResources(ApplicationContext context) throws AutopsyServiceException {
// /*
// * Autopsy services may not have case-level resources.
// */
// }
/**
* The context for the creation/opening/upgrading of case-level resources by
* a service.
*/
public static class CaseContext {
private final Case theCase;
private final ProgressIndicator progressIndicator;
private volatile boolean cancelRequested;
/**
* Constructs the context for the creation/opening/upgrading of
* case-level resources by a service.
*
* @param theCase The case.
* @param progressIndicator A progress indicator for the opening of the
* case-level resources
*/
public CaseContext(Case theCase, ProgressIndicator progressIndicator) {
this.theCase = theCase;
this.progressIndicator = progressIndicator;
this.cancelRequested = false;
}
/**
* Gets the case for the creation/opening/upgrading of case-level
* resources by a service.
*
* @return The case.
*/
public Case getCase() {
return this.theCase;
}
/**
* Gets the progress indicator for the creation/opening/upgrading of
* case-level resources by a service.
*
* @return The progress indicator.
*/
public ProgressIndicator getProgressIndicator() {
return this.progressIndicator;
}
/**
* Requests cancellation of the creation/opening/upgrading of case-level
* resources by a service. The request is not guaranteed to be honored.
*/
public void requestCancel() {
this.cancelRequested = true;
}
/**
* Indicates whether or not cancellation of the
* creation/opening/upgrading of case-level resources by a service has
* been requested.
*
* @return True or false.
*/
public boolean cancelRequested() {
return this.cancelRequested;
}
}
/**
* Exception thrown by autopsy service methods.
*/
public static class AutopsyServiceException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Constructs an exception to be thrown by an autopsy service provider
* method.
*
* @param message Exception message.
*/
public AutopsyServiceException(String message) {
super(message);
}
/**
* Constructs an exception to be thrown by an autopsy service provider
* method.
*
* @param message Exception message.
* @param cause Exception cause.
*/
public AutopsyServiceException(String message, Throwable cause) {
super(message, cause);
}
}
}

View File

@ -0,0 +1,5 @@
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
ProgressPanel.progressMessage.text=Message

View File

@ -0,0 +1,75 @@
/*
* 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.framework;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* A progress indicator that writes progress to the Autopsy application log.
*/
public final class LoggingProgressIndicator implements ProgressIndicator {
private final Logger LOGGER = Logger.getLogger(LoggingProgressIndicator.class.getName());
private int totalWorkUnits;
@Override
public void start(String message, int totalWorkUnits) {
this.totalWorkUnits = totalWorkUnits;
LOGGER.log(Level.INFO, "{0} started, {1} total work units", new Object[]{message, this.totalWorkUnits});
}
@Override
public void start(String message) {
LOGGER.log(Level.INFO, "{0}", message);
}
@Override
public void switchToIndeterminate(String message) {
this.totalWorkUnits = 0;
LOGGER.log(Level.INFO, "{0}", message);
}
@Override
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
this.totalWorkUnits = totalWorkUnits;
LOGGER.log(Level.INFO, "{0}, {1} of {2} total work units completed", new Object[]{message, workUnitsCompleted, this.totalWorkUnits});
}
@Override
public void progress(String message) {
LOGGER.log(Level.INFO, "{0}", message);
}
@Override
public void progress(int workUnitsCompleted) {
LOGGER.log(Level.INFO, "{1} of {2} total work units completed", new Object[]{workUnitsCompleted, this.totalWorkUnits});
}
@Override
public void progress(String message, int workUnitsCompleted) {
LOGGER.log(Level.INFO, "{0}, {1} of {2} total work units completed", new Object[]{message, workUnitsCompleted, this.totalWorkUnits});
}
@Override
public void finish(String message) {
LOGGER.log(Level.INFO, "{0} finished", message);
}
}

View File

@ -0,0 +1,247 @@
/*
* 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.framework;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.HelpCtx;
/**
* A progress indicator that displays progress using a modal dialog with a
* message label, a progress bar, and optionally, a configurable set of buttons
* with a button listener.
*/
public final class ModalDialogProgressIndicator implements ProgressIndicator {
private final Frame parent;
private final ProgressPanel progressPanel;
private final Dialog dialog;
private final ActionListener buttonListener;
/**
* Creates a progress indicator that displays progress using a modal dialog
* with a message label, a progress bar with a configurable set of buttons
* with a button listener.
*
* @param parent The parent frame.
* @param title The title for the dialog.
* @param buttonLabels The labels for the desired buttons.
* @param focusedButtonLabel The label of the button that should have
* initial focus.
* @param buttonListener An ActionListener for the buttons.
*/
public ModalDialogProgressIndicator(Frame parent, String title, Object[] buttonLabels, Object focusedButtonLabel, ActionListener buttonListener) {
this.parent = parent;
progressPanel = new ProgressPanel();
DialogDescriptor dialogDescriptor = new DialogDescriptor(
progressPanel,
title,
true,
buttonLabels,
focusedButtonLabel,
DialogDescriptor.BOTTOM_ALIGN,
HelpCtx.DEFAULT_HELP,
buttonListener);
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
this.buttonListener = buttonListener;
}
/**
* Creates a progress indicator that displays progress using a modal dialog
* with a message label and a progress bar with no buttons.
*
* @param parent The parent frame.
* @param title The title for the dialog.
*/
public ModalDialogProgressIndicator(Frame parent, String title) {
this.parent = parent;
progressPanel = new ProgressPanel();
dialog = new JDialog(parent, title, true);
dialog.add(progressPanel);
dialog.pack();
buttonListener = null;
}
/**
* Calls setVisible on the underlying modal dialog.
*
* @param isVisible True or false.
*/
public void setVisible(boolean isVisible) {
if (isVisible) {
dialog.setLocationRelativeTo(parent);
}
this.dialog.setVisible(isVisible);
}
/**
* Gets the button listener for the dialog, if there is one.
*
* @return The button listener or null.
*/
public ActionListener getButtonListener() {
return buttonListener;
}
/**
* Starts the progress indicator in determinate mode (the total number of
* work units to be completed is known).
*
* @param message The initial progress message.
* @param totalWorkUnits The total number of work units.
*/
@Override
public void start(String message, int totalWorkUnits) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setInderminate(false);
progressPanel.setMessage(message);
progressPanel.setMaximum(totalWorkUnits);
}
});
}
/**
* Starts the progress indicator in indeterminate mode (the total number of
* work units to be completed is unknown).
*
* @param message The initial progress message.
*/
@Override
public void start(String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setInderminate(true);
progressPanel.setMessage(message);
}
});
}
/**
* Switches the progress indicator to indeterminate mode (the total number
* of work units to be completed is unknown).
*
* @param message The initial progress message.
*/
@Override
public void switchToIndeterminate(String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setInderminate(true);
progressPanel.setMessage(message);
}
});
}
/**
* Switches the progress indicator to determinate mode (the total number of
* work units to be completed is known).
*
* @param message The initial progress message.
* @param workUnitsCompleted The number of work units completed so far.
* @param totalWorkUnits The total number of work units to be completed.
*/
@Override
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setInderminate(false);
progressPanel.setMessage(message);
progressPanel.setMaximum(totalWorkUnits);
progressPanel.setCurrent(workUnitsCompleted);
}
});
}
/**
* Updates the progress indicator with a progress message.
*
* @param message The progress message.
*/
@Override
public void progress(String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setMessage(message);
}
});
}
/**
* Updates the progress indicator with the number of work units completed so
* far when in determinate mode (the total number of work units to be
* completed is known).
*
* @param workUnitsCompleted Number of work units completed so far.
*/
@Override
public void progress(int workUnitsCompleted) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setCurrent(workUnitsCompleted);
}
});
}
/**
* Updates the progress indicator with a progress message and the number of
* work units completed so far when in determinate mode (the total number of
* work units to be completed is known).
*
* @param message The progress message.
* @param workUnitsCompleted Number of work units completed so far.
*/
@Override
public void progress(String message, int workUnitsCompleted) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setMessage(message);
progressPanel.setCurrent(workUnitsCompleted);
}
});
}
/**
* Finishes the progress indicator when the task is completed.
*
* @param message The finished message.
*/
@Override
public void finish(String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPanel.setMessage(message);
}
});
}
}

View File

@ -0,0 +1,96 @@
/*
* 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.framework;
/**
* An interface for progress indicators. A progress indicator can run in
* determinate mode (the total number of work units to be completed is known) or
* indeterminate mode. Switching back and forth between the two modes is
* supported. Starting, finishing, and starting again is supported.
*/
public interface ProgressIndicator {
/**
* Starts the progress indicator in determinate mode (the total number of
* work units to be completed is known).
*
* @param message The initial progress message.
* @param totalWorkUnits The total number of work units.
*/
void start(String message, int totalWorkUnits);
/**
* Starts the progress indicator in indeterminate mode (the total number of
* work units to be completed is unknown).
*
* @param message The initial progress message.
*/
void start(String message);
/**
* Switches the progress indicator to indeterminate mode (the total number
* of work units to be completed is unknown).
* @param message The initial progress message.
*/
public void switchToIndeterminate(String message);
/**
* Switches the progress indicator to determinate mode (the total number of
* work units to be completed is known).
*
* @param message The initial progress message.
* @param workUnitsCompleted The number of work units completed so far.
* @param totalWorkUnits The total number of work units to be completed.
*/
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits);
/**
* Updates the progress indicator with a progress message.
*
* @param message The progress message.
*/
public void progress(String message);
/**
* Updates the progress indicator with the number of work units completed so
* far when in determinate mode (the total number of work units to be
* completed is known).
*
* @param workUnitsCompleted Number of work units completed so far.
*/
public void progress(int workUnitsCompleted);
/**
* Updates the progress indicator with a progress message and the number of
* work units completed so far when in determinate mode (the total number of
* work units to be completed is known).
*
* @param message The progress message.
* @param workUnitsCompleted Number of work units completed so far.
*/
public void progress(String message, int workUnitsCompleted);
/**
* Finishes the progress indicator when the task is completed.
*
* @param message The finished message.
*/
void finish(String message);
}

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="22" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="progressMessage" max="32767" attributes="0"/>
<Component id="progressBar" pref="355" max="32767" attributes="0"/>
</Group>
<EmptySpace pref="23" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
<Component id="progressMessage" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="progressBar" min="-2" pref="32" max="-2" attributes="0"/>
<EmptySpace pref="33" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<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/framework/Bundle.properties" key="ProgressPanel.progressMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JProgressBar" name="progressBar">
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,90 @@
/*
* 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.framework;
/**
* A progress panel consisting of a message label and a progress bar.
*/
class ProgressPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
ProgressPanel() {
initComponents();
this.progressBar.setMinimum(0);
}
void setMessage(String message) {
this.progressMessage.setText(message);
}
void setInderminate(boolean indeterminate) {
this.progressBar.setIndeterminate(indeterminate);
}
void setMaximum(int max) {
this.progressBar.setMaximum(max);
}
void setCurrent(int current) {
this.progressBar.setValue(current);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
progressMessage = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
org.openide.awt.Mnemonics.setLocalizedText(progressMessage, org.openide.util.NbBundle.getMessage(ProgressPanel.class, "ProgressPanel.progressMessage.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(22, 22, 22)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(progressMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE))
.addContainerGap(23, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(24, 24, 24)
.addComponent(progressMessage)
.addGap(18, 18, 18)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(33, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JProgressBar progressBar;
private javax.swing.JLabel progressMessage;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,60 @@
/*
* 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.framework;
import org.sleuthkit.autopsy.framework.ProgressIndicator;
/**
* A "silent" or "null" progress indicator.
*/
public class SilentProgressIndicator implements ProgressIndicator {
@Override
public void start(String message, int totalWorkUnits) {
}
@Override
public void start(String message) {
}
@Override
public void switchToIndeterminate(String message) {
}
@Override
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
}
@Override
public void progress(String message) {
}
@Override
public void progress(int workUnitsCompleted) {
}
@Override
public void progress(String message, int workUnitsCompleted) {
}
@Override
public void finish(String message) {
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-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");
@ -330,11 +330,11 @@ public class IngestManager {
// check whether a multi-user case is currently being processed
try {
if (!Case.isCaseOpen() || Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
if (Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
return;
}
} catch (IllegalStateException ignore) {
// thorown by Case.getCurrentCase() when no case is open
// Thrown by Case.getCurrentCase() when no case is open
return;
}
@ -343,7 +343,7 @@ public class IngestManager {
logger.log(Level.SEVERE, "Service {0} is down! Cancelling all running ingest jobs", serviceDisplayName); //NON-NLS
// display notification if running interactively
if (isIngestRunning() && RuntimeProperties.coreComponentsAreActive()) {
if (isIngestRunning() && RuntimeProperties.runningWithGUI()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
@ -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));
@ -392,24 +392,17 @@ public class IngestManager {
}
synchronized void handleCaseClosed() {
/*
* TODO (JIRA-2227): IngestManager should wait for cancelled ingest jobs
* to complete when a case is closed.
*/
this.cancelAllIngestJobs(IngestJob.CancellationReason.CASE_CLOSED);
jobEventPublisher.closeRemoteEventChannel();
moduleEventPublisher.closeRemoteEventChannel();
this.jobCreationIsEnabled = false;
clearIngestMessageBox();
}
/**
* Deprecated, use RuntimeProperties.setCoreComponentsActive instead.
*
* @param runInteractively True or false
*
* @deprecated
*/
@Deprecated
public synchronized void setRunInteractively(boolean runInteractively) {
RuntimeProperties.setCoreComponentsActive(runInteractively);
}
/**
* Called by the custom installer for this package once the window system is
* initialized, allowing the ingest manager to get the top component used to
@ -428,7 +421,7 @@ public class IngestManager {
*/
void postIngestMessage(IngestMessage message) {
synchronized (this.ingestMessageBoxLock) {
if (ingestMessageBox != null && RuntimeProperties.coreComponentsAreActive()) {
if (ingestMessageBox != null && RuntimeProperties.runningWithGUI()) {
if (message.getMessageType() != IngestMessage.MessageType.ERROR && message.getMessageType() != IngestMessage.MessageType.WARNING) {
ingestMessageBox.displayMessage(message);
} else {
@ -475,7 +468,7 @@ public class IngestManager {
*/
public void queueIngestJob(Collection<Content> dataSources, IngestJobSettings settings) {
if (jobCreationIsEnabled) {
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.coreComponentsAreActive());
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.runningWithGUI());
if (job.hasIngestPipeline()) {
long taskId = nextThreadId.incrementAndGet();
Future<Void> task = startIngestJobsThreadPool.submit(new StartIngestJobTask(taskId, job));
@ -485,9 +478,9 @@ public class IngestManager {
}
/**
* Starts an ingest job that will process a collection of data sources.
* This is intended to be used in an auto-ingest context and will fail
* if no ingest modules are enabled.
* Starts an ingest job that will process a collection of data sources. This
* is intended to be used in an auto-ingest context and will fail if no
* ingest modules are enabled.
*
* @param dataSources The data sources to process.
* @param settings The settings for the ingest job.
@ -497,7 +490,7 @@ public class IngestManager {
*/
public synchronized IngestJobStartResult beginIngestJob(Collection<Content> dataSources, IngestJobSettings settings) {
if (this.jobCreationIsEnabled) {
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.coreComponentsAreActive());
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.runningWithGUI());
if (job.hasIngestPipeline()) {
return this.startIngestJob(job); // Start job
}
@ -543,7 +536,7 @@ public class IngestManager {
try {
if (!servicesMonitor.getServiceStatus(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString()).equals(ServicesMonitor.ServiceStatus.UP.toString())) {
// display notification if running interactively
if (RuntimeProperties.coreComponentsAreActive()) {
if (RuntimeProperties.runningWithGUI()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
@ -582,7 +575,7 @@ public class IngestManager {
logger.log(Level.SEVERE, String.format("Error starting %s ingest module for job %d", error.getModuleDisplayName(), job.getId()), error.getThrowable()); //NON-NLS
}
IngestManager.logger.log(Level.SEVERE, "Ingest job {0} could not be started", job.getId()); //NON-NLS
if (RuntimeProperties.coreComponentsAreActive()) {
if (RuntimeProperties.runningWithGUI()) {
final StringBuilder message = new StringBuilder();
message.append(Bundle.IngestManager_startupErr_dlgMsg()).append("\n");
message.append(Bundle.IngestManager_startupErr_dlgSolution()).append("\n\n");
@ -966,7 +959,7 @@ public class IngestManager {
return null;
}
if (RuntimeProperties.coreComponentsAreActive()) {
if (RuntimeProperties.runningWithGUI()) {
final String displayName = NbBundle.getMessage(this.getClass(), "IngestManager.StartIngestJobsTask.run.displayName");
this.progress = ProgressHandle.createHandle(displayName, new Cancellable() {
@Override

View File

@ -130,7 +130,7 @@ class IngestMessagesToolbar extends javax.swing.JPanel {
Case.addPropertyChangeListener((PropertyChangeEvent evt) -> {
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
setEnabled(evt.getNewValue() != null && RuntimeProperties.coreComponentsAreActive());
setEnabled(evt.getNewValue() != null && RuntimeProperties.runningWithGUI());
}
});
}

View File

@ -27,7 +27,7 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="profileListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
@ -45,42 +45,56 @@
</Group>
</Group>
<Component id="jSeparator2" min="-2" pref="2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="filterNameLabel" min="-2" pref="36" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="filterNameText" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="filterDescLabel" min="-2" max="-2" attributes="0"/>
<Component id="selectedModulesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="profileDescLabel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="profileDescLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="216" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="profileDescPane" alignment="1" max="32767" attributes="0"/>
<Component id="selectedModulesPane" alignment="1" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
<Component id="filterDescPane" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="filterDescPane" alignment="1" pref="413" max="32767" attributes="0"/>
<Component id="profileDescPane" alignment="1" pref="413" max="32767" attributes="0"/>
<Component id="selectedModulesPane" alignment="1" pref="413" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="filterNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="filterNameText" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="selectedModulesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
@ -90,19 +104,17 @@
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" attributes="0">
<Component id="profileDescPane" pref="0" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="filterNameLabel" max="32767" attributes="0"/>
<Component id="filterNameText" max="32767" attributes="0"/>
<Component id="profileDescPane" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="filterNameLabel" min="-2" max="-2" attributes="0"/>
<Component id="filterNameText" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="filterDescLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="filterDescPane" pref="0" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="filterDescPane" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="selectedModulesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="selectedModulesPane" max="32767" attributes="0"/>
</Group>
<Component id="profileListPane" pref="415" max="32767" attributes="0"/>
@ -257,15 +269,18 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="ProfileSettingsPanel.filterNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[30, 14]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[30, 14]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="filterNameText">
</Component>
<Component class="javax.swing.JLabel" name="filterDescLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="ProfileSettingsPanel.filterDescLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="horizontalTextPosition" type="int" value="2"/>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="filterDescPane">

View File

@ -38,7 +38,6 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
"ProfileSettingsPanel.profileListLabel.text=Profiles:",
"ProfileSettingsPanel.profileDescLabel.text=Profile Description:",
"ProfileSettingsPanel.filterNameLabel.text=Filter:",
"ProfileSettingsPanel.filterDescLabel.text=Filter Description:",
"ProfileSettingsPanel.selectedModulesLabel.text=Selected Ingest Modules:",
"ProfileSettingsPanel.newProfileButton.text=New Profile",
"ProfileSettingsPanel.editProfileButton.text=Edit Profile",
@ -85,7 +84,6 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
profileDescLabel = new javax.swing.JLabel();
filterNameLabel = new javax.swing.JLabel();
filterNameText = new javax.swing.JLabel();
filterDescLabel = new javax.swing.JLabel();
filterDescPane = new javax.swing.JScrollPane();
filterDescArea = new javax.swing.JTextArea();
selectedModulesPane = new javax.swing.JScrollPane();
@ -148,8 +146,11 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
org.openide.awt.Mnemonics.setLocalizedText(profileDescLabel, org.openide.util.NbBundle.getMessage(ProfileSettingsPanel.class, "ProfileSettingsPanel.profileDescLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(filterNameLabel, org.openide.util.NbBundle.getMessage(ProfileSettingsPanel.class, "ProfileSettingsPanel.filterNameLabel.text")); // NOI18N
filterNameLabel.setMinimumSize(new java.awt.Dimension(30, 14));
filterNameLabel.setPreferredSize(new java.awt.Dimension(30, 14));
org.openide.awt.Mnemonics.setLocalizedText(filterDescLabel, org.openide.util.NbBundle.getMessage(ProfileSettingsPanel.class, "ProfileSettingsPanel.filterDescLabel.text")); // NOI18N
filterNameText.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
filterNameText.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
filterDescArea.setEditable(false);
filterDescArea.setBackground(new java.awt.Color(240, 240, 240));
@ -193,28 +194,37 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
.addComponent(deleteProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(6, 6, 6)))
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(6, 6, 6)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(filterNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filterNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterDescLabel)
.addComponent(selectedModulesLabel)
.addComponent(profileDescLabel))
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGap(8, 8, 8)
.addGap(6, 6, 6)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(ingestWarningLabel)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(filterDescPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE)
.addComponent(profileDescPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE)
.addComponent(selectedModulesPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE))))
.addGap(12, 12, 12))
.addComponent(profileDescLabel)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(ingestWarningLabel)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(profileDescPane, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(selectedModulesPane, javax.swing.GroupLayout.Alignment.TRAILING)))
.addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(filterDescPane)))
.addContainerGap())))
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filterNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(filterNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selectedModulesLabel)
.addContainerGap())))
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deleteProfileButton, editProfileButton, newProfileButton});
@ -231,16 +241,14 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(profileDescPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(profileDescPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(filterNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(filterNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(filterNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filterDescLabel)
.addComponent(filterDescPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filterDescPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(selectedModulesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selectedModulesPane))
@ -428,7 +436,6 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
private javax.swing.JButton deleteProfileButton;
private javax.swing.JButton editProfileButton;
private javax.swing.JTextArea filterDescArea;
private javax.swing.JLabel filterDescLabel;
private javax.swing.JScrollPane filterDescPane;
private javax.swing.JLabel filterNameLabel;
private javax.swing.JLabel filterNameText;

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,14 +30,13 @@ import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
@ActionID(
category = "Tools",
id = "org.sleuthkit.autopsy.ingest.RunIngestAction"
)
@ActionRegistration(
displayName = "#CTL_RunIngestAction",
lazy = false
)
/**
* The action associated with assorted Run Ingest Modules menu items.
*
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.ingest.RunIngestAction")
@ActionRegistration(displayName = "#CTL_RunIngestAction", lazy = false)
@Messages("CTL_RunIngestAction=Run Ingest")
public final class RunIngestAction extends CallableSystemAction implements Presenter.Menu, ActionListener {
@ -51,6 +50,9 @@ public final class RunIngestAction extends CallableSystemAction implements Prese
return action;
}
private RunIngestAction() {
}
@Override
public void performAction() {
getMenuPresenter();
@ -80,6 +82,6 @@ public final class RunIngestAction extends CallableSystemAction implements Prese
@Override
public boolean isEnabled() {
return Case.isCaseOpen();// && Case.getCurrentCase().hasData();
return Case.isCaseOpen() && Case.getCurrentCase().hasData();
}
}

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");
@ -23,32 +23,39 @@ 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 concatenation 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.
*
* @throws KeywordSearchServiceException if unable to delete.
*/
public void tryConnect(String host, int port) throws KeywordSearchServiceException;
public void deleteTextIndex(String textIndexName) throws KeywordSearchServiceException;
}

View File

@ -50,10 +50,11 @@ class DataContentDynamicMenu extends JMenuItem implements DynamicMenuContent {
defaultItem.addActionListener(new OpenTopComponentAction(contentWin));
if (!Case.isCaseOpen() || Case.getCurrentCase().hasData() == false) {
defaultItem.setEnabled(false); // disable the menu items when no case is opened
} else {
defaultItem.setEnabled(true); // enable the menu items when there's a case opened / created
try {
Case currentCase = Case.getCurrentCase();
defaultItem.setEnabled(currentCase.hasData());
} catch (IllegalStateException ex) {
defaultItem.setEnabled(false); // disable the menu when no case is opened
}
comps[counter++] = defaultItem;

View File

@ -53,10 +53,11 @@ class DataExplorerDynamicMenu extends JMenuItem implements DynamicMenuContent {
JMenuItem item = new JMenuItem(explorerWin.getName());
item.addActionListener(new OpenTopComponentAction(explorerWin));
if (!Case.isCaseOpen() || Case.getCurrentCase().hasData() == false) {
try {
Case currentCase = Case.getCurrentCase();
item.setEnabled(currentCase.hasData());
} catch (IllegalStateException ex) {
item.setEnabled(false); // disable the menu when no case is opened
} else {
item.setEnabled(true); // enable the menu if the case is opened or created
}
comps[i++] = item;

View File

@ -492,7 +492,7 @@ public class HashDbManager implements PropertyChangeListener {
the database from HashLookupSettings and the user may not know about this
because the dialogs are not being displayed. The next time user starts Autopsy, HashDB
will load without errors and the user may think that the problem was solved.*/
if (!allDatabasesLoadedCorrectly && RuntimeProperties.coreComponentsAreActive()) {
if (!allDatabasesLoadedCorrectly && RuntimeProperties.runningWithGUI()) {
try {
HashLookupSettings.writeSettings(new HashLookupSettings(this.knownHashSets, this.knownBadHashSets));
allDatabasesLoadedCorrectly = true;
@ -512,7 +512,7 @@ public class HashDbManager implements PropertyChangeListener {
// Give the user an opportunity to find the desired file.
String newPath = null;
if (RuntimeProperties.coreComponentsAreActive() &&
if (RuntimeProperties.runningWithGUI() &&
JOptionPane.showConfirmDialog(null,
NbBundle.getMessage(this.getClass(), "HashDbManager.dlgMsg.dbNotFoundAtLoc",
hashSetName, configuredPath),

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");
@ -36,13 +36,13 @@ import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationCleanDialog;
*/
class HashDbPanelSearchAction extends CallableSystemAction {
private static final long serialVersionUID = 1L;
static final String ACTION_NAME = NbBundle.getMessage(HashDbPanelSearchAction.class, "HashDbPanelSearchAction.actionName");
private static HashDbPanelSearchAction instance = null;
HashDbPanelSearchAction() {
super();
setEnabled(Case.isCaseOpen()); //no guarantee listener executed, so check here
setEnabled(Case.isCaseOpen());
Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override

View File

@ -203,7 +203,7 @@ final class HashLookupSettings implements Serializable {
newHashSetName = hashSetName + suffix;
} while (hashSetNames.contains(newHashSetName));
logger.log(Level.INFO, "Duplicate hash set name " + hashSetName + " found. Replacing with " + newHashSetName + ".");
if (RuntimeProperties.coreComponentsAreActive()) {
if (RuntimeProperties.runningWithGUI()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(HashLookupSettings.class,
"HashDbManager.replacingDuplicateHashsetNameMsg",
@ -269,7 +269,7 @@ final class HashLookupSettings implements Serializable {
try {
FileUtils.copyFile(new File(configFilePath), new File(backupFilePath));
logger.log(Level.INFO, "Updated the schema, backup saved at: " + backupFilePath);
if (RuntimeProperties.coreComponentsAreActive()) {
if (RuntimeProperties.runningWithGUI()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(HashLookupSettings.class,
"HashDbManager.savedBackupOfOldConfigMsg",

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

@ -84,7 +84,7 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
Case.addPropertyChangeListener((PropertyChangeEvent evt) -> {
if (evt.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
Case newCase = (Case) evt.getNewValue();
setEnabled(newCase != null && RuntimeProperties.coreComponentsAreActive());
setEnabled(newCase != null && RuntimeProperties.runningWithGUI());
}
});

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

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.report.testfixtures;
package org.sleuthkit.autopsy.test;
import java.util.ArrayList;
import java.util.List;

View File

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.report.testfixtures;
package org.sleuthkit.autopsy.test;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.FileIngestModule;

View File

@ -0,0 +1,71 @@
/*
* 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.test;
import java.util.logging.Level;
import org.openide.util.lookup.ServiceProvider;
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)
public class TestAutopsyService implements AutopsyService {
private static final Logger logger = Logger.getLogger(TestAutopsyService.class.getName());
@Override
public String getServiceName() {
return "Test Autopsy Service";
}
@Override
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
ProgressIndicator progressIndicator = context.getProgressIndicator();
try {
progressIndicator.start("Test Autopsy Service doing first task...");
logger.log(Level.INFO, "Test Autopsy Service simulating work on first task");
Thread.sleep(1000L);
progressIndicator.progress(20);
Thread.sleep(1000L);
progressIndicator.progress(40);
Thread.sleep(1000L);
progressIndicator.progress(60);
Thread.sleep(1000L);
progressIndicator.progress(80);
Thread.sleep(1000L);
progressIndicator.progress(100);
progressIndicator.finish("First task completed by Test Autopsy Service.");
progressIndicator.start("Test Autopsy Service doing second task...");
for (int i = 0; i < 10000; ++i) {
logger.log(Level.INFO, "Test Autopsy Service simulating work on second task");
if (context.cancelRequested()) {
logger.log(Level.INFO, "Test Autopsy Service cancelled while doing second task, cancel requested = {0}", context.cancelRequested());
break;
}
}
progressIndicator.finish("Second task completed by Test Autopsy Service.");
} catch (InterruptedException ex) {
logger.log(Level.INFO, "Test Autopsy Service interrupted (cancelled) while doing first task, cancel requested = {0}", context.cancelRequested());
}
}
}

View File

@ -58,8 +58,7 @@ public final class OpenTimelineAction extends CallableSystemAction implements Pr
private static TimeLineController timeLineController = null;
private final JButton toolbarButton = new JButton(getName(),
new ImageIcon(getClass().getResource("images/btn_icon_timeline_colorized_26.png"))); //NON-NLS
new ImageIcon(getClass().getResource("images/btn_icon_timeline_colorized_26.png"))); //NON-NLS
/**
* Invalidate the reference to the controller so that a new one will be

View File

@ -453,8 +453,8 @@ public class TimeLineController {
TimeLineController.this.showFullRange();
} else {
//prompt user to pick specific event and time range
ShowInTimelineDialog showInTimelineDilaog =
(file == null)
ShowInTimelineDialog showInTimelineDilaog
= (file == null)
? new ShowInTimelineDialog(TimeLineController.this, artifact)
: new ShowInTimelineDialog(TimeLineController.this, file);
Optional<ViewInTimelineRequestedEvent> dialogResult = showInTimelineDilaog.showAndWait();
@ -575,7 +575,6 @@ public class TimeLineController {
Case.addPropertyChangeListener(caseListener);
listeningToAutopsy = true;
}
Platform.runLater(() -> promptForRebuild(file, artifact));
}

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

@ -0,0 +1,123 @@
/*
* 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.experimental.autoingest;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.SwingUtilities;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.AddImageAction;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseNewAction;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
/**
* Handles locating and opening cases created by auto ingest.
*/
final class AutoIngestCaseManager {
private static final Logger LOGGER = Logger.getLogger(AutoIngestCaseManager.class.getName());
private static AutoIngestCaseManager instance;
/**
* Gets the auto ingest case manager.
*
* @return The auto ingest case manager singleton.
*/
synchronized static AutoIngestCaseManager getInstance() {
if (null == instance) {
instance = new AutoIngestCaseManager();
}
return instance;
}
/**
* Constructs an object that handles locating and opening cases created by
* auto ingest.
*/
private AutoIngestCaseManager() {
/*
* Disable the new case action because review mode is only for looking
* at cases created by automated ingest.
*/
CallableSystemAction.get(CaseNewAction.class).setEnabled(false);
/*
* Permanently delete the "Open Recent Cases" item in the "File" menu.
* This is quite drastic, as it also affects Autopsy standalone mode on
* this machine, but review mode is only for looking at cases created by
* automated ingest.
*/
FileObject root = FileUtil.getConfigRoot();
FileObject openRecentCasesMenu = root.getFileObject("Menu/Case/OpenRecentCase");
if (openRecentCasesMenu != null) {
try {
openRecentCasesMenu.delete();
} catch (IOException ex) {
AutoIngestCaseManager.LOGGER.log(Level.WARNING, "Unable to remove Open Recent Cases file menu item", ex);
}
}
}
/*
* Gets a list of the cases in the top level case folder used by auto
* ingest.
*/
List<AutoIngestCase> getCases() {
List<AutoIngestCase> cases = new ArrayList<>();
List<Path> caseFolders = PathUtils.findCaseFolders(Paths.get(AutoIngestUserPreferences.getAutoModeResultsFolder()));
for (Path caseFolderPath : caseFolders) {
cases.add(new AutoIngestCase(caseFolderPath));
}
return cases;
}
/**
* Opens an auto ingest case case.
*
* @param caseMetadataFilePath Path to the case metadata file.
*
* @throws CaseActionException
*/
synchronized void openCase(Path caseMetadataFilePath) throws CaseActionException {
/*
* Open the case.
*/
Case.openAsCurrentCase(caseMetadataFilePath.toString());
/**
* Disable the add data source action in auto ingest examiner mode. This
* has to be done here because Case.open() calls Case.doCaseChange() and
* the latter method enables the action. Since Case.doCaseChange()
* enables the menus on EDT by calling SwingUtilities.invokeLater(), we
* have to do the same thing here to maintain the order of execution.
*/
SwingUtilities.invokeLater(() -> {
CallableSystemAction.get(AddImageAction.class).setEnabled(false);
});
}
}

View File

@ -73,7 +73,7 @@
<Component class="javax.swing.JButton" name="bnOpen">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.bnOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
@ -109,7 +109,7 @@
<Component class="javax.swing.JButton" name="bnRefresh">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.bnRefresh.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnRefresh.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
@ -160,7 +160,7 @@
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.rbAllCases.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbAllCases.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
@ -173,7 +173,7 @@
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.rbMonths.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbMonths.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
@ -186,7 +186,7 @@
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.rbWeeks.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbWeeks.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
@ -199,7 +199,7 @@
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.rbDays.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbDays.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
@ -213,7 +213,7 @@
<Font name="Tahoma" size="12" style="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.rbGroupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbGroupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -222,10 +222,10 @@
<Component class="javax.swing.JButton" name="bnShowLog">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.bnShowLog.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnShowLog.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="ReviewModeCasePanel.bnShowLog.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnShowLog.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
@ -18,38 +18,38 @@
*/
package org.sleuthkit.autopsy.experimental.autoingest;
import java.awt.Cursor;
import java.awt.Desktop;
import java.nio.file.Paths;
import java.util.List;
import javax.swing.JPanel;
import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JOptionPane;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
import java.awt.Cursor;
import java.io.IOException;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
import org.sleuthkit.autopsy.experimental.autoingest.ReviewModeCaseManager.ReviewModeCaseManagerException;
import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* A panel that allows a user to open cases created by automated ingest.
* A panel that allows a user to open cases created by auto ingest.
*/
public final class ReviewModeCasePanel extends JPanel {
public final class AutoIngestCasePanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(ReviewModeCasePanel.class.getName());
private static final Logger logger = Logger.getLogger(AutoIngestCasePanel.class.getName());
private static final AutoIngestCase.LastAccessedDateDescendingComparator reverseDateModifiedComparator = new AutoIngestCase.LastAccessedDateDescendingComparator();
private static final int CASE_COL_MIN_WIDTH = 30;
private static final int CASE_COL_MAX_WIDTH = 2000;
@ -60,8 +60,8 @@ public final class ReviewModeCasePanel extends JPanel {
private static final int STATUS_COL_MIN_WIDTH = 55;
private static final int STATUS_COL_MAX_WIDTH = 250;
private static final int STATUS_COL_PREFERRED_WIDTH = 60;
private static final int MILLISECONDS_TO_WAIT_BEFORE_STARTING = 500; // RJCTODO: Shorten name
private static final int MILLISECONDS_TO_WAIT_BETWEEN_UPDATES = 30000; // RJCTODO: Shorten name
private static final int MILLIS_TO_WAIT_BEFORE_STARTING = 500;
private static final int MILLIS_TO_WAIT_BETWEEN_UPDATES = 30000;
private ScheduledThreadPoolExecutor casesTableRefreshExecutor;
/*
@ -71,11 +71,11 @@ public final class ReviewModeCasePanel extends JPanel {
* TODO (RC): Consider unifying this stuff in an enum as in
* AutoIngestDashboard to make it less error prone.
*/
private static final String CASE_HEADER = org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.CaseHeaderText");
private static final String CREATEDTIME_HEADER = org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.CreatedTimeHeaderText");
private static final String COMPLETEDTIME_HEADER = org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.LastAccessedTimeHeaderText");
private static final String STATUS_ICON_HEADER = org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.StatusIconHeaderText");
private static final String OUTPUT_FOLDER_HEADER = org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.OutputFolderHeaderText");
private static final String CASE_HEADER = org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.CaseHeaderText");
private static final String CREATEDTIME_HEADER = org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.CreatedTimeHeaderText");
private static final String COMPLETEDTIME_HEADER = org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.LastAccessedTimeHeaderText");
private static final String STATUS_ICON_HEADER = org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.StatusIconHeaderText");
private static final String OUTPUT_FOLDER_HEADER = org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.OutputFolderHeaderText");
enum COLUMN_HEADERS {
@ -83,7 +83,7 @@ public final class ReviewModeCasePanel extends JPanel {
CREATEDTIME,
COMPLETEDTIME,
STATUS_ICON,
OUTPUTFOLDER // RJCTODO: Change name
OUTPUTFOLDER
}
private final String[] columnNames = {CASE_HEADER, CREATEDTIME_HEADER, COMPLETEDTIME_HEADER, STATUS_ICON_HEADER, OUTPUT_FOLDER_HEADER};
private DefaultTableModel caseTableModel;
@ -92,8 +92,10 @@ public final class ReviewModeCasePanel extends JPanel {
/**
* Constructs a panel that allows a user to open cases created by automated
* ingest.
*
* @param parent The parent dialog for this panel.
*/
public ReviewModeCasePanel(JDialog parent) {
public AutoIngestCasePanel(JDialog parent) {
caseTableModel = new DefaultTableModel(columnNames, 0) {
private static final long serialVersionUID = 1L;
@ -183,7 +185,7 @@ public final class ReviewModeCasePanel extends JPanel {
casesTableRefreshExecutor = new ScheduledThreadPoolExecutor(1);
this.casesTableRefreshExecutor.scheduleAtFixedRate(() -> {
refreshCasesTable();
}, MILLISECONDS_TO_WAIT_BEFORE_STARTING, MILLISECONDS_TO_WAIT_BETWEEN_UPDATES, TimeUnit.MILLISECONDS);
}, MILLIS_TO_WAIT_BEFORE_STARTING, MILLIS_TO_WAIT_BETWEEN_UPDATES, TimeUnit.MILLISECONDS);
}
}
@ -214,7 +216,7 @@ public final class ReviewModeCasePanel extends JPanel {
private void refreshCasesTable() {
try {
currentlySelectedCase = getSelectedCase();
List<AutoIngestCase> theModel = ReviewModeCaseManager.getInstance().getCases();
List<AutoIngestCase> theModel = AutoIngestCaseManager.getInstance().getCases();
EventQueue.invokeLater(new CaseTableRefreshTask(theModel));
} catch (Exception ex) {
logger.log(Level.SEVERE, "Unexpected exception in refreshCasesTable", ex); //NON-NLS
@ -279,10 +281,10 @@ public final class ReviewModeCasePanel extends JPanel {
private void openCase(Path caseMetadataFilePath) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
ReviewModeCaseManager.getInstance().openCaseInEDT(caseMetadataFilePath);
AutoIngestCaseManager.getInstance().openCase(caseMetadataFilePath);
stopCasesTableRefreshes();
StartupWindowProvider.getInstance().close();
} catch (ReviewModeCaseManagerException ex) {
} catch (CaseActionException ex) {
logger.log(Level.SEVERE, String.format("Error while opening case with case metadata file path %s", caseMetadataFilePath), ex);
/*
* ReviewModeCaseManagerExceptions have user-friendly error
@ -290,7 +292,7 @@ public final class ReviewModeCasePanel extends JPanel {
*/
JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
ex.getMessage(),
org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.cannotOpenCase"),
org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "ReviewModeCasePanel.cannotOpenCase"),
JOptionPane.ERROR_MESSAGE);
} finally {
@ -345,18 +347,12 @@ public final class ReviewModeCasePanel extends JPanel {
long multiplier = 1;
if (rbAllCases.isSelected()) {
return true;
} else {
if (rbMonths.isSelected()) {
multiplier = 31;
} else {
if (rbWeeks.isSelected()) {
multiplier = 7;
} else {
if (rbDays.isSelected()) {
multiplier = 1;
}
}
}
} else if (rbMonths.isSelected()) {
multiplier = 31;
} else if (rbWeeks.isSelected()) {
multiplier = 7;
} else if (rbDays.isSelected()) {
multiplier = 1;
}
return ((currentTime - inputTime) / (1000 * 60 * 60 * 24)) < (numberOfUnits * multiplier);
}
@ -387,7 +383,7 @@ public final class ReviewModeCasePanel extends JPanel {
setName("Completed Cases"); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnOpen, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.bnOpen.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnOpen, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.bnOpen.text")); // NOI18N
bnOpen.setEnabled(false);
bnOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -407,7 +403,7 @@ public final class ReviewModeCasePanel extends JPanel {
});
scrollPaneTable.setViewportView(casesTable);
org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.bnRefresh.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.bnRefresh.text")); // NOI18N
bnRefresh.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnRefreshActionPerformed(evt);
@ -416,7 +412,7 @@ public final class ReviewModeCasePanel extends JPanel {
rbGroupHistoryLength.add(rbAllCases);
rbAllCases.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(rbAllCases, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.rbAllCases.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbAllCases, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbAllCases.text")); // NOI18N
rbAllCases.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbAllCasesItemStateChanged(evt);
@ -424,7 +420,7 @@ public final class ReviewModeCasePanel extends JPanel {
});
rbGroupHistoryLength.add(rbMonths);
org.openide.awt.Mnemonics.setLocalizedText(rbMonths, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.rbMonths.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbMonths, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbMonths.text")); // NOI18N
rbMonths.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbMonthsItemStateChanged(evt);
@ -432,7 +428,7 @@ public final class ReviewModeCasePanel extends JPanel {
});
rbGroupHistoryLength.add(rbWeeks);
org.openide.awt.Mnemonics.setLocalizedText(rbWeeks, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.rbWeeks.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbWeeks, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbWeeks.text")); // NOI18N
rbWeeks.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbWeeksItemStateChanged(evt);
@ -440,7 +436,7 @@ public final class ReviewModeCasePanel extends JPanel {
});
rbGroupHistoryLength.add(rbDays);
org.openide.awt.Mnemonics.setLocalizedText(rbDays, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.rbDays.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbDays, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbDays.text")); // NOI18N
rbDays.setName(""); // NOI18N
rbDays.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
@ -449,7 +445,7 @@ public final class ReviewModeCasePanel extends JPanel {
});
rbGroupLabel.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbGroupLabel, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.rbGroupLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbGroupLabel, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbGroupLabel.text")); // NOI18N
javax.swing.GroupLayout panelFilterLayout = new javax.swing.GroupLayout(panelFilter);
panelFilter.setLayout(panelFilterLayout);
@ -481,8 +477,8 @@ public final class ReviewModeCasePanel extends JPanel {
.addContainerGap())
);
org.openide.awt.Mnemonics.setLocalizedText(bnShowLog, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.bnShowLog.text")); // NOI18N
bnShowLog.setToolTipText(org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "ReviewModeCasePanel.bnShowLog.toolTipText")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnShowLog, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.bnShowLog.text")); // NOI18N
bnShowLog.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.bnShowLog.toolTipText")); // NOI18N
bnShowLog.setEnabled(false);
bnShowLog.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -586,14 +582,14 @@ public final class ReviewModeCasePanel extends JPanel {
if (pathToLog.toFile().exists()) {
Desktop.getDesktop().edit(pathToLog.toFile());
} else {
JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "DisplayLogDialog.cannotFindLog"),
org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "DisplayLogDialog.unableToShowLogFile"), JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.cannotFindLog"),
org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.unableToShowLogFile"), JOptionPane.ERROR_MESSAGE);
}
} catch (IOException ex) {
logger.log(Level.SEVERE, String.format("Error attempting to open case auto ingest log file %s", pathToLog), ex);
JOptionPane.showMessageDialog(this,
org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "DisplayLogDialog.cannotOpenLog"),
org.openide.util.NbBundle.getMessage(ReviewModeCasePanel.class, "DisplayLogDialog.unableToShowLogFile"),
org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.cannotOpenLog"),
org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.unableToShowLogFile"),
JOptionPane.PLAIN_MESSAGE);
}
}

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");
}
@ -431,7 +431,7 @@ final class AutoIngestJobLogger {
* log file.
*/
private void log(MessageCategory category, String message) throws AutoIngestJobLoggerException, InterruptedException {
try (Lock lock = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, getLogPath(caseDirectoryPath).toString(), LOCK_TIME_OUT, LOCK_TIME_OUT_UNIT)) {
try (Lock lock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, getLogPath(caseDirectoryPath).toString(), LOCK_TIME_OUT, LOCK_TIME_OUT_UNIT)) {
if (null != lock) {
File logFile = getLogPath(caseDirectoryPath).toFile();
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true)) {

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

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 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");
@ -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
@ -232,7 +212,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
void startUp() throws AutoIngestManagerStartupException {
SYS_LOGGER.log(Level.INFO, "Auto ingest starting");
try {
coordinationService = CoordinationService.getInstance(CoordinationServiceNamespace.getRoot());
coordinationService = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot());
} catch (CoordinationServiceException ex) {
throw new AutoIngestManagerStartupException("Failed to get coordination service", ex);
}
@ -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);
RuntimeProperties.setCoreComponentsActive(false);
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) {
@ -502,12 +489,12 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
inputScanExecutor.submit(new InputDirScanTask());
}
/**
* Start a scan of the input directories and wait for scan to complete.
*/
void scanInputDirsAndWait(){
if (State.RUNNING != state) {
void scanInputDirsAndWait() {
if (State.RUNNING != state) {
return;
}
SYS_LOGGER.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory);
@ -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) {
return CaseDeletionResult.FAILED;
}
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;
}
/*
* 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,27 +755,27 @@ 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);
}
}
}
}
/**
* Get the current snapshot of the job lists.
*
* @return Snapshot of jobs lists
*/
JobsSnapshot getCurrentJobsSnapshot(){
synchronized(jobsLock){
JobsSnapshot getCurrentJobsSnapshot() {
synchronized (jobsLock) {
List<AutoIngestJob> runningJobs = new ArrayList<>();
getJobs(null, runningJobs, null);
return new JobsSnapshot(pendingJobs, runningJobs, completedJobs);
@ -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;
@ -1714,18 +1659,18 @@ public final class AutoIngestManager extends Observable implements PropertyChang
*/
continue;
}
ManifestNodeData nodeData = new ManifestNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString()));
if(! nodeData.getStatus().equals(PENDING)){
if (!nodeData.getStatus().equals(PENDING)) {
/*
* Due to a timing issue or a missed event,
* a non-pending job has ended up on the pending queue.
* Skip the job and remove it from the 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();
continue;
}
if (enforceMaxJobsPerCase) {
int currentJobsForCase = 0;
for (AutoIngestJob runningJob : hostNamesToRunningJobs.values()) {
@ -1806,9 +1751,9 @@ public final class AutoIngestManager extends Observable implements PropertyChang
if (jobProcessingTaskFuture.isCancelled()) {
currentJob.cancel();
}
nodeData = new ManifestNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath));
if(currentJob.isCompleted() || currentJob.isCancelled()){
if (currentJob.isCompleted() || currentJob.isCancelled()) {
nodeData.setStatus(COMPLETED);
Date completedDate = new Date();
currentJob.setCompletedDate(completedDate);
@ -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()) {
@ -1892,7 +1836,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
} finally {
try {
caseForJob.closeCase();
Case.closeCurrentCase();
} catch (CaseActionException ex) {
Manifest manifest = currentJob.getManifest();
throw new CaseManagementException(String.format("Error closing case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
@ -1983,41 +1927,33 @@ 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, 30, TimeUnit.MINUTES)) {
if (null != caseLock) {
try {
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, caseName);
if (null != caseDirectoryPath) {
Path metadataFilePath = caseDirectoryPath.resolve(manifest.getCaseName() + CaseMetadata.getFileExtension());
Case.open(metadataFilePath.toString());
} else {
caseDirectoryPath = PathUtils.createCaseFolderPath(rootOutputDirectory, caseName);
Case.create(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.
*/
Thread.sleep(AutoIngestUserPreferences.getSecondsToSleepBetweenCases() * 1000);
}
currentJob.setCaseDirectoryPath(caseDirectoryPath);
Case caseForJob = Case.getCurrentCase();
SYS_LOGGER.log(Level.INFO, "Opened case {0} for {1}", new Object[]{caseForJob.getName(), manifest.getFilePath()});
return caseForJob;
} catch (CaseActionException ex) {
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.
*/
throw new CaseManagementException(String.format("Error getting current case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
}
try {
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, caseName);
if (null != caseDirectoryPath) {
Path metadataFilePath = caseDirectoryPath.resolve(manifest.getCaseName() + CaseMetadata.getFileExtension());
Case.openAsCurrentCase(metadataFilePath.toString());
} else {
throw new CaseManagementException(String.format("Timed out acquiring case name lock for %s for %s", manifest.getCaseName(), manifest.getFilePath()));
caseDirectoryPath = PathUtils.createCaseFolderPath(rootOutputDirectory, caseName);
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.
*/
Thread.sleep(AutoIngestUserPreferences.getSecondsToSleepBetweenCases() * 1000);
}
currentJob.setCaseDirectoryPath(caseDirectoryPath);
Case caseForJob = Case.getCurrentCase();
SYS_LOGGER.log(Level.INFO, "Opened case {0} for {1}", new Object[]{caseForJob.getName(), manifest.getFilePath()});
return caseForJob;
} catch (CaseActionException ex) {
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.
*/
throw new CaseManagementException(String.format("Error getting current case %s for %s", manifest.getCaseName(), manifest.getFilePath()), ex);
}
}
@ -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()) {
@ -2200,7 +2136,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
for (AutoIngestDataSourceProcessor processor : processorCandidates) {
try {
int confidence = processor.canProcess(dataSource.getPath());
if(confidence > 0){
if (confidence > 0) {
validDataSourceProcessorsMap.put(processor, confidence);
}
} catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException ex) {
@ -2219,16 +2155,16 @@ public final class AutoIngestManager extends Observable implements PropertyChang
SYS_LOGGER.log(Level.WARNING, "Unsupported data source {0} for {1}", new Object[]{dataSource.getPath(), manifestPath}); // NON-NLS
return;
}
// Get an ordered list of data source processors to try
List<AutoIngestDataSourceProcessor> validDataSourceProcessors = validDataSourceProcessorsMap.entrySet().stream()
.sorted(Map.Entry.<AutoIngestDataSourceProcessor, Integer>comparingByValue().reversed())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
.sorted(Map.Entry.<AutoIngestDataSourceProcessor, Integer>comparingByValue().reversed())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
synchronized (ingestLock) {
// Try each DSP in decreasing order of confidence
for(AutoIngestDataSourceProcessor selectedProcessor:validDataSourceProcessors){
for (AutoIngestDataSourceProcessor selectedProcessor : validDataSourceProcessors) {
jobLogger.logDataSourceProcessorSelected(selectedProcessor.getDataSourceType());
SYS_LOGGER.log(Level.INFO, "Identified data source type for {0} as {1}", new Object[]{manifestPath, selectedProcessor.getDataSourceType()});
try {
@ -2249,7 +2185,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
SYS_LOGGER.log(Level.SEVERE, "All data source processors failed to process {0}", dataSource.getPath());
jobLogger.logFailedToAddDataSource();
// Throw an exception. It will get caught & handled upstream and will result in AIM auto-pause.
throw new AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException("Failed to process " + dataSource.getPath() + " with all data source processors");
throw new AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException("Failed to process " + dataSource.getPath() + " with all data source processors");
}
} finally {
currentJob.setDataSourceProcessor(null);
@ -2325,7 +2261,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
jobLogger.logDataSourceProcessorCancelled();
}
}
/**
* Analyzes the data source content returned by the data source
* processor using the configured set of data source level and file
@ -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;
@ -2704,14 +2640,14 @@ public final class AutoIngestManager extends Observable implements PropertyChang
notifyObservers(Event.JOB_STATUS_UPDATED);
eventPublisher.publishRemotely(new AutoIngestJobStatusEvent(currentJob));
}
if(AutoIngestUserPreferences.getStatusDatabaseLoggingEnabled()){
if (AutoIngestUserPreferences.getStatusDatabaseLoggingEnabled()) {
String message;
boolean isError = false;
if(getErrorState().equals(ErrorState.NONE)){
if(currentJob != null){
message = "Processing " + currentJob.getManifest().getDataSourceFileName() +
" for case " + currentJob.getManifest().getCaseName();
if (getErrorState().equals(ErrorState.NONE)) {
if (currentJob != null) {
message = "Processing " + currentJob.getManifest().getDataSourceFileName()
+ " for case " + currentJob.getManifest().getCaseName();
} else {
message = "Paused or waiting for next case";
}
@ -2719,9 +2655,9 @@ public final class AutoIngestManager extends Observable implements PropertyChang
message = getErrorState().toString();
isError = true;
}
try{
try {
StatusDatabaseLogger.logToStatusDatabase(message, isError);
} catch (SQLException | UserPreferencesException ex){
} catch (SQLException | UserPreferencesException ex) {
SYS_LOGGER.log(Level.WARNING, "Failed to update status database", ex);
}
}
@ -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 {
@ -2794,31 +2730,31 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
/**
* The current auto ingest error state.
* The current auto ingest error state.
*/
private enum ErrorState {
NONE ("None"),
COORDINATION_SERVICE_ERROR ("Coordination service error"),
NONE("None"),
COORDINATION_SERVICE_ERROR("Coordination service error"),
SHARED_CONFIGURATION_DOWNLOAD_ERROR("Shared configuration download error"),
SERVICES_MONITOR_COMMUNICATION_ERROR ("Services monitor communication error"),
DATABASE_SERVER_ERROR ("Database server error"),
KEYWORD_SEARCH_SERVER_ERROR ("Keyword search server error"),
CASE_MANAGEMENT_ERROR ("Case management error"),
ANALYSIS_STARTUP_ERROR ("Analysis startup error"),
FILE_EXPORT_ERROR ("File export error"),
ALERT_FILE_ERROR ("Alert file error"),
JOB_LOGGER_ERROR ("Job logger error"),
DATA_SOURCE_PROCESSOR_ERROR ("Data source processor error"),
UNEXPECTED_EXCEPTION ("Unknown error");
SERVICES_MONITOR_COMMUNICATION_ERROR("Services monitor communication error"),
DATABASE_SERVER_ERROR("Database server error"),
KEYWORD_SEARCH_SERVER_ERROR("Keyword search server error"),
CASE_MANAGEMENT_ERROR("Case management error"),
ANALYSIS_STARTUP_ERROR("Analysis startup error"),
FILE_EXPORT_ERROR("File export error"),
ALERT_FILE_ERROR("Alert file error"),
JOB_LOGGER_ERROR("Job logger error"),
DATA_SOURCE_PROCESSOR_ERROR("Data source processor error"),
UNEXPECTED_EXCEPTION("Unknown error");
private final String desc;
private ErrorState(String desc){
private ErrorState(String desc) {
this.desc = desc;
}
@Override
public String toString(){
public String toString() {
return desc;
}
}
@ -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

@ -89,13 +89,6 @@ OpenIDE-Module-Long-Description=\
We make no guarantee that the API of this module will not change, so developers should be careful when relying on it.
OpenIDE-Module-Name=Experimental
OpenIDE-Module-Short-Description=This module contains features that are being developed by Basis Technology and are not part of the default Autopsy distribution.
ReviewModeCasePanel.bnRefresh.text=&Refresh
ReviewModeCasePanel.bnOpen.text=&Open
ReviewModeCasePanel.rbGroupLabel.text=Show Last 10:
ReviewModeCasePanel.rbDays.text=Days
ReviewModeCasePanel.rbWeeks.text=Weeks
ReviewModeCasePanel.rbMonths.text=Months
ReviewModeCasePanel.rbAllCases.text=Everything
ReviewModeCasePanel.cannotOpenCase=Cannot Open Case
ReviewModeCasePanel.casePathNotFound=Case path not found
ReviewModeCasePanel.caseIsLocked=Single-user case is locked.
@ -170,12 +163,10 @@ CopyFilesPanel.ConfirmCopyAdd=exists. Do you really want to copy more files to t
CopyFilesPanel.ConfirmCopyYes=Copy
CopyFilesPanel.ConfirmCopyNo=Do not copy
ConfirmationDialog.ConfirmUnlockHeader=Confirm Case Unlock
ReviewModeCasePanel.bnShowLog.text=&Show Log
AutoIngestDashboard.bnPrioritizeCase.toolTipText=Move all images associated with a case to top of Pending queue.
AutoIngestDashboard.bnPrioritizeCase.text=Prioriti&ze Case
AutoIngestDashboard.bnShowCaseLog.toolTipText=Display case log file for selected case
AutoIngestDashboard.bnShowCaseLog.text=Show Case &Log
ReviewModeCasePanel.bnShowLog.toolTipText=Display case log file for selected case
CopyFilesPanel.bnCancelPendingJob.text=Ca&ncel
CopyFilesPanel.tbDestinationCase.text=
CopyFilesPanel.cbThrottleNetwork.text=&Throttle Network
@ -298,3 +289,12 @@ AutoIngestDashboard.bnPrioritizeJob.toolTipText=Move this folder to the top of t
AutoIngestDashboard.bnReprocessJob.text=Reprocess Job
AutoIngestDashboard.bnPrioritizeFolder.label=<AutoIngestDashboard.bnPrioritizeJob.text>
AutoIngestDashboard.bnPrioritizeJob.actionCommand=<AutoIngestDashboard.bnPrioritizeJob.text>
AutoIngestCasePanel.rbDays.text=Days
AutoIngestCasePanel.rbWeeks.text=Weeks
AutoIngestCasePanel.rbMonths.text=Months
AutoIngestCasePanel.rbAllCases.text=Everything
AutoIngestCasePanel.bnRefresh.text=&Refresh
AutoIngestCasePanel.bnOpen.text=&Open
AutoIngestCasePanel.bnShowLog.toolTipText=Display case log file for selected case
AutoIngestCasePanel.bnShowLog.text=&Show Log
AutoIngestCasePanel.rbGroupLabel.text=Show Last 10:

Some files were not shown because too many files have changed in this diff Show More