mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 2094-ExportImportFilesSets
This commit is contained in:
commit
f0ea129bde
@ -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>
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.crDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.updateCaseNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.deleteCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.caseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.examinerLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.lbDbType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesPanel.lbDbName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
@ -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;
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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())) {
|
||||
|
@ -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
|
171
Core/src/org/sleuthkit/autopsy/framework/AutopsyService.java
Normal file
171
Core/src/org/sleuthkit/autopsy/framework/AutopsyService.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
52
Core/src/org/sleuthkit/autopsy/framework/ProgressPanel.form
Normal file
52
Core/src/org/sleuthkit/autopsy/framework/ProgressPanel.form
Normal 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, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JProgressBar" name="progressBar">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
90
Core/src/org/sleuthkit/autopsy/framework/ProgressPanel.java
Normal file
90
Core/src/org/sleuthkit/autopsy/framework/ProgressPanel.java
Normal 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
|
||||
}
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="2"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Container class="javax.swing.JScrollPane" name="filterDescPane">
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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<>();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
@ -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;
|
71
Core/src/org/sleuthkit/autopsy/test/TestAutopsyService.java
Normal file
71
Core/src/org/sleuthkit/autopsy/test/TestAutopsyService.java
Normal 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
@ -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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnRefresh.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbAllCases.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbMonths.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbWeeks.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbDays.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.rbGroupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnShowLog.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestCasePanel.bnShowLog.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user