mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Fix assorted Case action bugs
This commit is contained in:
parent
a4d2196484
commit
ee43f71137
@ -96,10 +96,10 @@ Case.databaseConnectionInfo.error.msg=Error accessing database server connection
|
||||
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.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-user.
|
||||
Case.checkImgExist.confDlg.doesntExist.msg={0} has detected that one of the images associated with \n\
|
||||
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\
|
||||
this case are missing. Would you like to search for them now?\n\
|
||||
Previously, the image was located at\:\n\
|
||||
{1}\n\
|
||||
{0}\n\
|
||||
Please note that you will still be able to browse directories and generate reports\n\
|
||||
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
|
||||
@ -136,12 +136,6 @@ IntervalErrorReport.NewIssues=new issue(s)
|
||||
IntervalErrorReport.TotalIssues=total issue(s)
|
||||
IntervalErrorReport.ErrorText=Database Connection Error
|
||||
CasePropertiesAction.window.title=Case Properties
|
||||
CasePropertiesForm.updateCaseName.msgDlg.empty.msg=The caseName cannot be empty.
|
||||
CasePropertiesForm.updateCaseName.msgDlg.empty.title=Error
|
||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg=The Case Name cannot contain any of this following symbol\: \\ / \: * ? " < > |
|
||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title=Error
|
||||
CasePropertiesForm.updateCaseName.confMsg.msg=Are you sure you want to update the case name from "{0}" to "{1}"?
|
||||
CasePropertiesForm.updateCaseName.confMsg.title=Change Case Name
|
||||
CueBannerPanel.title.text=Open Recent Case
|
||||
GeneralFilter.rawImageDesc.text=Raw Images (*.img, *.dd, *.001, *.aa, *.raw, *.bin)
|
||||
GeneralFilter.encaseImageDesc.text=Encase Images (*.e01)
|
||||
|
@ -73,10 +73,6 @@ Case.getCurCase.exception.noneOpen=\u4f5c\u696d\u4e2d\u306e\u30b1\u30fc\u30b9\u3
|
||||
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.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.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
|
||||
@ -99,10 +95,6 @@ CaseDeleteAction.msgDlg.caseDelete.msg=\u30b1\u30fc\u30b9\u304c\u524a\u9664\u305
|
||||
CaseOpenAction.autFilter.title={0} \u30b1\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb ( {1})
|
||||
CaseOpenAction.msgDlg.cantOpenCase.title=\u30b1\u30fc\u30b9\u3092\u958b\u304f\u969b\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
|
||||
CasePropertiesAction.window.title=\u30b1\u30fc\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3
|
||||
CasePropertiesForm.updateCaseName.msgDlg.empty.msg=\u30b1\u30fc\u30b9\u540d\u306f\u7a7a\u767d\u3067\u306f\u3044\u3051\u307e\u305b\u3093\u3002
|
||||
CasePropertiesForm.updateCaseName.msgDlg.empty.title=\u30a8\u30e9\u30fc
|
||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg=\u30b1\u30fc\u30b9\u540d\u306b\u306f\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u307e\u305b\u3093\uff1a\\ / \: * ? " < > |
|
||||
CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title=\u30a8\u30e9\u30fc
|
||||
CueBannerPanel.title.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
|
||||
GeneralFilter.rawImageDesc.text=\u30ed\u30fc\u30a4\u30e1\u30fc\u30b8(*.img, *.dd, *.001, *.aa, *.raw, *.bin)
|
||||
GeneralFilter.encaseImageDesc.text=\u30a8\u30f3\u30b1\u30fc\u30b9\u30a4\u30e1\u30fc\u30b8(*.e01)
|
||||
|
File diff suppressed because it is too large
Load Diff
49
Core/src/org/sleuthkit/autopsy/casemodule/CaseActionCancelledException.java
Executable file
49
Core/src/org/sleuthkit/autopsy/casemodule/CaseActionCancelledException.java
Executable file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2017 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
/**
|
||||
* Exception thrown when a case action (e.g., create, open, close, delete) is
|
||||
* cancelled before it is completed.
|
||||
*/
|
||||
class CaseActionCancelledException extends CaseActionException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||
* close, delete) is cancelled before it is completed.
|
||||
*
|
||||
* @param message An error message.
|
||||
*/
|
||||
CaseActionCancelledException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||
* close, delete) is cancelled before it is completed.
|
||||
*
|
||||
* @param message An error message.
|
||||
* @param cause An excception that caused this exception to be thrown.
|
||||
*/
|
||||
CaseActionCancelledException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 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.
|
||||
@ -19,15 +19,30 @@
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
/**
|
||||
* Exception thrown when case action (such as open, close, create) resulted in
|
||||
* an error
|
||||
* Exception thrown when a case action (e.g., create, open, close, delete)
|
||||
* experiences an error condition.
|
||||
*/
|
||||
public class CaseActionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||
* close, delete) experiences an error condition.
|
||||
*
|
||||
* @param message An error message.
|
||||
*/
|
||||
public CaseActionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an exception thrown when a case action (e.g., create, open,
|
||||
* close, delete) experiences an error condition.
|
||||
*
|
||||
* @param message An error message.
|
||||
* @param cause An excception that caused this exception to be thrown.
|
||||
*/
|
||||
public CaseActionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
/*
|
||||
* 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");
|
||||
* 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.
|
||||
@ -19,10 +19,6 @@
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
|
||||
@ -32,44 +28,40 @@ import org.openide.util.NbBundle.Messages;
|
||||
*/
|
||||
class CaseInformationPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CaseInformationPanel.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates new form CaseInformationPanel
|
||||
* Constructs a panel for displaying the case information, including both
|
||||
* case details and ingest job history.
|
||||
*/
|
||||
CaseInformationPanel() {
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
@Messages({"CaseInformationPanel.caseDetails.header=Case Details",
|
||||
"CaseInformationPanel.ingestJobInfo.header=Ingest History",
|
||||
"CaseInformationPanel.loadMetadataFail.message=Failed to load case metadata.",
|
||||
"CaseInformationPanel.loadMetadataFail.title=Metadata load failure",})
|
||||
@Messages({
|
||||
"CaseInformationPanel.caseDetails.header=Case Details",
|
||||
"CaseInformationPanel.ingestJobInfo.header=Ingest History"
|
||||
})
|
||||
private void customizeComponents() {
|
||||
try {
|
||||
Case currentCase = Case.getCurrentCase();
|
||||
String crDate = currentCase.getCreatedDate();
|
||||
String caseDir = currentCase.getCaseDirectory();
|
||||
|
||||
// put the image paths information into hashmap
|
||||
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
|
||||
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());
|
||||
this.tabbedPane.addChangeListener((ChangeEvent e) -> {
|
||||
tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize());
|
||||
});
|
||||
} catch (CaseMetadata.CaseMetadataException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to load case metadata.", ex);
|
||||
JOptionPane.showMessageDialog(null, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
CasePropertiesPanel propertiesPanel = new CasePropertiesPanel(Case.getCurrentCase());
|
||||
propertiesPanel.setSize(propertiesPanel.getPreferredSize());
|
||||
this.tabbedPane.addTab(Bundle.CaseInformationPanel_caseDetails_header(), propertiesPanel);
|
||||
this.tabbedPane.addTab(Bundle.CaseInformationPanel_ingestJobInfo_header(), new IngestJobInfoPanel());
|
||||
this.tabbedPane.addChangeListener((ChangeEvent e) -> {
|
||||
tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an action listener to the Close button of the panel.
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
void addCloseButtonAction(ActionListener action) {
|
||||
this.closeButton.addActionListener(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -127,7 +119,7 @@ class CaseInformationPanel extends javax.swing.JPanel {
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
|
||||
// TODO add your handling code here:
|
||||
// Used by CasePropertiesAction
|
||||
}//GEN-LAST:event_closeButtonActionPerformed
|
||||
|
||||
|
||||
|
@ -54,7 +54,9 @@ 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)");
|
||||
|
||||
//fields from schema version 1
|
||||
/*
|
||||
* Fields from schema version 1
|
||||
*/
|
||||
private static final String SCHEMA_VERSION_ONE = "1.0";
|
||||
private final static String ROOT_ELEMENT_NAME = "AutopsyCase"; //NON-NLS
|
||||
private final static String SCHEMA_VERSION_ELEMENT_NAME = "SchemaVersion"; //NON-NLS
|
||||
@ -68,22 +70,28 @@ public final class CaseMetadata {
|
||||
private final static String CASE_DATABASE_NAME_ELEMENT_NAME = "DatabaseName"; //NON-NLS
|
||||
private final static String TEXT_INDEX_NAME_ELEMENT = "TextIndexName"; //NON-NLS
|
||||
|
||||
//fields from schema version 2
|
||||
/*
|
||||
* Fields from schema version 2
|
||||
*/
|
||||
private static final String SCHEMA_VERSION_TWO = "2.0";
|
||||
private final static String AUTOPSY_CREATED_BY_ELEMENT_NAME = "CreatedByAutopsyVersion"; //NON-NLS
|
||||
private final static String CASE_DATABASE_ABSOLUTE_PATH_ELEMENT_NAME = "Database"; //NON-NLS
|
||||
private final static String CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME = "Database"; //NON-NLS
|
||||
private final static String TEXT_INDEX_ELEMENT = "TextIndex"; //NON-NLS
|
||||
|
||||
//fields from schema version 3
|
||||
/*
|
||||
* Fields from schema version 3
|
||||
*/
|
||||
private static final String SCHEMA_VERSION_THREE = "3.0";
|
||||
private final static String CASE_DISPLAY_NAME_ELEMENT_NAME = "DisplayName"; //NON-NLS
|
||||
private final static String CASE_DATABASE_NAME_RELATIVE_ELEMENT_NAME = "CaseDatabase"; //NON-NLS
|
||||
private final static String CASE_DB_NAME_RELATIVE_ELEMENT_NAME = "CaseDatabase"; //NON-NLS
|
||||
|
||||
//unread fields, these are regenerated on save
|
||||
/*
|
||||
* Unread fields, regenerated on save.
|
||||
*/
|
||||
private final static String MODIFIED_DATE_ELEMENT_NAME = "ModifiedDate"; //NON-NLS
|
||||
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
|
||||
|
||||
private static final String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_THREE;
|
||||
private final static String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_THREE;
|
||||
|
||||
private final Path metadataFilePath;
|
||||
private Case.CaseType caseType;
|
||||
@ -92,8 +100,8 @@ public final class CaseMetadata {
|
||||
private String caseNumber;
|
||||
private String examiner;
|
||||
private String caseDatabaseName;
|
||||
private String caseDatabasePath;
|
||||
private String textIndexName;
|
||||
private String caseDatabasePath; // Legacy
|
||||
private String textIndexName; // Legacy
|
||||
private String createdDate;
|
||||
private String createdByVersion;
|
||||
|
||||
@ -107,8 +115,9 @@ 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.
|
||||
* Constructs a CaseMetadata object for a new case. The metadata is not
|
||||
* persisted to the case metadata file until writeFile or a setX method is
|
||||
* called.
|
||||
*
|
||||
* @param caseDirectory The case directory.
|
||||
* @param caseType The type of case.
|
||||
@ -117,29 +126,24 @@ public final class CaseMetadata {
|
||||
* 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 caseDisplayName, String caseNumber, String examiner, String caseDatabase) throws CaseMetadataException {
|
||||
CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseDisplayName, String caseNumber, String examiner) {
|
||||
metadataFilePath = Paths.get(caseDirectory, caseDisplayName + FILE_EXTENSION);
|
||||
this.caseType = caseType;
|
||||
this.caseName = caseName;
|
||||
this.caseDisplayName = caseDisplayName;
|
||||
this.caseNumber = caseNumber;
|
||||
this.examiner = examiner;
|
||||
this.caseDatabaseName = caseDatabase;
|
||||
caseDatabaseName = "";
|
||||
caseDatabasePath = "";
|
||||
textIndexName = "";
|
||||
createdByVersion = Version.getVersion();
|
||||
createdDate = CaseMetadata.DATE_FORMAT.format(new Date());
|
||||
writeToFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an object that provides access to the case metadata stored in
|
||||
* an existing case metadata file.
|
||||
* Constructs a CaseMetadata object for an existing case. The metadata is
|
||||
* read from an existing case metadata file.
|
||||
*
|
||||
* @param metadataFilePath The full path to the case metadata file.
|
||||
*
|
||||
@ -179,7 +183,7 @@ public final class CaseMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immutable case name, set at case creation.
|
||||
* Gets the unique and immutable case name.
|
||||
*
|
||||
* @return The case display name.
|
||||
*/
|
||||
@ -193,22 +197,23 @@ public final class CaseMetadata {
|
||||
* @return The case display name.
|
||||
*/
|
||||
public String getCaseDisplayName() {
|
||||
return this.caseDisplayName;
|
||||
return caseDisplayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the case display name. This does not change the name of the case
|
||||
* directory, the case database, or the text index name.
|
||||
* Sets the case display name.
|
||||
*
|
||||
* @param caseName A case display name.
|
||||
* @param caseDisplayName A case display name.
|
||||
*
|
||||
* @throws CaseMetadataException If the operation fails.
|
||||
*/
|
||||
void setCaseDisplayName(String caseName) throws CaseMetadataException {
|
||||
String oldCaseName = caseName;
|
||||
this.caseDisplayName = caseName;
|
||||
void setCaseDisplayName(String caseDisplayName) throws CaseMetadataException {
|
||||
String oldCaseDisplayName = this.caseDisplayName;
|
||||
this.caseDisplayName = caseDisplayName;
|
||||
try {
|
||||
writeToFile();
|
||||
} catch (CaseMetadataException ex) {
|
||||
this.caseDisplayName = oldCaseName;
|
||||
this.caseDisplayName = oldCaseDisplayName;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@ -234,32 +239,35 @@ public final class CaseMetadata {
|
||||
/**
|
||||
* Gets the name of the case database.
|
||||
*
|
||||
* @return The case database name.
|
||||
* @return The case database name, may be empty.
|
||||
*/
|
||||
public String getCaseDatabaseName() {
|
||||
return caseDatabaseName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text index name.
|
||||
* Sets the name of the case database.
|
||||
*
|
||||
* @param caseTextIndexName The text index name.
|
||||
* @param caseDatabaseName The case database name.
|
||||
*
|
||||
* @throws CaseMetadataException If the operation fails.
|
||||
*/
|
||||
void setTextIndexName(String caseTextIndexName) throws CaseMetadataException {
|
||||
String oldIndexName = caseTextIndexName;
|
||||
this.textIndexName = caseTextIndexName;
|
||||
void setCaseDatabaseName(String caseDatabaseName) throws CaseMetadataException {
|
||||
String oldCaseDatabaseName = this.caseDatabaseName;
|
||||
this.caseDatabaseName = caseDatabaseName;
|
||||
try {
|
||||
writeToFile();
|
||||
} catch (CaseMetadataException ex) {
|
||||
this.textIndexName = oldIndexName;
|
||||
this.caseDatabaseName = oldCaseDatabaseName;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text index name.
|
||||
* Gets the text index name. This is a legacy field and will be empty for
|
||||
* cases created with Autopsy 4.4.0 and above.
|
||||
*
|
||||
* @return The name of the text index for the case.
|
||||
* @return The name of the text index for the case, may be empty.
|
||||
*/
|
||||
public String getTextIndexName() {
|
||||
return textIndexName;
|
||||
@ -268,7 +276,7 @@ public final class CaseMetadata {
|
||||
/**
|
||||
* Gets the date the case was created.
|
||||
*
|
||||
* @return The date this case was created as a string
|
||||
* @return The date this case was created, as a string.
|
||||
*/
|
||||
String getCreatedDate() {
|
||||
return createdDate;
|
||||
@ -278,7 +286,9 @@ public final class CaseMetadata {
|
||||
* Sets the date the case was created. Used for preserving the case creation
|
||||
* date during single-user to multi-user case conversion.
|
||||
*
|
||||
* @param createdDate The date the case was created as a string.
|
||||
* @param createdDate The date the case was created, as a string.
|
||||
*
|
||||
* @throws CaseMetadataException If the operation fails.
|
||||
*/
|
||||
void setCreatedDate(String createdDate) throws CaseMetadataException {
|
||||
String oldCreatedDate = createdDate;
|
||||
@ -304,13 +314,15 @@ public final class CaseMetadata {
|
||||
* Sets the Autopsy version that created the case. Used for preserving this
|
||||
* metadata during single-user to multi-user case conversion.
|
||||
*
|
||||
* @param buildVersion An build version identifier.
|
||||
* @param buildVersion A build version identifier.
|
||||
*
|
||||
* @throws CaseMetadataException If the operation fails.
|
||||
*/
|
||||
void setCreatedByVersion(String buildVersion) throws CaseMetadataException {
|
||||
String oldCreatedByVersion = this.createdByVersion;
|
||||
this.createdByVersion = buildVersion;
|
||||
try {
|
||||
this.writeToFile();
|
||||
writeToFile();
|
||||
} catch (CaseMetadataException ex) {
|
||||
this.createdByVersion = oldCreatedByVersion;
|
||||
throw ex;
|
||||
@ -381,8 +393,8 @@ public final class CaseMetadata {
|
||||
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_ABSOLUTE_PATH_ELEMENT_NAME, caseDatabasePath);
|
||||
createChildElement(doc, caseElement, CASE_DATABASE_NAME_RELATIVE_ELEMENT_NAME, caseDatabaseName);
|
||||
createChildElement(doc, caseElement, CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME, caseDatabasePath);
|
||||
createChildElement(doc, caseElement, CASE_DB_NAME_RELATIVE_ELEMENT_NAME, caseDatabaseName);
|
||||
createChildElement(doc, caseElement, TEXT_INDEX_ELEMENT, textIndexName);
|
||||
}
|
||||
|
||||
@ -451,15 +463,19 @@ public final class CaseMetadata {
|
||||
if (null == this.caseType) {
|
||||
throw new CaseMetadataException("Case metadata file corrupted");
|
||||
}
|
||||
if (schemaVersion.equals(SCHEMA_VERSION_ONE)) {
|
||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
|
||||
} else if (schemaVersion.equals(SCHEMA_VERSION_TWO)) {
|
||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_ABSOLUTE_PATH_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
||||
} else {
|
||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_RELATIVE_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
||||
switch (schemaVersion) {
|
||||
case SCHEMA_VERSION_ONE:
|
||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DATABASE_NAME_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_NAME_ELEMENT, true);
|
||||
break;
|
||||
case SCHEMA_VERSION_TWO:
|
||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
||||
break;
|
||||
default:
|
||||
this.caseDatabaseName = getElementTextContent(caseElement, CASE_DB_NAME_RELATIVE_ELEMENT_NAME, true);
|
||||
this.textIndexName = getElementTextContent(caseElement, TEXT_INDEX_ELEMENT, false);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -489,7 +505,7 @@ public final class CaseMetadata {
|
||||
* @param elementName The element name.
|
||||
* @param contentIsRequired Whether or not the content is required.
|
||||
*
|
||||
* @return The text content, may be empty if not required.
|
||||
* @return The text content, may be empty If not required.
|
||||
*
|
||||
* @throws CaseMetadataException If the element is missing or content is
|
||||
* required and it is empty.
|
||||
@ -530,7 +546,7 @@ public final class CaseMetadata {
|
||||
* @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 Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getCaseDatabasePath() throws UnsupportedOperationException {
|
||||
|
@ -125,13 +125,15 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
StartupWindowProvider.getInstance().open();
|
||||
} catch (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.getCause().getMessage(), //get the message of the wrapped exception
|
||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||
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.getCause().getMessage(), //get the message of the wrapped exception
|
||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
StartupWindowProvider.getInstance().open();
|
||||
}
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
|
@ -22,7 +22,6 @@ import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -43,11 +42,11 @@ final class CasePropertiesAction extends CallableSystemAction {
|
||||
CasePropertiesAction() {
|
||||
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) {
|
||||
setEnabled(null != evt.getNewValue());
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), (PropertyChangeEvent evt) -> {
|
||||
if (null == evt.getNewValue()) {
|
||||
casePropertiesDialog = null;
|
||||
}
|
||||
setEnabled(null != evt.getNewValue());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -16,63 +16,57 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sleuthkit.autopsy.casemodule;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import org.openide.DialogDescriptor;
|
||||
import org.openide.DialogDisplayer;
|
||||
import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
|
||||
/**
|
||||
* A panel that allows the user to view various properties of the current case
|
||||
* and change the display name of the case.
|
||||
* A panel that allows the user to view various properties of a case and change
|
||||
* the display name of the case.
|
||||
*/
|
||||
class CasePropertiesPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Case current = null;
|
||||
private static JPanel caller; // panel for error
|
||||
private static final Logger LOGGER = Logger.getLogger(CasePropertiesPanel.class.getName());
|
||||
private final Case theCase;
|
||||
|
||||
CasePropertiesPanel(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) throws CaseMetadata.CaseMetadataException {
|
||||
/**
|
||||
* Constructs a panel that allows the user to view various properties of the
|
||||
* current case and change the display name of the case.
|
||||
*
|
||||
* @param aCase A case.
|
||||
*/
|
||||
CasePropertiesPanel(Case aCase) {
|
||||
initComponents();
|
||||
caseNameTextField.setText(currentCase.getDisplayName());
|
||||
String caseNumber = currentCase.getNumber();
|
||||
theCase = aCase;
|
||||
caseNameTextField.setText(theCase.getDisplayName());
|
||||
String caseNumber = theCase.getNumber();
|
||||
if (!caseNumber.isEmpty()) {
|
||||
caseNumberField.setText(caseNumber);
|
||||
} else {
|
||||
caseNumberField.setText("N/A");
|
||||
}
|
||||
String examiner = currentCase.getExaminer();
|
||||
String examiner = theCase.getExaminer();
|
||||
if (!examiner.isEmpty()) {
|
||||
examinerField.setText(examiner);
|
||||
} else {
|
||||
examinerField.setText("N/A");
|
||||
}
|
||||
crDateField.setText(crDate);
|
||||
caseDirField.setText(caseDir);
|
||||
current = currentCase;
|
||||
|
||||
CaseMetadata caseMetadata = currentCase.getCaseMetadata();
|
||||
if (caseMetadata.getCaseType() == Case.CaseType.SINGLE_USER_CASE) {
|
||||
dbNameField.setText(Paths.get(caseMetadata.getCaseDirectory(), caseMetadata.getCaseDatabaseName()).toString());
|
||||
crDateField.setText(theCase.getCreatedDate());
|
||||
caseDirField.setText(theCase.getCaseDirectory());
|
||||
if (Case.CaseType.SINGLE_USER_CASE == theCase.getCaseType()) {
|
||||
dbNameField.setText(Paths.get(theCase.getCaseDirectory(), theCase.getMetadata().getCaseDatabaseName()).toString());
|
||||
} else {
|
||||
dbNameField.setText(caseMetadata.getCaseDatabaseName());
|
||||
}
|
||||
Case.CaseType caseType = caseMetadata.getCaseType();
|
||||
caseTypeField.setText(caseType.getLocalizedDisplayName());
|
||||
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
|
||||
deleteCaseButton.setEnabled(true);
|
||||
} else {
|
||||
deleteCaseButton.setEnabled(false);
|
||||
dbNameField.setText(theCase.getMetadata().getCaseDatabaseName());
|
||||
}
|
||||
Case.CaseType caseType = theCase.getCaseType();
|
||||
caseTypeField.setText(caseType.getLocalizedDisplayName());
|
||||
deleteCaseButton.setEnabled(Case.CaseType.SINGLE_USER_CASE == caseType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,59 +253,35 @@ class CasePropertiesPanel extends javax.swing.JPanel {
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
/**
|
||||
* Updates the case name.
|
||||
* Updates the case display name.
|
||||
*
|
||||
* @param evt The action event
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CasePropertiesPanel.errorDialog.emptyCaseNameMessage=No case name entered.",
|
||||
"CasePropertiesPanel.errorDialog.invalidCaseNameMessage=Case names cannot include the following symbols: \\, /, :, *, ?, \", <, >, |"
|
||||
})
|
||||
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
|
||||
String oldCaseName = Case.getCurrentCase().getDisplayName();
|
||||
String newCaseName = caseNameTextField.getText();
|
||||
// check if the old and new case name is not equal
|
||||
if (!oldCaseName.equals(newCaseName)) {
|
||||
String newCaseDisplayName = caseNameTextField.getText();
|
||||
if (newCaseDisplayName.equals(theCase.getDisplayName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the case name is empty
|
||||
if (newCaseName.trim().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(caller,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"CasePropertiesForm.updateCaseName.msgDlg.empty.title"),
|
||||
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);
|
||||
if (newCaseDisplayName.trim().isEmpty()) {
|
||||
MessageNotifyUtil.Message.error(Bundle.CasePropertiesPanel_errorDialog_emptyCaseNameMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Case.isValidName(newCaseDisplayName)) {
|
||||
MessageNotifyUtil.Message.error(Bundle.CasePropertiesPanel_errorDialog_invalidCaseNameMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
theCase.updateDisplayName(newCaseDisplayName);
|
||||
} catch (CaseActionException ex) {
|
||||
MessageNotifyUtil.Message.error(ex.getLocalizedMessage());
|
||||
LOGGER.log(Level.SEVERE, "Failed to update case display name", ex); //NON-NLS
|
||||
}
|
||||
}//GEN-LAST:event_updateCaseNameButtonActionPerformed
|
||||
|
||||
|
@ -94,15 +94,17 @@ final class NewCaseWizardAction extends CallableSystemAction {
|
||||
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
|
||||
addImageAction.actionPerformed(null);
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
|
||||
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);
|
||||
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||
logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS
|
||||
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);
|
||||
}
|
||||
doFailedCaseCleanup(wizardDescriptor);
|
||||
StartupWindowProvider.getInstance().close();
|
||||
StartupWindowProvider.getInstance().open();
|
||||
doFailedCaseCleanup(wizardDescriptor);
|
||||
} finally {
|
||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
|
@ -38,29 +38,21 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
|
||||
/**
|
||||
* The "New Case" wizard panel with a component on it. This class represents
|
||||
* data of wizard step. It defers creation and initialization of UI component of
|
||||
* wizard panel into getComponent() method.
|
||||
* The first panel of the New Case wizard.
|
||||
*/
|
||||
class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
|
||||
|
||||
/**
|
||||
* The visual component that displays this panel. If you need to access the
|
||||
* component from this class, just use getComponent().
|
||||
*/
|
||||
private NewCaseVisualPanel1 component;
|
||||
private Boolean isFinish = false;
|
||||
private static String createdDirectory;
|
||||
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
|
||||
private static final Logger logger = Logger.getLogger(NewCaseWizardPanel1.class.getName());
|
||||
private static final String PROP_BASECASE = "LBL_BaseCase_PATH"; //NON-NLS
|
||||
private static String createdDirectory;
|
||||
private final Set<ChangeListener> listeners = new HashSet<>(1);
|
||||
private NewCaseVisualPanel1 component;
|
||||
private boolean isFinish;
|
||||
|
||||
/**
|
||||
* Get the visual component for the panel. In this template, the component
|
||||
* is kept separate. This can be more efficient: if the wizard is created
|
||||
* but never displayed, or not all panels are displayed, it is better to
|
||||
* create only those which really need to be visible.
|
||||
* Get the visual component for the panel.
|
||||
*
|
||||
* @return component the UI component of this wizard panel
|
||||
* @return The UI component of this wizard panel
|
||||
*/
|
||||
@Override
|
||||
public NewCaseVisualPanel1 getComponent() {
|
||||
@ -71,65 +63,57 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
}
|
||||
|
||||
/**
|
||||
* Help for this panel. When the panel is active, this is used as the help
|
||||
* for the wizard dialog.
|
||||
* Gets the help object for this panel. When the panel is active, this is
|
||||
* used as the help for the wizard dialog.
|
||||
*
|
||||
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||
* @return The help for this panel.
|
||||
*/
|
||||
@Override
|
||||
public HelpCtx getHelp() {
|
||||
// Show no Help button for this panel:
|
||||
/*
|
||||
* Currently, no help is provided for this panel.
|
||||
*/
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
// If you have context help:
|
||||
// return new HelpCtx(SampleWizardPanel1.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the panel is finished. If the panel is valid, the "Finish"
|
||||
* button will be enabled.
|
||||
*
|
||||
* @return boolean true if all the fields are correctly filled, false
|
||||
* otherwise
|
||||
* @return boolean True if all the fields are correctly filled, false
|
||||
* otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
// If it is always OK to press Next or Finish, then:
|
||||
return isFinish;
|
||||
// If it depends on some condition (form filled out...), then:
|
||||
// return someCondition();
|
||||
// and when this condition changes (last form field filled in...) then:
|
||||
// fireChangeEvent();
|
||||
// and uncomment the complicated stuff below.
|
||||
}
|
||||
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.
|
||||
* Adds a change listener to this panel.
|
||||
*
|
||||
* @param l the change listener to add
|
||||
* @param listener The change listener to add.
|
||||
*/
|
||||
@Override
|
||||
public final void addChangeListener(ChangeListener l) {
|
||||
public final void addChangeListener(ChangeListener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.add(l);
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener to changes of the panel's validity.
|
||||
* Removes a change listener from this panel.
|
||||
*
|
||||
* @param l the change listener to move
|
||||
* @param listener The change listener to remove.
|
||||
*/
|
||||
@Override
|
||||
public final void removeChangeListener(ChangeListener l) {
|
||||
public final void removeChangeListener(ChangeListener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.remove(l);
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is auto-generated. It seems that this method is used to
|
||||
* listen to any change in this wizard panel.
|
||||
* Notifies any registerd change listeners of a change in the panel.
|
||||
*/
|
||||
protected final void fireChangeEvent() {
|
||||
Iterator<ChangeListener> it;
|
||||
@ -153,12 +137,8 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
// You can use a settings object to keep track of state. Normally the
|
||||
// settings object will be the WizardDescriptor, so you can use
|
||||
// WizardDescriptor.getProperty & putProperty to store information entered
|
||||
// by the user.
|
||||
/**
|
||||
* Provides the wizard panel with the current data--either the default data
|
||||
* Provides the wizard panel with the current data - either the default data
|
||||
* or already-modified settings, if the user used the previous and/or next
|
||||
* buttons. This method can be called multiple times on one instance of
|
||||
* WizardDescriptor.Panel.
|
||||
@ -322,4 +302,5 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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");
|
||||
@ -28,35 +28,19 @@ import org.openide.WizardValidationException;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.windows.WindowManager;
|
||||
import java.awt.Cursor;
|
||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||
|
||||
/**
|
||||
* The "New Case" wizard panel with a component on it. This class represents
|
||||
* data of wizard step. It defers creation and initialization of UI component of
|
||||
* wizard panel into getComponent() method.
|
||||
*
|
||||
* @author jantonius
|
||||
* The second panel of the New Case wizard.
|
||||
*/
|
||||
class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
|
||||
|
||||
/**
|
||||
* The visual component that displays this panel. If you need to access the
|
||||
* component from this class, just use getComponent().
|
||||
*/
|
||||
private NewCaseVisualPanel2 component;
|
||||
private Boolean isFinish = true;
|
||||
private String caseName;
|
||||
private String caseDir;
|
||||
private String createdDirectory;
|
||||
private CaseType caseType;
|
||||
private final Set<ChangeListener> listeners = new HashSet<>(1);
|
||||
|
||||
/**
|
||||
* Get the visual component for the panel. In this template, the component
|
||||
* is kept separate. This can be more efficient: if the wizard is created
|
||||
* but never displayed, or not all panels are displayed, it is better to
|
||||
* create only those which really need to be visible.
|
||||
* Get the visual component for the panel.
|
||||
*
|
||||
* @return component the UI component of this wizard panel
|
||||
* @return component The UI component of this wizard panel.
|
||||
*/
|
||||
@Override
|
||||
public NewCaseVisualPanel2 getComponent() {
|
||||
@ -67,17 +51,17 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
}
|
||||
|
||||
/**
|
||||
* Help for this panel. When the panel is active, this is used as the help
|
||||
* for the wizard dialog.
|
||||
* Gets the help object for this panel. When the panel is active, this is
|
||||
* used as the help for the wizard dialog.
|
||||
*
|
||||
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||
* @return The help for this panel.
|
||||
*/
|
||||
@Override
|
||||
public HelpCtx getHelp() {
|
||||
// Show no Help button for this panel:
|
||||
/*
|
||||
* Currently, no help is provided for this panel.
|
||||
*/
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
// If you have context help:
|
||||
// return new HelpCtx(SampleWizardPanel1.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,43 +73,35 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
// If it is always OK to press Next or Finish, then:
|
||||
return isFinish;
|
||||
// If it depends on some condition (form filled out...), then:
|
||||
// return someCondition();
|
||||
// and when this condition changes (last form field filled in...) then:
|
||||
// fireChangeEvent();
|
||||
// and uncomment the complicated stuff below.
|
||||
return true;
|
||||
}
|
||||
private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
|
||||
|
||||
/**
|
||||
* Adds a listener to changes of the panel's validity.
|
||||
* Adds a change listener to this panel.
|
||||
*
|
||||
* @param l the change listener to add
|
||||
* @param listener The change listener to add.
|
||||
*/
|
||||
@Override
|
||||
public final void addChangeListener(ChangeListener l) {
|
||||
public final void addChangeListener(ChangeListener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.add(l);
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener to changes of the panel's validity.
|
||||
* Removes a change listener from this panel.
|
||||
*
|
||||
* @param l the change listener to move
|
||||
* @param listener The change listener to remove.
|
||||
*/
|
||||
@Override
|
||||
public final void removeChangeListener(ChangeListener l) {
|
||||
public final void removeChangeListener(ChangeListener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.remove(l);
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is auto-generated. It seems that this method is used to
|
||||
* listen to any change in this wizard panel.
|
||||
* Notifies any registerd change listeners of a change in the panel.
|
||||
*/
|
||||
protected final void fireChangeEvent() {
|
||||
Iterator<ChangeListener> it;
|
||||
@ -138,10 +114,6 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
}
|
||||
}
|
||||
|
||||
// You can use a settings object to keep track of state. Normally the
|
||||
// settings object will be the WizardDescriptor, so you can use
|
||||
// WizardDescriptor.getProperty & putProperty to store information entered
|
||||
// by the user.
|
||||
/**
|
||||
* Provides the wizard panel with the current data--either the default data
|
||||
* or already-modified settings, if the user used the previous and/or next
|
||||
@ -152,10 +124,6 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
||||
*/
|
||||
@Override
|
||||
public void readSettings(WizardDescriptor settings) {
|
||||
caseName = (String) settings.getProperty("caseName"); //NON-NLS
|
||||
caseDir = (String) settings.getProperty("caseParentDir"); //NON-NLS
|
||||
createdDirectory = (String) settings.getProperty("createdDirectory"); //NON-NLS
|
||||
caseType = CaseType.values()[(int) settings.getProperty("caseType")]; //NON-NLS
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,13 +125,15 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
||||
try {
|
||||
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(() -> {
|
||||
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 (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", casePath), ex); //NON-NLS
|
||||
JOptionPane.showMessageDialog(
|
||||
WindowManager.getDefault().getMainWindow(),
|
||||
ex.getMessage(), // Should be user-friendly
|
||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
StartupWindowProvider.getInstance().open();
|
||||
});
|
||||
}
|
||||
|
@ -407,9 +407,11 @@ final class RecentCases extends CallableSystemAction implements Presenter.Menu {
|
||||
String[] casePaths = new String[LENGTH];
|
||||
String currentCasePath = null;
|
||||
try {
|
||||
currentCasePath = Case.getCurrentCase().getCaseMetadata().getFilePath().toString();
|
||||
currentCasePath = Case.getCurrentCase().getMetadata().getFilePath().toString();
|
||||
} catch (IllegalStateException ex) {
|
||||
// in case there is no current case.
|
||||
/*
|
||||
* There may be no current case.
|
||||
*/
|
||||
}
|
||||
|
||||
Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
|
||||
|
@ -65,17 +65,20 @@ class RecentItems implements ActionListener {
|
||||
try {
|
||||
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(() -> {
|
||||
JOptionPane.showMessageDialog(
|
||||
WindowManager.getDefault().getMainWindow(),
|
||||
ex.getMessage(),
|
||||
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
|
||||
logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetaDataFilePath), ex); //NON-NLS
|
||||
JOptionPane.showMessageDialog(
|
||||
WindowManager.getDefault().getMainWindow(),
|
||||
ex.getMessage(),
|
||||
NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
StartupWindowProvider.getInstance().open();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}).
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,8 +204,8 @@ public class SingleUserCaseConverter {
|
||||
icd.getNewCaseName(),
|
||||
icd.getNewCaseName(),
|
||||
oldCaseMetadata.getCaseNumber(),
|
||||
oldCaseMetadata.getExaminer(),
|
||||
dbName);
|
||||
oldCaseMetadata.getExaminer());
|
||||
newCaseMetadata.setCaseDatabaseName(dbName);
|
||||
// Set created date. This calls writefile, no need to call it again
|
||||
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
|
||||
newCaseMetadata.setCreatedByVersion(oldCaseMetadata.getCreatedByVersion());
|
||||
|
@ -59,7 +59,7 @@ public final class LoggingProgressIndicator implements ProgressIndicator {
|
||||
|
||||
@Override
|
||||
public void progress(int workUnitsCompleted) {
|
||||
LOGGER.log(Level.INFO, "{1} of {2} total work units completed", new Object[]{workUnitsCompleted, this.totalWorkUnits});
|
||||
LOGGER.log(Level.INFO, "{0} of {1} total work units completed", new Object[]{workUnitsCompleted, this.totalWorkUnits});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,8 +68,8 @@ public final class LoggingProgressIndicator implements ProgressIndicator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(String message) {
|
||||
LOGGER.log(Level.INFO, "{0} finished", message);
|
||||
public void finish() {
|
||||
LOGGER.log(Level.INFO, "Finished");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.framework;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.DialogDescriptor;
|
||||
@ -30,14 +32,17 @@ 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.
|
||||
* with a button listener. Setting a cancelling flag which locks in a cancelling
|
||||
* message and an indeterminate progress bar is supported.
|
||||
*/
|
||||
@ThreadSafe
|
||||
public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
|
||||
private final Frame parent;
|
||||
private final ProgressPanel progressPanel;
|
||||
private final Dialog dialog;
|
||||
private final ActionListener buttonListener;
|
||||
@GuardedBy("this")
|
||||
private boolean cancelling;
|
||||
|
||||
/**
|
||||
* Creates a progress indicator that displays progress using a modal dialog
|
||||
@ -54,6 +59,7 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
public ModalDialogProgressIndicator(Frame parent, String title, Object[] buttonLabels, Object focusedButtonLabel, ActionListener buttonListener) {
|
||||
this.parent = parent;
|
||||
progressPanel = new ProgressPanel();
|
||||
progressPanel.setIndeterminate(true);
|
||||
DialogDescriptor dialogDescriptor = new DialogDescriptor(
|
||||
progressPanel,
|
||||
title,
|
||||
@ -64,7 +70,6 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
HelpCtx.DEFAULT_HELP,
|
||||
buttonListener);
|
||||
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
||||
this.buttonListener = buttonListener;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,31 +82,10 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
public ModalDialogProgressIndicator(Frame parent, String title) {
|
||||
this.parent = parent;
|
||||
progressPanel = new ProgressPanel();
|
||||
progressPanel.setIndeterminate(true);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,14 +96,14 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @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);
|
||||
}
|
||||
public synchronized void start(String message, int totalWorkUnits) {
|
||||
cancelling = false;
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setIndeterminate(false);
|
||||
progressPanel.setMessage(message);
|
||||
progressPanel.setMaximum(totalWorkUnits);
|
||||
dialog.setLocationRelativeTo(parent);
|
||||
this.dialog.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
@ -130,13 +114,28 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @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);
|
||||
}
|
||||
public synchronized void start(String message) {
|
||||
cancelling = false;
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setIndeterminate(true);
|
||||
progressPanel.setMessage(message);
|
||||
dialog.setLocationRelativeTo(parent);
|
||||
this.dialog.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a cancelling message and makes the progress bar indeterminate. Once
|
||||
* cancel has been called, the progress indicator no longer accepts updates
|
||||
* unless start is called again.
|
||||
*
|
||||
* @param cancellingMessage
|
||||
*/
|
||||
public synchronized void setCancelling(String cancellingMessage) {
|
||||
cancelling = true;
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setIndeterminate(false);
|
||||
progressPanel.setMessage(cancellingMessage);
|
||||
});
|
||||
}
|
||||
|
||||
@ -147,14 +146,13 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @param message The initial progress message.
|
||||
*/
|
||||
@Override
|
||||
public void switchToIndeterminate(String message) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressPanel.setInderminate(true);
|
||||
public synchronized void switchToIndeterminate(String message) {
|
||||
if (!cancelling) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setIndeterminate(true);
|
||||
progressPanel.setMessage(message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,16 +164,15 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @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);
|
||||
public synchronized void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
|
||||
if (!cancelling) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setIndeterminate(false);
|
||||
progressPanel.setMessage(message);
|
||||
progressPanel.setMaximum(totalWorkUnits);
|
||||
progressPanel.setCurrent(workUnitsCompleted);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,13 +181,12 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @param message The progress message.
|
||||
*/
|
||||
@Override
|
||||
public void progress(String message) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
public synchronized void progress(String message) {
|
||||
if (!cancelling) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setMessage(message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,13 +197,12 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @param workUnitsCompleted Number of work units completed so far.
|
||||
*/
|
||||
@Override
|
||||
public void progress(int workUnitsCompleted) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
public synchronized void progress(int workUnitsCompleted) {
|
||||
if (!cancelling) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressPanel.setCurrent(workUnitsCompleted);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,28 +214,22 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
||||
* @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() {
|
||||
public synchronized void progress(String message, int workUnitsCompleted) {
|
||||
if (!cancelling) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
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);
|
||||
}
|
||||
public synchronized void finish() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
this.dialog.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ public interface ProgressIndicator {
|
||||
/**
|
||||
* 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);
|
||||
@ -54,7 +55,7 @@ public interface ProgressIndicator {
|
||||
* 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 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.
|
||||
*/
|
||||
@ -88,9 +89,7 @@ public interface ProgressIndicator {
|
||||
|
||||
/**
|
||||
* Finishes the progress indicator when the task is completed.
|
||||
*
|
||||
* @param message The finished message.
|
||||
*/
|
||||
void finish(String message);
|
||||
void finish();
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class ProgressPanel extends javax.swing.JPanel {
|
||||
this.progressMessage.setText(message);
|
||||
}
|
||||
|
||||
void setInderminate(boolean indeterminate) {
|
||||
void setIndeterminate(boolean indeterminate) {
|
||||
this.progressBar.setIndeterminate(indeterminate);
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ public class SilentProgressIndicator implements ProgressIndicator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(String message) {
|
||||
public void finish() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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,98 +25,99 @@ import org.openide.DialogDisplayer;
|
||||
import org.openide.NotifyDescriptor;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.openide.util.lookup.ServiceProviders;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.framework.AutopsyService;
|
||||
|
||||
@ServiceProviders(value = {@ServiceProvider(service = AutopsyService.class)})
|
||||
|
||||
/**
|
||||
* Creates and handles closing of ImageWriter objects.
|
||||
* Currently, ImageWriter is only enabled for local disks, and local disks can
|
||||
* not be processed in multi user mode. If ImageWriter is ever enabled for multi user
|
||||
* cases this code will need to be revised.
|
||||
* Creates and handles closing of ImageWriter objects. Currently, ImageWriter is
|
||||
* only enabled for local disks, and local disks can not be processed in multi
|
||||
* user mode. If ImageWriter is ever enabled for multi user cases this code will
|
||||
* need to be revised.
|
||||
*/
|
||||
|
||||
@ServiceProvider(service = AutopsyService.class)
|
||||
public class ImageWriterService implements AutopsyService {
|
||||
|
||||
private static final List<ImageWriter> imageWriters = new ArrayList<>(); // Contains all Image Writer objects
|
||||
private static final Object imageWritersLock = new Object(); // Get this lock before accessing currentImageWriters
|
||||
|
||||
|
||||
/**
|
||||
* Create an image writer object for the given data source ID.
|
||||
*
|
||||
* @param imageId ID for the image
|
||||
*/
|
||||
public static void createImageWriter(Long imageId, ImageWriterSettings settings){
|
||||
|
||||
public static void createImageWriter(Long imageId, ImageWriterSettings settings) {
|
||||
|
||||
// ImageWriter objects are created during the addImageTask. They can not arrive while
|
||||
// we're closing case resources so we don't need to worry about one showing up while
|
||||
// doing our close/cleanup.
|
||||
synchronized(imageWritersLock){
|
||||
synchronized (imageWritersLock) {
|
||||
ImageWriter writer = new ImageWriter(imageId, settings);
|
||||
writer.subscribeToEvents();
|
||||
imageWriters.add(writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return NbBundle.getMessage(this.getClass(), "ImageWriterService.serviceName");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void closeCaseResources(CaseContext context) throws AutopsyServiceException {
|
||||
context.getProgressIndicator().progress(NbBundle.getMessage(this.getClass(), "ImageWriterService.waitingForVHDs"));
|
||||
|
||||
synchronized(imageWritersLock){
|
||||
synchronized (imageWritersLock) {
|
||||
if (imageWriters.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.getProgressIndicator().progress(NbBundle.getMessage(this.getClass(), "ImageWriterService.waitingForVHDs"));
|
||||
|
||||
// If any of our ImageWriter objects haven't started the finish task, set the cancel flag
|
||||
// to make sure they don't start now. The reason they haven't started is that
|
||||
// ingest was not complete, and the user already confirmed that they want to exit
|
||||
// even though ingest is not complete so we will take that to mean that they
|
||||
// also don't want to wait for Image Writer.
|
||||
for(ImageWriter writer: imageWriters){
|
||||
for (ImageWriter writer : imageWriters) {
|
||||
writer.cancelIfNotStarted();
|
||||
}
|
||||
|
||||
|
||||
// Test whether any finishImage tasks are in progress
|
||||
boolean jobsAreInProgress = false;
|
||||
for(ImageWriter writer: imageWriters){
|
||||
if(writer.jobIsInProgress()){
|
||||
for (ImageWriter writer : imageWriters) {
|
||||
if (writer.jobIsInProgress()) {
|
||||
jobsAreInProgress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(jobsAreInProgress){
|
||||
|
||||
if (jobsAreInProgress) {
|
||||
// If jobs are in progress, ask the user if they want to wait for them to complete
|
||||
NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
|
||||
NbBundle.getMessage(this.getClass(), "ImageWriterService.shouldWait"),
|
||||
NbBundle.getMessage(this.getClass(), "ImageWriterService.localDisk"),
|
||||
NotifyDescriptor.YES_NO_OPTION,
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
NbBundle.getMessage(this.getClass(), "ImageWriterService.shouldWait"),
|
||||
NbBundle.getMessage(this.getClass(), "ImageWriterService.localDisk"),
|
||||
NotifyDescriptor.YES_NO_OPTION,
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
descriptor.setValue(NotifyDescriptor.NO_OPTION);
|
||||
Object response = DialogDisplayer.getDefault().notify(descriptor);
|
||||
|
||||
if(response == DialogDescriptor.NO_OPTION){
|
||||
|
||||
if (response == DialogDescriptor.NO_OPTION) {
|
||||
// Cancel all the jobs
|
||||
for(ImageWriter writer: imageWriters){
|
||||
for (ImageWriter writer : imageWriters) {
|
||||
writer.cancelJob();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Wait for all finishImage jobs to complete. If the jobs got cancelled
|
||||
// this will be very fast.
|
||||
for(ImageWriter writer: imageWriters){
|
||||
for (ImageWriter writer : imageWriters) {
|
||||
writer.waitForJobToFinish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Stop listening for events
|
||||
for(ImageWriter writer: imageWriters){
|
||||
for (ImageWriter writer : imageWriters) {
|
||||
writer.unsubscribeFromEvents();
|
||||
}
|
||||
|
||||
|
||||
// Clear out the list of Image Writers
|
||||
imageWriters.clear();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class TestAutopsyService implements AutopsyService {
|
||||
progressIndicator.progress(80);
|
||||
Thread.sleep(1000L);
|
||||
progressIndicator.progress(100);
|
||||
progressIndicator.finish("First task completed by Test Autopsy Service.");
|
||||
progressIndicator.finish();
|
||||
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");
|
||||
@ -62,7 +62,7 @@ public class TestAutopsyService implements AutopsyService {
|
||||
break;
|
||||
}
|
||||
}
|
||||
progressIndicator.finish("Second task completed by Test Autopsy Service.");
|
||||
progressIndicator.finish();
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.INFO, "Test Autopsy Service interrupted (cancelled) while doing first task, cancel requested = {0}", context.cancelRequested());
|
||||
}
|
||||
|
@ -200,6 +200,10 @@ public class SolrSearchService implements KeywordSearchService, AutopsyService {
|
||||
"SolrSearch.openCore.msg=Opening text index",
|
||||
"SolrSearch.complete.msg=Text index successfully opened"})
|
||||
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
|
||||
if (context.cancelRequested()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProgressIndicator progress = context.getProgressIndicator();
|
||||
int totalNumProgressUnits = 7;
|
||||
int progressUnitsCompleted = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user