diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index b78e9fecdf..1d172a96ed 100755
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -237,6 +237,55 @@
+
+
+ unit
+
+ org.netbeans.libs.junit4
+
+
+
+ org.netbeans.modules.jellytools.java
+
+
+
+ org.netbeans.modules.jellytools.platform
+
+
+
+ org.netbeans.modules.jemmy
+
+
+
+ org.netbeans.modules.nbjunit
+
+
+
+
+ qa-functional
+
+ org.netbeans.libs.junit4
+
+
+
+ org.netbeans.modules.jellytools.java
+
+
+
+ org.netbeans.modules.jellytools.platform
+
+
+
+ org.netbeans.modules.jemmy
+
+
+
+ org.netbeans.modules.nbjunit
+
+
+
+
+
net.sf.sevenzipjbinding
net.sf.sevenzipjbinding.impl
@@ -260,6 +309,7 @@
org.sleuthkit.autopsy.events
org.sleuthkit.autopsy.externalresults
org.sleuthkit.autopsy.filesearch
+ org.sleuthkit.autopsy.guiutils
org.sleuthkit.autopsy.ingest
org.sleuthkit.autopsy.keywordsearchservice
org.sleuthkit.autopsy.menuactions
@@ -366,6 +416,14 @@
ext/c3p0-0.9.5.jar
release/modules/ext/c3p0-0.9.5.jar
+
+ ext/commons-dbcp2-2.1.1.jar
+ release\modules\ext\commons-dbcp2-2.1.1.jar
+
+
+ ext/commons-pool2-2.4.2.jar
+ release\modules\ext\commons-pool2-2.4.2.jar
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
index 1fc2209750..60db8edaf8 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
@@ -1,14 +1,13 @@
-CTL_AddImage=Add Data Source...
+CTL_AddImage=Add Data Source
CTL_AddImageButton=Add Data Source
CTL_CaseCloseAct=Close Case
-CTL_CaseNewAction=New Case...
-CTL_CasePropertiesAction=Case Properties...
+CTL_CaseNewAction=New Case
+CTL_CasePropertiesAction=Case Properties
CTL_CaseDeleteAction=Delete Case
-CTL_OpenAction=Open Case...
+CTL_CaseOpenAction=Open Case
Menu/Case/OpenRecentCase=Open Recent Case
CTL_CaseDeleteAction=Delete Case
OpenIDE-Module-Name=Case
-NewCaseVisualPanel1.jLabel1.text_1=Enter New Case Information:
NewCaseVisualPanel1.caseNameLabel.text_1=Case Name:
NewCaseVisualPanel1.caseDirLabel.text=Base Directory:
NewCaseVisualPanel1.caseDirBrowseButton.text=Browse
@@ -20,11 +19,6 @@ CueBannerPanel.autopsyLogo.text=
CueBannerPanel.closeButton.text=Close
OpenRecentCasePanel.cancelButton.text=Cancel
OpenRecentCasePanel.jLabel1.text=Recent Cases
-NewCaseVisualPanel2.caseNumberTextField.text=
-NewCaseVisualPanel2.examinerLabel.text=Examiner:
-NewCaseVisualPanel2.caseNumberLabel.text=Case Number:
-NewCaseVisualPanel2.examinerTextField.text=
-NewCaseVisualPanel2.optionalLabel.text=Optional: Set Case Number and Examiner
AddImageErrorsDialog.title=Add Image Log
AddImageErrorsDialog.copyButton.toolTipText=Copy errors to clipboard
AddImageErrorsDialog.copyButton.text=Copy
@@ -152,10 +146,10 @@ MissingImageDialog.display.title=Search for Missing Image
MissingImageDialog.confDlg.noFileSel.msg=No image file has been selected, are you sure you\nwould like to exit without finding the image.
MissingImageDialog.confDlg.noFileSel.title=Missing Image
MissingImageDialog.ErrorSettingImage=Error setting image path. Please try again.
-NewCaseVisualPanel1.getName.text=Case Info
+NewCaseVisualPanel1.getName.text=Case Information
NewCaseVisualPanel1.caseDirBrowse.selectButton.text=Select
NewCaseVisualPanel1.badCredentials.text=Bad multi-user settings (see Tools, Options, Multi-user) or services are down.
-NewCaseVisualPanel2.getName.text=Additional Information
+NewCaseVisualPanel2.getName.text=Optional Information
NewCaseWizardAction.newCase.windowTitle.text=New Case Information
NewCaseWizardAction.getName.text=New Case Wizard
NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case creation.
@@ -209,21 +203,39 @@ LocalDiskPanel.imageWriterErrorLabel.text=Error Label
LocalDiskPanel.jLabel1.text=Note that at least one ingest module must be run to create a complete copy
LocalDiskPanel.pathTextField.text=
LocalDiskPanel.browseButton.text=Browse
-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:
LocalDiskPanel.changeDatabasePathCheckbox.text=Update case to use VHD file upon completion
-CueBannerPanel.openAutoIngestCaseButton.text=
+CueBannerPanel.openMultiUserCaseButton.text=
CueBannerPanel.openExistingCaseButton.text=
CueBannerPanel.openRecentCaseButton.text=
CueBannerPanel.createNewCaseButton.text=
CueBannerPanel.createNewCaseLabel.text=Create New Case
CueBannerPanel.openRecentCaseLabel.text=Open Recent Case
CueBannerPanel.openExistingCaseLabel.text=Open Existing Case
-CueBannerPanel.openAutoIngestCaseLabel.text=Open Auto Ingest Case
+CueBannerPanel.openMultiUserCaseLabel.text=Open Multi-User Case
+ReviewModeCasePanel.cannotOpenCase=Cannot Open Case
+ReviewModeCasePanel.casePathNotFound=Case path not found
+ReviewModeCasePanel.caseIsLocked=Single-user case is locked.
+ReviewModeCasePanel.CaseHeaderText=Case
+ReviewModeCasePanel.CreatedTimeHeaderText=Created Time
+ReviewModeCasePanel.StatusIconHeaderText=Status
+ReviewModeCasePanel.OutputFolderHeaderText=Output Folder
+ReviewModeCasePanel.LastAccessedTimeHeaderText=Last Accessed Time
+ReviewModeCasePanel.MetadataFileHeaderText=Metadata File
+OpenMultiUserCasePanel.jLabel1.text=Recent Cases
+OpenMultiUserCasePanel.openButton.text=Open
+OpenMultiUserCasePanel.cancelButton.text=Cancel
+MultiUserCasesPanel.rbWeeks.text=Weeks
+MultiUserCasesPanel.rbDays.text=Days
+MultiUserCasesPanel.bnShowLog.toolTipText=Display case log file for selected case
+MultiUserCasesPanel.bnShowLog.text=&Show Auto Ingest Case Log
+MultiUserCasesPanel.rbAllCases.text=Everything
+MultiUserCasesPanel.bnRefresh.text=&Refresh
+MultiUserCasesPanel.bnOpen.text=&Open
+MultiUserCasesPanel.rbGroupLabel.text=Show cases accessed in the last 10:
+MultiUserCasesPanel.rbMonths.text=Months
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
index fd00f725e5..de333e790f 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
@@ -1,13 +1,12 @@
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...
-CTL_CasePropertiesAction=\u30b1\u30fc\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3...
+CTL_CaseNewAction=\u65b0\u898f\u30b1\u30fc\u30b9
+CTL_CasePropertiesAction=\u30b1\u30fc\u30b9\u30d7\u30ed\u30d1\u30c6\u30a3
CTL_CaseDeleteAction=\u30b1\u30fc\u30b9\u3092\u524a\u9664
-CTL_OpenAction=\u30b1\u30fc\u30b9\u3092\u958b\u304f...
+CTL_CaseOpenAction=\u30b1\u30fc\u30b9\u3092\u958b\u304f
Menu/Case/OpenRecentCase=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
CTL_CaseDeleteAction=\u30b1\u30fc\u30b9\u3092\u524a\u9664
OpenIDE-Module-Name=\u30b1\u30fc\u30b9
-NewCaseVisualPanel1.jLabel1.text_1=\u65b0\u898f\u30b1\u30fc\u30b9\u60c5\u5831\u3092\u5165\u529b\uff1a
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
@@ -15,9 +14,6 @@ NewCaseVisualPanel1.jLabel2.text_1=\u30b1\u30fc\u30b9\u30c7\u30fc\u30bf\u306f\u6
CueBannerPanel.closeButton.text=\u9589\u3058\u308b
OpenRecentCasePanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
OpenRecentCasePanel.jLabel1.text=\u6700\u8fd1\u958b\u3044\u305f\u30d5\u30a1\u30a4\u30eb
-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
AddImageErrorsDialog.title=\u30a4\u30e1\u30fc\u30b8\u30ed\u30b0\u3092\u8ffd\u52a0
AddImageErrorsDialog.copyButton.toolTipText=\u30a8\u30e9\u30fc\u3092\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059
AddImageErrorsDialog.copyButton.text=\u30b3\u30d4\u30fc
@@ -185,15 +181,19 @@ 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.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
+OptionalCasePropertiesPanel.examinerLabel.text=\u8abf\u67fb\u62c5\u5f53\u8005\uff1a
+OptionalCasePropertiesPanel.caseDisplayNameLabel.text=\u30b1\u30fc\u30b9\u756a\u53f7\uff1a
CueBannerPanel.createNewCaseLabel.text=\u65b0\u898f\u30b1\u30fc\u30b9\u3092\u4f5c\u6210
CueBannerPanel.openRecentCaseLabel.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.openExistingCaseLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f
CueBannerPanel.openAutoIngestCaseLabel.text=\u65e2\u5b58\u30b1\u30fc\u30b9\u3092\u958b\u304f
+OpenMultiUserCasePanel.openButton.text=\u958b\u304f
+OpenMultiUserCasePanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
+OpenMultiUserCasePanel.jLabel1.text=\u6700\u8fd1\u958b\u3044\u305f\u30d5\u30a1\u30a4\u30eb
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index ee45d53944..00ce2cca5d 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -91,6 +91,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+import org.sleuthkit.autopsy.coreutils.ThreadUtils;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.events.AutopsyEvent;
@@ -129,7 +130,6 @@ public class Case {
private static final String REPORTS_FOLDER = "Reports"; //NON-NLS
private static final String TEMP_FOLDER = "Temp"; //NON-NLS
private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS
- private static final long EXECUTOR_AWAIT_TIMEOUT_SECS = 5;
private static final String CASE_ACTION_THREAD_NAME = "%s-case-action";
private static final String CASE_RESOURCES_THREAD_NAME = "%s-manage-case-resources";
private static final Logger logger = Logger.getLogger(Case.class.getName());
@@ -250,19 +250,28 @@ public class Case {
* The name of the current case has changed. The old value of the
* PropertyChangeEvent is the old case name (type: String), the new
* value is the new case name (type: String).
+ *
+ * @Deprecated CASE_DETAILS event should be used instead
*/
+ @Deprecated
NAME,
/**
* The number of the current case has changed. The old value of the
* PropertyChangeEvent is the old case number (type: String), the new
* value is the new case number (type: String).
+ *
+ * @Deprecated CASE_DETAILS event should be used instead
*/
+ @Deprecated
NUMBER,
/**
* The examiner associated with the current case has changed. The old
* value of the PropertyChangeEvent is the old examiner (type: String),
* the new value is the new examiner (type: String).
+ *
+ * @Deprecated CASE_DETAILS event should be used instead
*/
+ @Deprecated
EXAMINER,
/**
* An attempt to add a new data source to the current case is being
@@ -347,7 +356,14 @@ public class Case {
* The old value of the PropertyChangeEvent is is the tag info (type:
* ContentTagDeletedEvent.DeletedContentTagInfo), the new value is null.
*/
- CONTENT_TAG_DELETED;
+ CONTENT_TAG_DELETED,
+ /**
+ * The case display name or an optional detail which can be provided
+ * regarding a case has been changed. The optional details include the
+ * case number, the examiner name, examiner phone, examiner email, and
+ * the case notes.
+ */
+ CASE_DETAILS;
};
/**
@@ -478,19 +494,46 @@ public class Case {
* @throws CaseActionException If there is a problem creating the
* case.
* @throws CaseActionCancelledException If creating the case is cancelled.
+ *
+ * @Deprecated use createAsCurrentCase(CaseType caseType, String caseDir,
+ * CaseDetails caseDetails) instead
+ */
+ @Deprecated
+ public static void createAsCurrentCase(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType) throws CaseActionException, CaseActionCancelledException {
+ createAsCurrentCase(caseType, caseDir, new CaseDetails(caseDisplayName, caseNumber, examiner, "", "", ""));
+ }
+
+ /**
+ * Creates a new case and makes it the current case.
+ *
+ * IMPORTANT: This method should not be called in the event dispatch thread
+ * (EDT).
+ *
+ * @param caseDir The full path of the case directory. The directory
+ * will be created if it doesn't already exist; if it
+ * exists, it is ASSUMED it was created by calling
+ * createCaseDirectory.
+ * @param caseType The type of case (single-user or multi-user).
+ * @param caseDetails Contains the modifiable details of the case such as
+ * the case display name, the case number, and the
+ * examiner related data.
+ *
+ * @throws CaseActionException If there is a problem creating the
+ * case.
+ * @throws CaseActionCancelledException If creating the case is cancelled.
*/
@Messages({
"Case.exceptionMessage.emptyCaseName=Must specify a case name.",
"Case.exceptionMessage.emptyCaseDir=Must specify a case directory path."
})
- public static void createAsCurrentCase(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType) throws CaseActionException, CaseActionCancelledException {
- if (caseDisplayName.isEmpty()) {
+ public static void createAsCurrentCase(CaseType caseType, String caseDir, CaseDetails caseDetails) throws CaseActionException, CaseActionCancelledException {
+ if (caseDetails.getCaseDisplayName().isEmpty()) {
throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseName());
}
if (caseDir.isEmpty()) {
throw new CaseActionException(Bundle.Case_exceptionMessage_emptyCaseDir());
}
- openAsCurrentCase(new Case(caseType, caseDir, caseDisplayName, caseNumber, examiner), true);
+ openAsCurrentCase(new Case(caseType, caseDir, caseDetails), true);
}
/**
@@ -1158,6 +1201,33 @@ public class Case {
return metadata.getExaminer();
}
+ /**
+ * Gets the examiner phone number.
+ *
+ * @return The examiner phone number.
+ */
+ public String getExaminerPhone() {
+ return metadata.getExaminerPhone();
+ }
+
+ /**
+ * Gets the examiner email address.
+ *
+ * @return The examiner email address.
+ */
+ public String getExaminerEmail() {
+ return metadata.getExaminerEmail();
+ }
+
+ /**
+ * Gets the case notes.
+ *
+ * @return The case notes.
+ */
+ public String getCaseNotes() {
+ return metadata.getCaseNotes();
+ }
+
/**
* Gets the path to the top-level case directory.
*
@@ -1475,24 +1545,37 @@ public class Case {
}
/**
- * Updates the case display name name.
+ * Updates the case display name.
+ *
+ * @param newDisplayName the new display name for the case
+ *
+ * @throws org.sleuthkit.autopsy.casemodule.CaseActionException
*/
@Messages({
- "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata, cannot change case display name."
+ "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata"
})
- void updateDisplayName(String newDisplayName) throws CaseActionException {
- String oldDisplayName = metadata.getCaseDisplayName();
+ void updateCaseDetails(CaseDetails caseDetails) throws CaseActionException {
+ CaseDetails oldCaseDetails = metadata.getCaseDetails();
try {
- metadata.setCaseDisplayName(newDisplayName);
+ metadata.setCaseDetails(caseDetails);
} catch (CaseMetadataException ex) {
- throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError());
+ throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
}
- eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldDisplayName, newDisplayName));
+ if (!oldCaseDetails.getCaseNumber().equals(caseDetails.getCaseNumber())) {
+ eventPublisher.publish(new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getCaseNumber(), caseDetails.getCaseNumber()));
+ }
+ if (!oldCaseDetails.getExaminerName().equals(caseDetails.getExaminerName())) {
+ eventPublisher.publish(new AutopsyEvent(Events.NUMBER.toString(), oldCaseDetails.getExaminerName(), caseDetails.getExaminerName()));
+ }
+ if (!oldCaseDetails.getCaseDisplayName().equals(caseDetails.getCaseDisplayName())) {
+ eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldCaseDetails.getCaseDisplayName(), caseDetails.getCaseDisplayName()));
+ }
+ eventPublisher.publish(new AutopsyEvent(Events.CASE_DETAILS.toString(), oldCaseDetails, caseDetails));
if (RuntimeProperties.runningWithGUI()) {
SwingUtilities.invokeLater(() -> {
- mainFrame.setTitle(newDisplayName + " - " + UserPreferences.getAppName());
+ mainFrame.setTitle(caseDetails.getCaseDisplayName() + " - " + UserPreferences.getAppName());
try {
- RecentCases.getInstance().updateRecentCase(oldDisplayName, metadata.getFilePath().toString(), newDisplayName, metadata.getFilePath().toString());
+ RecentCases.getInstance().updateRecentCase(oldCaseDetails.getCaseDisplayName(), metadata.getFilePath().toString(), caseDetails.getCaseDisplayName(), metadata.getFilePath().toString());
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error updating case name in UI", ex); //NON-NLS
}
@@ -1514,8 +1597,8 @@ public class Case {
* @param examiner The examiner to associate with the case, can be
* the empty string.
*/
- private Case(CaseType caseType, String caseDir, String caseDisplayName, String caseNumber, String examiner) {
- metadata = new CaseMetadata(caseDir, caseType, displayNameToUniqueName(caseDisplayName), caseDisplayName, caseNumber, examiner);
+ private Case(CaseType caseType, String caseDir, CaseDetails caseDetails) {
+ metadata = new CaseMetadata(caseType, caseDir, displayNameToUniqueName(caseDetails.getCaseDisplayName()), caseDetails);
}
/**
@@ -1636,7 +1719,7 @@ public class Case {
} else {
future.cancel(true);
}
- Case.shutDownTaskExecutor(caseLockingExecutor);
+ ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
} catch (CancellationException discarded) {
/*
* The create/open task has been cancelled. Wait for it to finish,
@@ -1645,7 +1728,7 @@ public class Case {
* will have been closed and the case directory lock released will
* have been released.
*/
- Case.shutDownTaskExecutor(caseLockingExecutor);
+ ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelledByUser());
} catch (ExecutionException ex) {
/*
@@ -1655,7 +1738,7 @@ public class Case {
* case will have been closed and the case directory lock released
* will have been released.
*/
- Case.shutDownTaskExecutor(caseLockingExecutor);
+ ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
} finally {
progressIndicator.finish();
@@ -1983,7 +2066,7 @@ public class Case {
* would be possible to start the next task before the current
* task responded to a cancellation request.
*/
- shutDownTaskExecutor(executor);
+ ThreadUtils.shutDownTaskExecutor(executor);
progressIndicator.finish();
}
@@ -2054,7 +2137,7 @@ public class Case {
} catch (ExecutionException ex) {
throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
} finally {
- shutDownTaskExecutor(caseLockingExecutor);
+ ThreadUtils.shutDownTaskExecutor(caseLockingExecutor);
progressIndicator.finish();
}
}
@@ -2165,7 +2248,7 @@ public class Case {
Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
}
} finally {
- shutDownTaskExecutor(executor);
+ ThreadUtils.shutDownTaskExecutor(executor);
progressIndicator.finish();
}
}
@@ -2222,41 +2305,6 @@ public class Case {
}
- /**
- * Shuts down a task executor service, waiting until all tasks are
- * terminated. The current policy is to wait for the tasks to finish so that
- * the case for which the executor is running can be left in a consistent
- * state.
- *
- * @param executor The executor.
- */
- private static void shutDownTaskExecutor(ExecutorService executor) {
- executor.shutdown();
- boolean taskCompleted = false;
- while (!taskCompleted) {
- try {
- taskCompleted = executor.awaitTermination(EXECUTOR_AWAIT_TIMEOUT_SECS, TimeUnit.SECONDS);
- } catch (InterruptedException ignored) {
- /*
- * The current policy is to wait for the task to finish so that
- * the case can be left in a consistent state.
- *
- * For a specific example of the motivation for this policy,
- * note that a application service (Solr search service)
- * experienced an error condition when opening case resources
- * that left the service blocked uninterruptibly on a socket
- * read. This eventually led to a mysterious "freeze" as the
- * user-cancelled service task continued to run holdiong a lock
- * that a UI thread soon tried to acquire. Thus it has been
- * deemed better to make the "freeze" happen in a more
- * informative way, i.e., with the progress indicator for the
- * unfinished task on the screen, if a similar error condition
- * arises again.
- */
- }
- }
- }
-
/**
* A case operation Cancel button listener for use with a
* ModalDialogProgressIndicator when running with a GUI.
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java
index 3ef30f2594..66e983b1ce 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java
@@ -33,7 +33,6 @@ 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.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
@@ -45,13 +44,16 @@ import org.sleuthkit.autopsy.coreutils.Logger;
final class CaseDeleteAction extends CallableSystemAction {
private static final long serialVersionUID = 1L;
- private static final Logger logger = Logger.getLogger(CaseDeleteAction.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(CaseDeleteAction.class.getName());
CaseDeleteAction() {
putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction"));
this.setEnabled(false);
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> {
- setEnabled(null != evt.getNewValue() && UserPreferences.getMode() != UserPreferences.SelectedMode.REVIEW);
+ /*
+ * A value of 'null' signifies that there is no case open.
+ */
+ setEnabled(null != evt.getNewValue());
});
}
@@ -93,7 +95,7 @@ final class CaseDeleteAction extends CallableSystemAction {
try {
get();
} catch (InterruptedException | ExecutionException ex) {
- logger.log(Level.SEVERE, String.format("Failed to delete case %s at %s", caseName, caseDirectory), 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.getLocalizedMessage()),
@@ -108,7 +110,7 @@ final class CaseDeleteAction extends CallableSystemAction {
}.execute();
}
} catch (IllegalStateException ex) {
- logger.log(Level.SEVERE, "Case delete action called with no current case", ex);
+ LOGGER.log(Level.SEVERE, "Case delete action called with no current case", ex);
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseDetails.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDetails.java
new file mode 100644
index 0000000000..d1cd8861eb
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseDetails.java
@@ -0,0 +1,121 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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;
+
+/**
+ * Wrapper to contain the modifiable details of a case, such as case display
+ * name, case number, and examiner related fields.
+ */
+public final class CaseDetails {
+
+ private final String caseDisplayName;
+ private final String caseNumber;
+ private final String examinerName;
+ private final String examinerPhone;
+ private final String examinerEmail;
+ private final String caseNotes;
+
+ /**
+ * Create a case details object with all optional fields set to default
+ * values.
+ *
+ * @param displayName the display name of the case
+ */
+ public CaseDetails(String displayName) {
+ caseDisplayName = displayName;
+ caseNumber = "";
+ examinerName = "";
+ examinerPhone = "";
+ examinerEmail = "";
+ caseNotes = "";
+ }
+
+ /**
+ * Create a case details object with the specified values.
+ *
+ * @param displayName the display name of the case
+ * @param number the case number
+ * @param exName the examiner name
+ * @param exPhone the examiner phone number
+ * @param exEmail the examiner email address
+ * @param notes the case notes
+ */
+ public CaseDetails(String displayName, String number, String exName, String exPhone, String exEmail, String notes) {
+ caseDisplayName = displayName;
+ caseNumber = number;
+ examinerName = exName;
+ examinerPhone = exPhone;
+ examinerEmail = exEmail;
+ caseNotes = notes;
+ }
+
+ /**
+ * Get the case display name
+ *
+ * @return caseDisplayName - the display name of the case
+ */
+ public String getCaseDisplayName() {
+ return caseDisplayName;
+ }
+
+ /**
+ * Get the case number
+ *
+ * @return caseNumber - the optional number assiciated with the case
+ */
+ public String getCaseNumber() {
+ return caseNumber;
+ }
+
+ /**
+ * Get the examiner name
+ *
+ * @return name - the name associated with the examiner
+ */
+ public String getExaminerName() {
+ return examinerName;
+ }
+
+ /**
+ * Get the examiner phone number
+ *
+ * @return phone - the phone number associated with the examiner
+ */
+ public String getExaminerPhone() {
+ return examinerPhone;
+ }
+
+ /**
+ * Get the examiner email address
+ *
+ * @return email - the email address associated with the examiner
+ */
+ public String getExaminerEmail() {
+ return examinerEmail;
+ }
+
+ /**
+ * Get the case notes
+ *
+ * @return notes - the note asssociated with the case
+ */
+ public String getCaseNotes() {
+ return caseNotes;
+ }
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.form
index 74892fe40d..932f370478 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.form
@@ -18,38 +18,43 @@
-
+
-
+
-
+
-
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
@@ -70,8 +75,15 @@
+
+
+
+
+
+
+
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java
index b51f0d8a63..b03a17920e 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseInformationPanel.java
@@ -18,9 +18,15 @@
*/
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.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import org.openide.util.NbBundle.Messages;
+import org.openide.windows.WindowManager;
/**
* Panel for displaying the case information, including both case details and
@@ -29,6 +35,7 @@ import org.openide.util.NbBundle.Messages;
class CaseInformationPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
+ CasePropertiesPanel propertiesPanel;
/**
* Constructs a panel for displaying the case information, including both
@@ -40,16 +47,21 @@ class CaseInformationPanel extends javax.swing.JPanel {
}
@Messages({
- "CaseInformationPanel.caseDetails.header=Case Details",
- "CaseInformationPanel.ingestJobInfo.header=Ingest History"
+ "CaseInformationPanel.caseDetails.header=Details",
+ "CaseInformationPanel.ingestJobInfo.header=Ingest History",
+ "CaseInformationPanel.editDetailsButton.text=Edit Details",
+ "CaseInformationPanel.editDetailsDialog.title=Edit Case Details"
})
private void customizeComponents() {
- CasePropertiesPanel propertiesPanel = new CasePropertiesPanel(Case.getCurrentCase());
+ 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());
+ this.tabbedPane.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ tabbedPane.getSelectedComponent().setSize(tabbedPane.getSelectedComponent().getPreferredSize());
+ }
});
}
@@ -71,36 +83,46 @@ class CaseInformationPanel extends javax.swing.JPanel {
// //GEN-BEGIN:initComponents
private void initComponents() {
- jPanel1 = new javax.swing.JPanel();
+ outerDetailsPanel = new javax.swing.JPanel();
tabbedPane = new javax.swing.JTabbedPane();
closeButton = new javax.swing.JButton();
+ editDetailsButton = new javax.swing.JButton();
tabbedPane.setPreferredSize(new java.awt.Dimension(420, 200));
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(CaseInformationPanel.class, "CaseInformationPanel.closeButton.text")); // NOI18N
- closeButton.addActionListener(new java.awt.event.ActionListener() {
+
+ org.openide.awt.Mnemonics.setLocalizedText(editDetailsButton, org.openide.util.NbBundle.getMessage(CaseInformationPanel.class, "CaseInformationPanel.editDetailsButton.text")); // NOI18N
+ editDetailsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
- closeButtonActionPerformed(evt);
+ editDetailsButtonActionPerformed(evt);
}
});
- javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
- jPanel1.setLayout(jPanel1Layout);
- jPanel1Layout.setHorizontalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ javax.swing.GroupLayout outerDetailsPanelLayout = new javax.swing.GroupLayout(outerDetailsPanel);
+ outerDetailsPanel.setLayout(outerDetailsPanelLayout);
+ outerDetailsPanelLayout.setHorizontalGroup(
+ outerDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 709, Short.MAX_VALUE)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(outerDetailsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(editDetailsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(closeButton)
- .addGap(5, 5, 5))
+ .addContainerGap())
);
- jPanel1Layout.setVerticalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 223, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(closeButton)
- .addGap(5, 5, 5))
+
+ outerDetailsPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {closeButton, editDetailsButton});
+
+ outerDetailsPanelLayout.setVerticalGroup(
+ outerDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(outerDetailsPanelLayout.createSequentialGroup()
+ .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 228, Short.MAX_VALUE)
+ .addGap(0, 0, 0)
+ .addGroup(outerDetailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(closeButton)
+ .addComponent(editDetailsButton))
+ .addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@@ -109,23 +131,45 @@ class CaseInformationPanel extends javax.swing.JPanel {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 0, 0)
- .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(outerDetailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(outerDetailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
}// //GEN-END:initComponents
- private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
- // Used by CasePropertiesAction
- }//GEN-LAST:event_closeButtonActionPerformed
+ private void editDetailsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editDetailsButtonActionPerformed
+ JDialog editCasePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), Bundle.CaseInformationPanel_editDetailsDialog_title(), true);
+ EditOptionalCasePropertiesPanel editCasePropertiesPanel = new EditOptionalCasePropertiesPanel();
+ editCasePropertiesPanel.addCancelButtonAction((ActionEvent e) -> {
+ editCasePropertiesDialog.setVisible(false);
+ });
+ editCasePropertiesPanel.addSaveButtonAction((ActionEvent e) -> {
+ editCasePropertiesDialog.setVisible(false);
+ editCasePropertiesPanel.saveProperties();
+ propertiesPanel.updateCaseInfo();
+ });
+
+ editCasePropertiesDialog.add(editCasePropertiesPanel);
+ editCasePropertiesDialog.setResizable(true);
+ editCasePropertiesDialog.pack();
+
+ Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+ double w = editCasePropertiesDialog.getSize().getWidth();
+ double h = editCasePropertiesDialog.getSize().getHeight();
+ editCasePropertiesDialog.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
+ editCasePropertiesDialog.setVisible(true);
+ editCasePropertiesDialog.toFront();
+ propertiesPanel.updateCaseInfo();
+ }//GEN-LAST:event_editDetailsButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton closeButton;
- private javax.swing.JPanel jPanel1;
+ private javax.swing.JButton editDetailsButton;
+ private javax.swing.JPanel outerDetailsPanel;
private javax.swing.JTabbedPane tabbedPane;
// End of variables declaration//GEN-END:variables
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java
index 1f4c5b7912..6e47363db5 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseMetadata.java
@@ -85,20 +85,25 @@ public final class CaseMetadata {
private final static String CASE_DISPLAY_NAME_ELEMENT_NAME = "DisplayName"; //NON-NLS
private final static String CASE_DB_NAME_RELATIVE_ELEMENT_NAME = "CaseDatabase"; //NON-NLS
+ /*
+ * Fields from schema version 4
+ */
+ private static final String SCHEMA_VERSION_FOUR = "4.0";
+ private final static String EXAMINER_ELEMENT_PHONE = "ExaminerPhone"; //NON-NLS
+ private final static String EXAMINER_ELEMENT_EMAIL = "ExaminerEmail"; //NON-NLS
+ private final static String CASE_ELEMENT_NOTES = "CaseNotes"; //NON-NLS
/*
* 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 final static String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_THREE;
+ private final static String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_FOUR;
private final Path metadataFilePath;
private Case.CaseType caseType;
private String caseName;
- private String caseDisplayName;
- private String caseNumber;
- private String examiner;
+ private CaseDetails caseDetails;
private String caseDatabaseName;
private String caseDatabasePath; // Legacy
private String textIndexName; // Legacy
@@ -127,13 +132,11 @@ public final class CaseMetadata {
* @param caseNumber The case number.
* @param examiner The name of the case examiner.
*/
- CaseMetadata(String caseDirectory, Case.CaseType caseType, String caseName, String caseDisplayName, String caseNumber, String examiner) {
- metadataFilePath = Paths.get(caseDirectory, caseDisplayName + FILE_EXTENSION);
+ CaseMetadata(Case.CaseType caseType, String caseDirectory, String caseName, CaseDetails caseDetails) {
+ metadataFilePath = Paths.get(caseDirectory, caseDetails.getCaseDisplayName() + FILE_EXTENSION);
this.caseType = caseType;
this.caseName = caseName;
- this.caseDisplayName = caseDisplayName;
- this.caseNumber = caseNumber;
- this.examiner = examiner;
+ this.caseDetails = caseDetails;
caseDatabaseName = "";
caseDatabasePath = "";
textIndexName = "";
@@ -191,29 +194,31 @@ public final class CaseMetadata {
return caseName;
}
+ /**
+ * Get current values for the case details which are user modifiable.
+ *
+ * @return the case details
+ */
+ public CaseDetails getCaseDetails() {
+ return caseDetails;
+ }
+
/**
* Gets the case display name.
*
* @return The case display name.
*/
public String getCaseDisplayName() {
- return caseDisplayName;
+ return caseDetails.getCaseDisplayName();
}
- /**
- * Sets the case display name.
- *
- * @param caseDisplayName A case display name.
- *
- * @throws CaseMetadataException If the operation fails.
- */
- void setCaseDisplayName(String caseDisplayName) throws CaseMetadataException {
- String oldCaseDisplayName = this.caseDisplayName;
- this.caseDisplayName = caseDisplayName;
+ void setCaseDetails(CaseDetails newCaseDetails) throws CaseMetadataException {
+ CaseDetails oldCaseDetails = this.caseDetails;
+ this.caseDetails = newCaseDetails;
try {
writeToFile();
} catch (CaseMetadataException ex) {
- this.caseDisplayName = oldCaseDisplayName;
+ this.caseDetails = oldCaseDetails;
throw ex;
}
}
@@ -224,7 +229,7 @@ public final class CaseMetadata {
* @return The case number, may be empty.
*/
public String getCaseNumber() {
- return caseNumber;
+ return caseDetails.getCaseNumber();
}
/**
@@ -233,7 +238,19 @@ public final class CaseMetadata {
* @return The examiner, may be empty.
*/
public String getExaminer() {
- return examiner;
+ return caseDetails.getExaminerName();
+ }
+
+ public String getExaminerPhone() {
+ return caseDetails.getExaminerPhone();
+ }
+
+ public String getExaminerEmail() {
+ return caseDetails.getExaminerEmail();
+ }
+
+ public String getCaseNotes() {
+ return caseDetails.getCaseNotes();
}
/**
@@ -389,9 +406,12 @@ 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_DISPLAY_NAME_ELEMENT_NAME, caseDetails.getCaseDisplayName());
+ createChildElement(doc, caseElement, CASE_NUMBER_ELEMENT_NAME, caseDetails.getCaseNumber());
+ createChildElement(doc, caseElement, EXAMINER_ELEMENT_NAME, caseDetails.getExaminerName());
+ createChildElement(doc, caseElement, EXAMINER_ELEMENT_PHONE, caseDetails.getExaminerPhone());
+ createChildElement(doc, caseElement, EXAMINER_ELEMENT_EMAIL, caseDetails.getExaminerEmail());
+ createChildElement(doc, caseElement, CASE_ELEMENT_NOTES, caseDetails.getCaseNotes());
createChildElement(doc, caseElement, CASE_TYPE_ELEMENT_NAME, caseType.toString());
createChildElement(doc, caseElement, CASE_DB_ABSOLUTE_PATH_ELEMENT_NAME, caseDatabasePath);
createChildElement(doc, caseElement, CASE_DB_NAME_RELATIVE_ELEMENT_NAME, caseDatabaseName);
@@ -452,13 +472,28 @@ public final class CaseMetadata {
}
Element caseElement = (Element) caseElements.item(0);
this.caseName = getElementTextContent(caseElement, CASE_NAME_ELEMENT_NAME, true);
+ String caseDisplayName;
+ String caseNumber;
if (schemaVersion.equals(SCHEMA_VERSION_ONE) || schemaVersion.equals(SCHEMA_VERSION_TWO)) {
- this.caseDisplayName = caseName;
+ caseDisplayName = caseName;
} else {
- this.caseDisplayName = getElementTextContent(caseElement, CASE_DISPLAY_NAME_ELEMENT_NAME, true);
+ 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);
+ caseNumber = getElementTextContent(caseElement, CASE_NUMBER_ELEMENT_NAME, false);
+ String examinerName = getElementTextContent(caseElement, EXAMINER_ELEMENT_NAME, false);
+ String examinerPhone;
+ String examinerEmail;
+ String caseNotes;
+ if (schemaVersion.equals(SCHEMA_VERSION_ONE) || schemaVersion.equals(SCHEMA_VERSION_TWO) || schemaVersion.equals(SCHEMA_VERSION_THREE)) {
+ examinerPhone = ""; //case had metadata file written before additional examiner details were included
+ examinerEmail = "";
+ caseNotes = "";
+ } else {
+ examinerPhone = getElementTextContent(caseElement, EXAMINER_ELEMENT_PHONE, false);
+ examinerEmail = getElementTextContent(caseElement, EXAMINER_ELEMENT_EMAIL, false);
+ caseNotes = getElementTextContent(caseElement, CASE_ELEMENT_NOTES, false);
+ }
+ this.caseDetails = new CaseDetails(caseDisplayName, caseNumber, examinerName, examinerPhone, examinerEmail, caseNotes);
this.caseType = Case.CaseType.fromString(getElementTextContent(caseElement, CASE_TYPE_ELEMENT_NAME, true));
if (null == this.caseType) {
throw new CaseMetadataException("Case metadata file corrupted");
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
index 533cab58c5..e4ed92d897 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
@@ -141,7 +141,7 @@ public final class CaseOpenAction extends CallableSystemAction implements Action
@Override
public String getName() {
- return NbBundle.getMessage(CaseOpenAction.class, "CTL_OpenAction");
+ return NbBundle.getMessage(CaseOpenAction.class, "CTL_CaseOpenAction");
}
@Override
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java
new file mode 100755
index 0000000000..7a12b69cf7
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenMultiUserAction.java
@@ -0,0 +1,91 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JDialog;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+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.core.UserPreferences;
+
+/**
+ * The action associated with the Open Multi-User Case menu item via the
+ * layer.xml file.
+ *
+ * This action should only be invoked in the event dispatch thread (EDT).
+ */
+@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.CaseOpenMultiUserAction")
+@ActionReference(path = "Menu/Case", position = 102)
+@ActionRegistration(displayName = "#CTL_CaseOpenMultiUserAction", lazy = false)
+@NbBundle.Messages({"CTL_CaseOpenMultiUserAction=Open Multi-User Case"})
+public final class CaseOpenMultiUserAction extends CallableSystemAction implements ActionListener {
+
+ private static final long serialVersionUID = 1L;
+ private static JDialog multiUserCaseWindow;
+
+ private static final String DISPLAY_NAME = Bundle.CTL_CaseOpenMultiUserAction();
+
+ public CaseOpenMultiUserAction() {}
+
+ @Override
+ public boolean isEnabled() {
+ return UserPreferences.getIsMultiUserModeEnabled();
+ }
+
+ /**
+ * Pops up a case selection panel to allow the user to select a multi-user
+ * case to open.
+ *
+ * @param event The action event.
+ */
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ if(multiUserCaseWindow == null) {
+ multiUserCaseWindow = MultiUserCasesDialog.getInstance();
+ }
+ multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
+ multiUserCaseWindow.setVisible(true);
+ }
+
+ @Override
+ public void performAction() {
+ actionPerformed(null);
+ }
+
+ @Override
+ public String getName() {
+ return DISPLAY_NAME;
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public boolean asynchronous() {
+ return false; // run on edt
+ }
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java
index c50c561564..886ea011b7 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java
@@ -52,7 +52,7 @@ final class CasePropertiesAction extends CallableSystemAction {
public void performAction() {
SwingUtilities.invokeLater(() -> {
String title = NbBundle.getMessage(this.getClass(), "CasePropertiesAction.window.title");
- casePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), title, false);
+ casePropertiesDialog = new JDialog(WindowManager.getDefault().getMainWindow(), title, true);
CaseInformationPanel caseInformationPanel = new CaseInformationPanel();
caseInformationPanel.addCloseButtonAction((ActionEvent e) -> {
casePropertiesDialog.setVisible(false);
@@ -66,7 +66,6 @@ final class CasePropertiesAction extends CallableSystemAction {
double h = casePropertiesDialog.getSize().getHeight();
casePropertiesDialog.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
casePropertiesDialog.setVisible(true);
- casePropertiesDialog.setVisible(true);
casePropertiesDialog.toFront();
});
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.form
index d373e58a6e..ab036f2e87 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.form
@@ -33,258 +33,656 @@
-
+
+
+
+
+
-
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.java
index 7a513d7261..23e9d0b1c8 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CasePropertiesPanel.java
@@ -20,19 +20,22 @@ package org.sleuthkit.autopsy.casemodule;
import java.nio.file.Paths;
import java.util.logging.Level;
-import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
+import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
/**
* 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 {
+final class CasePropertiesPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(CasePropertiesPanel.class.getName());
- private final Case theCase;
+ private Case theCase;
/**
* Constructs a panel that allows the user to view various properties of the
@@ -40,22 +43,19 @@ class CasePropertiesPanel extends javax.swing.JPanel {
*
* @param aCase A case.
*/
- CasePropertiesPanel(Case aCase) {
+ CasePropertiesPanel(Case caseInfo) {
initComponents();
- theCase = aCase;
- caseNameTextField.setText(theCase.getDisplayName());
- String caseNumber = theCase.getNumber();
- if (!caseNumber.isEmpty()) {
- caseNumberField.setText(caseNumber);
- } else {
- caseNumberField.setText("N/A");
- }
- String examiner = theCase.getExaminer();
- if (!examiner.isEmpty()) {
- examinerField.setText(examiner);
- } else {
- examinerField.setText("N/A");
- }
+ updateCaseInfo();
+ }
+
+ void updateCaseInfo() {
+ theCase = Case.getCurrentCase();
+ lbCaseNameText.setText(theCase.getDisplayName());
+ lbCaseNumberText.setText(theCase.getNumber());
+ lbExaminerNameText.setText(theCase.getExaminer());
+ lbExaminerPhoneText.setText(theCase.getExaminerPhone());
+ lbExaminerEmailText.setText(theCase.getExaminerEmail());
+ taNotesText.setText(theCase.getCaseNotes());
crDateField.setText(theCase.getCreatedDate());
caseDirField.setText(theCase.getCaseDirectory());
if (Case.CaseType.SINGLE_USER_CASE == theCase.getCaseType()) {
@@ -63,10 +63,63 @@ class CasePropertiesPanel extends javax.swing.JPanel {
} else {
dbNameField.setText(theCase.getMetadata().getCaseDatabaseName());
}
+ boolean cREnabled = EamDb.isEnabled();
+ lbOrganizationNameLabel.setEnabled(cREnabled);
+ lbOrganizationNameText.setEnabled(cREnabled);
+ lbPointOfContactEmailLabel.setEnabled(cREnabled);
+ lbPointOfContactEmailText.setEnabled(cREnabled);
+ lbPointOfContactNameLabel.setEnabled(cREnabled);
+ lbPointOfContactNameText.setEnabled(cREnabled);
+ lbPointOfContactPhoneLabel.setEnabled(cREnabled);
+ lbPointOfContactPhoneText.setEnabled(cREnabled);
+ pnOrganization.setEnabled(cREnabled);
+ EamOrganization currentOrg = null;
+ if (cREnabled) {
+ try {
+ EamDb dbManager = EamDb.getInstance();
+ if (dbManager != null) {
+ CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ if (null == correlationCase) {
+ dbManager.newCase(Case.getCurrentCase());
+ correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ }
+ currentOrg = correlationCase.getOrg();
+ }
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Unable to access Correlation Case when Central Repo is enabled", ex);
+ }
+ }
+ if (currentOrg != null) {
+ lbOrganizationNameText.setText(currentOrg.getName());
+ lbPointOfContactNameText.setText(currentOrg.getPocName());
+ lbPointOfContactPhoneText.setText(currentOrg.getPocPhone());
+ lbPointOfContactEmailText.setText(currentOrg.getPocEmail());
+ } else {
+ lbOrganizationNameText.setText("");
+ lbPointOfContactNameText.setText("");
+ lbPointOfContactPhoneText.setText("");
+ lbPointOfContactEmailText.setText("");
+ }
Case.CaseType caseType = theCase.getCaseType();
- caseTypeField.setText(caseType.getLocalizedDisplayName());
+ caseTypeField.setText(caseType.getLocalizedDisplayName());
+ lbCaseUIDText.setText(theCase.getName());
+ validate();
+ repaint();
}
+ @Messages({"CasePropertiesPanel.casePanel.border.title=Case",
+ "CasePropertiesPanel.lbCaseUUIDLabel.text=Case UUID:",
+ "CasePropertiesPanel.examinerPanel.border.title=Examiner",
+ "CasePropertiesPanel.examinerLabel.text=Name:",
+ "CasePropertiesPanel.lbExaminerPhoneLabel.text=Phone:",
+ "CasePropertiesPanel.lbExaminerEmailLabel.text=Email:",
+ "CasePropertiesPanel.lbNotesLabel.text=Notes:",
+ "CasePropertiesPanel.pnOrganization.border.title=Organization",
+ "CasePropertiesPanel.lbOrganizationNameLabel.text=Name:",
+ "CasePropertiesPanel.lbPointOfContactNameLabel.text=Point of Contact:",
+ "CasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone:",
+ "CasePropertiesPanel.lbPointOfContactEmailLabel.text=Email:"})
+
/**
* In this generated code below, there are 2 strings "Path" and "Remove"
* that are table column headers in the DefaultTableModel. When this model
@@ -87,208 +140,393 @@ class CasePropertiesPanel extends javax.swing.JPanel {
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
- jPanel1 = new javax.swing.JPanel();
+ detailsPanel = new javax.swing.JPanel();
+ casePanel = new javax.swing.JPanel();
caseNameLabel = new javax.swing.JLabel();
- crDateLabel = new javax.swing.JLabel();
- caseDirLabel = new javax.swing.JLabel();
- caseNameTextField = new javax.swing.JTextField();
- updateCaseNameButton = new javax.swing.JButton();
- caseNumberLabel = new javax.swing.JLabel();
- examinerLabel = new javax.swing.JLabel();
lbDbType = new javax.swing.JLabel();
- lbDbName = new javax.swing.JLabel();
- caseNumberField = new javax.swing.JLabel();
- examinerField = new javax.swing.JLabel();
- crDateField = new javax.swing.JLabel();
- caseDirField = new javax.swing.JLabel();
- dbNameField = new javax.swing.JLabel();
+ lbCaseUUIDLabel = new javax.swing.JLabel();
caseTypeField = new javax.swing.JLabel();
+ dbNameField = new javax.swing.JLabel();
+ lbDbName = new javax.swing.JLabel();
+ caseNumberLabel = new javax.swing.JLabel();
+ caseDirLabel = new javax.swing.JLabel();
+ caseDirField = new javax.swing.JLabel();
+ crDateLabel = new javax.swing.JLabel();
+ crDateField = new javax.swing.JLabel();
+ lbCaseUIDText = new javax.swing.JLabel();
+ lbCaseNameText = new javax.swing.JLabel();
+ lbCaseNumberText = new javax.swing.JLabel();
+ examinerPanel = new javax.swing.JPanel();
+ lbExaminerNameText = new javax.swing.JLabel();
+ lbNotesLabel = new javax.swing.JLabel();
+ examinerLabel = new javax.swing.JLabel();
+ caseNotesScrollPane = new javax.swing.JScrollPane();
+ taNotesText = new javax.swing.JTextArea();
+ lbExaminerEmailLabel = new javax.swing.JLabel();
+ lbExaminerPhoneLabel = new javax.swing.JLabel();
+ lbExaminerPhoneText = new javax.swing.JLabel();
+ lbExaminerEmailText = new javax.swing.JLabel();
+ pnOrganization = new javax.swing.JPanel();
+ lbOrganizationNameLabel = new javax.swing.JLabel();
+ lbPointOfContactNameLabel = new javax.swing.JLabel();
+ lbPointOfContactEmailLabel = new javax.swing.JLabel();
+ lbPointOfContactPhoneLabel = new javax.swing.JLabel();
+ lbPointOfContactNameText = new javax.swing.JLabel();
+ lbPointOfContactEmailText = new javax.swing.JLabel();
+ lbPointOfContactPhoneText = new javax.swing.JLabel();
+ lbOrganizationNameText = new javax.swing.JLabel();
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);
+ casePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.casePanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+
caseNameLabel.setFont(caseNameLabel.getFont().deriveFont(caseNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
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(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(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(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(CasePropertiesPanel.class, "CasePropertiesPanel.updateCaseNameButton.text")); // NOI18N
- updateCaseNameButton.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- updateCaseNameButtonActionPerformed(evt);
- }
- });
-
- caseNumberLabel.setFont(caseNumberLabel.getFont().deriveFont(caseNumberLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- 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(CasePropertiesPanel.class, "CasePropertiesPanel.examinerLabel.text")); // NOI18N
+ caseNameLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ caseNameLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ caseNameLabel.setPreferredSize(new java.awt.Dimension(82, 14));
lbDbType.setFont(lbDbType.getFont().deriveFont(lbDbType.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
lbDbType.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbDbType.text")); // NOI18N
+ lbDbType.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbDbType.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbDbType.setPreferredSize(new java.awt.Dimension(82, 14));
- lbDbName.setFont(lbDbName.getFont().deriveFont(lbDbName.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- lbDbName.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbDbName.text")); // NOI18N
-
- caseDirField.setMinimumSize(new java.awt.Dimension(25, 14));
-
- dbNameField.setMinimumSize(new java.awt.Dimension(25, 14));
+ lbCaseUUIDLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbCaseUUIDLabel.text")); // NOI18N
+ lbCaseUUIDLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbCaseUUIDLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbCaseUUIDLabel.setPreferredSize(new java.awt.Dimension(82, 14));
caseTypeField.setMaximumSize(new java.awt.Dimension(1, 0));
- javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
- jPanel1.setLayout(jPanel1Layout);
- jPanel1Layout.setHorizontalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
+ dbNameField.setMinimumSize(new java.awt.Dimension(25, 14));
+
+ lbDbName.setFont(lbDbName.getFont().deriveFont(lbDbName.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ lbDbName.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbDbName.text")); // NOI18N
+ lbDbName.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbDbName.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbDbName.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ caseNumberLabel.setFont(caseNumberLabel.getFont().deriveFont(caseNumberLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ caseNumberLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.caseNumberLabel.text")); // NOI18N
+ caseNumberLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ caseNumberLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ caseNumberLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ caseDirLabel.setFont(caseDirLabel.getFont().deriveFont(caseDirLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ caseDirLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.caseDirLabel.text")); // NOI18N
+ caseDirLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ caseDirLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ caseDirLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ caseDirField.setMinimumSize(new java.awt.Dimension(25, 14));
+
+ crDateLabel.setFont(crDateLabel.getFont().deriveFont(crDateLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ crDateLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.crDateLabel.text")); // NOI18N
+ crDateLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ crDateLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ crDateLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ lbCaseNameText.setMinimumSize(new java.awt.Dimension(25, 14));
+
+ lbCaseNumberText.setMinimumSize(new java.awt.Dimension(25, 14));
+
+ javax.swing.GroupLayout casePanelLayout = new javax.swing.GroupLayout(casePanel);
+ casePanel.setLayout(casePanelLayout);
+ casePanelLayout.setHorizontalGroup(
+ casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createSequentialGroup()
.addContainerGap()
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbDbName)
- .addComponent(lbDbType)
- .addComponent(caseDirLabel))
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createSequentialGroup()
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(caseNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(caseNumberLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbCaseNumberText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbCaseNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ .addGroup(casePanelLayout.createSequentialGroup()
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(lbCaseUUIDLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbDbName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbDbType, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(caseDirLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(crDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(crDateField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(caseDirField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(caseTypeField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(dbNameField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(crDateLabel)
- .addComponent(examinerLabel)
- .addComponent(caseNumberLabel))
- .addGap(18, 18, 18)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(examinerField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(caseNumberField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addComponent(caseNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(updateCaseNameButton, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(crDateField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+ .addComponent(dbNameField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbCaseUIDText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap())
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(caseNameLabel)
- .addContainerGap(392, Short.MAX_VALUE)))
);
- jPanel1Layout.setVerticalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+ casePanelLayout.setVerticalGroup(
+ casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createSequentialGroup()
.addContainerGap()
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(updateCaseNameButton))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addComponent(caseNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(caseNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbCaseNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(caseNumberLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbCaseNumberText, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(crDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(crDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(caseDirLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(caseDirField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(caseTypeField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbDbType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lbDbName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(dbNameField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbCaseUUIDLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbCaseUIDText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6))
+ );
+
+ examinerPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.examinerPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+
+ lbNotesLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbNotesLabel.text")); // NOI18N
+ lbNotesLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbNotesLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbNotesLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+ lbNotesLabel.setRequestFocusEnabled(false);
+
+ examinerLabel.setFont(examinerLabel.getFont().deriveFont(examinerLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ examinerLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.examinerLabel.text")); // NOI18N
+ examinerLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ examinerLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ examinerLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ caseNotesScrollPane.setBorder(null);
+
+ taNotesText.setEditable(false);
+ taNotesText.setBackground(new java.awt.Color(240, 240, 240));
+ taNotesText.setColumns(20);
+ taNotesText.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
+ taNotesText.setLineWrap(true);
+ taNotesText.setRows(2);
+ taNotesText.setWrapStyleWord(true);
+ taNotesText.setBorder(null);
+ taNotesText.setFocusable(false);
+ caseNotesScrollPane.setViewportView(taNotesText);
+
+ lbExaminerEmailLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbExaminerEmailLabel.text")); // NOI18N
+ lbExaminerEmailLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbExaminerEmailLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbExaminerEmailLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ lbExaminerPhoneLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbExaminerPhoneLabel.text")); // NOI18N
+ lbExaminerPhoneLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbExaminerPhoneLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbExaminerPhoneLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ javax.swing.GroupLayout examinerPanelLayout = new javax.swing.GroupLayout(examinerPanel);
+ examinerPanel.setLayout(examinerPanelLayout);
+ examinerPanelLayout.setHorizontalGroup(
+ examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbExaminerPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbNotesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(examinerField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(examinerLabel))
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbExaminerPhoneText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(caseNotesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 411, Short.MAX_VALUE)))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, examinerPanelLayout.createSequentialGroup()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbExaminerEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(examinerLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(crDateField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(crDateLabel, javax.swing.GroupLayout.Alignment.TRAILING))
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbExaminerNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbExaminerEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+ .addContainerGap())
+ );
+ examinerPanelLayout.setVerticalGroup(
+ examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(examinerLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbExaminerNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbExaminerPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbExaminerPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbExaminerEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbExaminerEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbNotesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(caseNotesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6))
+ );
+
+ pnOrganization.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.pnOrganization.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+
+ lbOrganizationNameLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbOrganizationNameLabel.text")); // NOI18N
+ lbOrganizationNameLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbOrganizationNameLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbOrganizationNameLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ lbPointOfContactNameLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbPointOfContactNameLabel.text")); // NOI18N
+
+ lbPointOfContactEmailLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbPointOfContactEmailLabel.text")); // NOI18N
+ lbPointOfContactEmailLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactEmailLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactEmailLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ lbPointOfContactPhoneLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesPanel.class, "CasePropertiesPanel.lbPointOfContactPhoneLabel.text")); // NOI18N
+ lbPointOfContactPhoneLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactPhoneLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactPhoneLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ javax.swing.GroupLayout pnOrganizationLayout = new javax.swing.GroupLayout(pnOrganization);
+ pnOrganization.setLayout(pnOrganizationLayout);
+ pnOrganizationLayout.setHorizontalGroup(
+ pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnOrganizationLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnOrganizationLayout.createSequentialGroup()
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(caseDirLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(caseDirField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, 411, Short.MAX_VALUE)
+ .addComponent(lbOrganizationNameText, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ .addGroup(pnOrganizationLayout.createSequentialGroup()
+ .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(caseTypeField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbDbType))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbDbName)
- .addComponent(dbNameField, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addComponent(caseNumberLabel))
- .addGap(44, 44, 44))
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(caseNameLabel)
- .addContainerGap(173, Short.MAX_VALUE)))
+ .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+ pnOrganizationLayout.setVerticalGroup(
+ pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnOrganizationLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbOrganizationNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6))
+ );
+
+ javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel);
+ detailsPanel.setLayout(detailsPanelLayout);
+ detailsPanelLayout.setHorizontalGroup(
+ detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(detailsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(casePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(examinerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnOrganization, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ detailsPanelLayout.setVerticalGroup(
+ detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, detailsPanelLayout.createSequentialGroup()
+ .addComponent(casePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(examinerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(pnOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(detailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGap(0, 0, 0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(detailsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGap(0, 0, 0))
);
}// //GEN-END:initComponents
- /**
- * 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 newCaseDisplayName = caseNameTextField.getText();
- if (newCaseDisplayName.equals(theCase.getDisplayName())) {
- return;
- }
-
- if (newCaseDisplayName.trim().isEmpty()) {
- MessageNotifyUtil.Message.error(Bundle.CasePropertiesPanel_errorDialog_emptyCaseNameMessage());
- return;
- }
-
- 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
-
-
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel caseDirField;
private javax.swing.JLabel caseDirLabel;
private javax.swing.JLabel caseNameLabel;
- private javax.swing.JTextField caseNameTextField;
- private javax.swing.JLabel caseNumberField;
+ private javax.swing.JScrollPane caseNotesScrollPane;
private javax.swing.JLabel caseNumberLabel;
+ private javax.swing.JPanel casePanel;
private javax.swing.JLabel caseTypeField;
private javax.swing.JLabel crDateField;
private javax.swing.JLabel crDateLabel;
private javax.swing.JLabel dbNameField;
- private javax.swing.JLabel examinerField;
+ private javax.swing.JPanel detailsPanel;
private javax.swing.JLabel examinerLabel;
- private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel examinerPanel;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextArea1;
+ private javax.swing.JLabel lbCaseNameText;
+ private javax.swing.JLabel lbCaseNumberText;
+ private javax.swing.JLabel lbCaseUIDText;
+ private javax.swing.JLabel lbCaseUUIDLabel;
private javax.swing.JLabel lbDbName;
private javax.swing.JLabel lbDbType;
- private javax.swing.JButton updateCaseNameButton;
+ private javax.swing.JLabel lbExaminerEmailLabel;
+ private javax.swing.JLabel lbExaminerEmailText;
+ private javax.swing.JLabel lbExaminerNameText;
+ private javax.swing.JLabel lbExaminerPhoneLabel;
+ private javax.swing.JLabel lbExaminerPhoneText;
+ private javax.swing.JLabel lbNotesLabel;
+ private javax.swing.JLabel lbOrganizationNameLabel;
+ private javax.swing.JLabel lbOrganizationNameText;
+ private javax.swing.JLabel lbPointOfContactEmailLabel;
+ private javax.swing.JLabel lbPointOfContactEmailText;
+ private javax.swing.JLabel lbPointOfContactNameLabel;
+ private javax.swing.JLabel lbPointOfContactNameText;
+ private javax.swing.JLabel lbPointOfContactPhoneLabel;
+ private javax.swing.JLabel lbPointOfContactPhoneText;
+ private javax.swing.JPanel pnOrganization;
+ private javax.swing.JTextArea taNotesText;
// End of variables declaration//GEN-END:variables
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form
index 75819e41d0..0d6525db8b 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form
@@ -28,14 +28,14 @@
-
+
-
+
@@ -66,9 +66,9 @@
-
+
-
+
@@ -216,13 +216,13 @@
-
+
-
+
@@ -237,18 +237,18 @@
-
+
-
+
-
+
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java
index 2d7b17458e..2c81d100e4 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java
@@ -26,14 +26,11 @@ import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
-import javax.swing.JPanel;
import javax.swing.KeyStroke;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
-import org.sleuthkit.autopsy.casemodule.AutoIngestCasePanelInterface;
import org.sleuthkit.autopsy.core.UserPreferences;
-import org.sleuthkit.autopsy.coreutils.NetworkUtils;
/*
* The panel in the default Autopsy startup window.
@@ -41,14 +38,11 @@ import org.sleuthkit.autopsy.coreutils.NetworkUtils;
public class CueBannerPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
- private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
- private static final String REVIEW_MODE_TITLE = "Cases" + " (" + LOCAL_HOST_NAME + ")";
/*
* This is field is static for the sake of the closeOpenRecentCasesWindow
* method.
*/
private static JDialog recentCasesWindow;
- private static JDialog autoIngestCasePanelWindow;
public static void closeOpenRecentCasesWindow() {
if (null != recentCasesWindow) {
@@ -56,15 +50,9 @@ public class CueBannerPanel extends javax.swing.JPanel {
}
}
- public static void closeAutoIngestCasesWindow() {
- if (null != autoIngestCasePanelWindow) {
- autoIngestCasePanelWindow.setVisible(false);
- }
- }
-
public CueBannerPanel() {
initComponents();
- customizeComponents();
+ initRecentCasesWindow();
enableComponents();
}
@@ -75,7 +63,7 @@ public class CueBannerPanel extends javax.swing.JPanel {
ImageIcon icon = new ImageIcon(cl.getResource(welcomeLogo));
autopsyLogo.setIcon(icon);
}
- customizeComponents();
+ initRecentCasesWindow();
enableComponents();
}
@@ -90,11 +78,6 @@ public class CueBannerPanel extends javax.swing.JPanel {
public void refresh() {
enableComponents();
}
-
- private void customizeComponents() {
- initRecentCasesWindow();
- initAutoIngestCasesWindow();
- }
private void initRecentCasesWindow() {
recentCasesWindow = new JDialog(
@@ -118,39 +101,15 @@ public class CueBannerPanel extends javax.swing.JPanel {
recentCasesWindow.pack();
recentCasesWindow.setResizable(false);
}
-
- private void initAutoIngestCasesWindow() {
- autoIngestCasePanelWindow = new JDialog(
- WindowManager.getDefault().getMainWindow(),
- REVIEW_MODE_TITLE,
- Dialog.ModalityType.APPLICATION_MODAL);
- autoIngestCasePanelWindow.getRootPane().registerKeyboardAction(
- e -> {
- autoIngestCasePanelWindow.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) {
- autoIngestCasePanelWindow.setVisible(false);
- }
- });
- AutoIngestCasePanelInterface autoIngestCasePanel = Lookup.getDefault().lookup(AutoIngestCasePanelInterface.class);
- autoIngestCasePanel.addWindowStateListener(autoIngestCasePanelWindow);
- autoIngestCasePanelWindow.add((JPanel)autoIngestCasePanel);
- autoIngestCasePanelWindow.pack();
- autoIngestCasePanelWindow.setResizable(false);
- }
private void enableComponents() {
boolean enableOpenRecentCaseButton = (RecentCases.getInstance().getTotalRecentCases() > 0);
openRecentCaseButton.setEnabled(enableOpenRecentCaseButton);
openRecentCaseLabel.setEnabled(enableOpenRecentCaseButton);
- boolean showOpenAutoIngestCaseButton = (UserPreferences.getMode() == UserPreferences.SelectedMode.REVIEW);
- openAutoIngestCaseButton.setVisible(showOpenAutoIngestCaseButton);
- openAutoIngestCaseLabel.setVisible(showOpenAutoIngestCaseButton);
+ boolean enableOpenMultiUserCaseButton = UserPreferences.getIsMultiUserModeEnabled();
+ openMultiUserCaseButton.setEnabled(enableOpenMultiUserCaseButton);
+ openMultiUserCaseLabel.setEnabled(enableOpenMultiUserCaseButton);
}
/**
@@ -172,8 +131,8 @@ public class CueBannerPanel extends javax.swing.JPanel {
openExistingCaseLabel = new javax.swing.JLabel();
closeButton = new javax.swing.JButton();
jSeparator1 = new javax.swing.JSeparator();
- openAutoIngestCaseButton = new javax.swing.JButton();
- openAutoIngestCaseLabel = new javax.swing.JLabel();
+ openMultiUserCaseButton = new javax.swing.JButton();
+ openMultiUserCaseLabel = new javax.swing.JLabel();
autopsyLogo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/welcome_logo.png"))); // NOI18N
autopsyLogo.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.autopsyLogo.text")); // NOI18N
@@ -229,21 +188,21 @@ public class CueBannerPanel extends javax.swing.JPanel {
jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
- openAutoIngestCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"))); // NOI18N
- openAutoIngestCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openAutoIngestCaseButton.text")); // NOI18N
- openAutoIngestCaseButton.setBorder(null);
- openAutoIngestCaseButton.setBorderPainted(false);
- openAutoIngestCaseButton.setContentAreaFilled(false);
- openAutoIngestCaseButton.setMargin(new java.awt.Insets(1, 1, 1, 1));
- openAutoIngestCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
- openAutoIngestCaseButton.addActionListener(new java.awt.event.ActionListener() {
+ openMultiUserCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/btn_icon_open_existing.png"))); // NOI18N
+ openMultiUserCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openMultiUserCaseButton.text")); // NOI18N
+ openMultiUserCaseButton.setBorder(null);
+ openMultiUserCaseButton.setBorderPainted(false);
+ openMultiUserCaseButton.setContentAreaFilled(false);
+ openMultiUserCaseButton.setMargin(new java.awt.Insets(1, 1, 1, 1));
+ openMultiUserCaseButton.setPreferredSize(new java.awt.Dimension(64, 64));
+ openMultiUserCaseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
- openAutoIngestCaseButtonActionPerformed(evt);
+ openMultiUserCaseButtonActionPerformed(evt);
}
});
- openAutoIngestCaseLabel.setFont(openAutoIngestCaseLabel.getFont().deriveFont(openAutoIngestCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
- openAutoIngestCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openAutoIngestCaseLabel.text")); // NOI18N
+ openMultiUserCaseLabel.setFont(openMultiUserCaseLabel.getFont().deriveFont(openMultiUserCaseLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 13));
+ openMultiUserCaseLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openMultiUserCaseLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@@ -261,13 +220,13 @@ public class CueBannerPanel extends javax.swing.JPanel {
.addComponent(createNewCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openRecentCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(openExistingCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(openAutoIngestCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(openMultiUserCaseButton, 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)
.addComponent(createNewCaseLabel)
.addComponent(openRecentCaseLabel)
.addComponent(openExistingCaseLabel)
- .addComponent(openAutoIngestCaseLabel)))
+ .addComponent(openMultiUserCaseLabel)))
.addComponent(closeButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
@@ -290,9 +249,9 @@ public class CueBannerPanel extends javax.swing.JPanel {
.addComponent(openExistingCaseLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(openAutoIngestCaseButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(openMultiUserCaseButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(openAutoIngestCaseLabel)
+ .addComponent(openMultiUserCaseLabel)
.addGap(20, 20, 20))))
.addComponent(jSeparator1)
.addComponent(autopsyLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 257, javax.swing.GroupLayout.PREFERRED_SIZE))
@@ -316,10 +275,11 @@ public class CueBannerPanel extends javax.swing.JPanel {
recentCasesWindow.setVisible(true);
}//GEN-LAST:event_openRecentCaseButtonActionPerformed
- private void openAutoIngestCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openAutoIngestCaseButtonActionPerformed
- autoIngestCasePanelWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
- autoIngestCasePanelWindow.setVisible(true);
- }//GEN-LAST:event_openAutoIngestCaseButtonActionPerformed
+ private void openMultiUserCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMultiUserCaseButtonActionPerformed
+ MultiUserCasesDialog multiUserCaseWindow = MultiUserCasesDialog.getInstance();
+ multiUserCaseWindow.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
+ multiUserCaseWindow.setVisible(true);
+ }//GEN-LAST:event_openMultiUserCaseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel autopsyLogo;
@@ -327,8 +287,8 @@ public class CueBannerPanel extends javax.swing.JPanel {
private javax.swing.JButton createNewCaseButton;
private javax.swing.JLabel createNewCaseLabel;
private javax.swing.JSeparator jSeparator1;
- private javax.swing.JButton openAutoIngestCaseButton;
- private javax.swing.JLabel openAutoIngestCaseLabel;
+ private javax.swing.JButton openMultiUserCaseButton;
+ private javax.swing.JLabel openMultiUserCaseLabel;
private javax.swing.JButton openExistingCaseButton;
private javax.swing.JLabel openExistingCaseLabel;
private javax.swing.JButton openRecentCaseButton;
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/EditOptionalCasePropertiesPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/EditOptionalCasePropertiesPanel.form
new file mode 100644
index 0000000000..c9f71e0b0e
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/EditOptionalCasePropertiesPanel.form
@@ -0,0 +1,70 @@
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/EditOptionalCasePropertiesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/EditOptionalCasePropertiesPanel.java
new file mode 100644
index 0000000000..d1c726d3eb
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/EditOptionalCasePropertiesPanel.java
@@ -0,0 +1,128 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionListener;
+import org.openide.util.NbBundle.Messages;
+
+/**
+ *
+ * @author wschaefer
+ */
+class EditOptionalCasePropertiesPanel extends javax.swing.JPanel {
+
+ private static final long serialVersionUID = 1L;
+
+ private final OptionalCasePropertiesPanel propertiesPanel;
+
+ /**
+ * Creates new form EditOptionalCasePropertiesPanel
+ */
+ EditOptionalCasePropertiesPanel() {
+ initComponents();
+ propertiesPanel = new OptionalCasePropertiesPanel(true);
+
+ optionsPanel.add(propertiesPanel);
+ optionsPanel.setVisible(true);
+ propertiesPanel.setVisible(true);
+ }
+
+ @Messages({
+ "EditOptionalCasePropertiesPanel.saveButton.text=Save",
+ "EditOptionalCasePropertiesPanel.cancelButton.text=Cancel"
+ })
+ /**
+ * 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")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ optionsPanel = new javax.swing.JPanel();
+ cancelButton = new javax.swing.JButton();
+ saveButton = new javax.swing.JButton();
+
+ optionsPanel.setLayout(new java.awt.BorderLayout());
+
+ org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(EditOptionalCasePropertiesPanel.class, "EditOptionalCasePropertiesPanel.cancelButton.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(saveButton, org.openide.util.NbBundle.getMessage(EditOptionalCasePropertiesPanel.class, "EditOptionalCasePropertiesPanel.saveButton.text")); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(254, Short.MAX_VALUE)
+ .addComponent(saveButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cancelButton)
+ .addContainerGap())
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(optionsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelButton, saveButton});
+
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap(266, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cancelButton)
+ .addComponent(saveButton))
+ .addContainerGap())
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(optionsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 262, Short.MAX_VALUE)
+ .addGap(38, 38, 38)))
+ );
+ }// //GEN-END:initComponents
+
+ void saveProperties() {
+ this.propertiesPanel.saveUpdatedCaseDetails();
+ }
+
+ /**
+ * Adds an action listener to the Save button of the panel.
+ *
+ * @param action
+ */
+ void addSaveButtonAction(ActionListener action) {
+ this.saveButton.addActionListener(action);
+ }
+
+ /**
+ * Adds an action listener to the Cancel button of the panel.
+ *
+ * @param action
+ */
+ void addCancelButtonAction(ActionListener action) {
+ this.cancelButton.addActionListener(action);
+ }
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton cancelButton;
+ private javax.swing.JPanel optionsPanel;
+ private javax.swing.JButton saveButton;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCaseManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCaseManager.java
new file mode 100755
index 0000000000..d0baf94bc9
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCaseManager.java
@@ -0,0 +1,388 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.casemodule;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
+import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
+import org.sleuthkit.autopsy.coreutils.Logger;
+
+/**
+ * Handles locating and opening multi-user cases.
+ */
+final class MultiUserCaseManager {
+
+ private static final Logger LOGGER = Logger.getLogger(MultiUserCaseManager.class.getName());
+ private static final String LOG_FILE_NAME = "auto_ingest_log.txt";
+ private static MultiUserCaseManager instance;
+ private CoordinationService coordinationService;
+
+ /**
+ * Gets the multi-user case manager.
+ *
+ * @return The multi-user case manager singleton.
+ *
+ * @throws MultiUserCaseManagerException
+ */
+ synchronized static MultiUserCaseManager getInstance() throws MultiUserCaseManager.MultiUserCaseManagerException {
+ if (null == instance) {
+ instance = new MultiUserCaseManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Constructs an object that handles locating and opening multi-user cases.
+ *
+ * @throws MultiUserCaseManagerException
+ */
+ private MultiUserCaseManager() throws MultiUserCaseManagerException {
+ try {
+ coordinationService = CoordinationService.getInstance();
+ } catch (CoordinationServiceException ex) {
+ throw new MultiUserCaseManager.MultiUserCaseManagerException("Failed to get the coordination service.", ex);
+ }
+ }
+
+ /**
+ * Gets a list of the cases in the top level case folder
+ *
+ * @return List of cases.
+ *
+ * @throws CoordinationServiceException
+ */
+ List getCases() throws CoordinationServiceException {
+ List cases = new ArrayList<>();
+ List nodeList = coordinationService.getNodeList(CoordinationService.CategoryNode.CASES);
+ for (String node : nodeList) {
+ Path casePath = Paths.get(node);
+ File caseFolder = casePath.toFile();
+ if(caseFolder.exists()) {
+ File[] autFiles = caseFolder.listFiles((dir, name) -> name.toLowerCase().endsWith(".aut"));
+ if(autFiles != null && autFiles.length > 0) {
+ try {
+ CaseMetadata caseMetadata = new CaseMetadata(Paths.get(autFiles[0].getAbsolutePath()));
+ cases.add(new MultiUserCase(casePath, caseMetadata));
+ } catch (CaseMetadata.CaseMetadataException | MultiUserCase.MultiUserCaseException ex) {
+ LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFiles[0].getAbsolutePath()), ex);
+ }
+ }
+ }
+ }
+ return cases;
+ }
+
+ /**
+ * Opens a multi-user 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());
+ }
+
+ /**
+ * Exception type thrown when there is an error completing a multi-user case
+ * manager operation.
+ */
+ static final class MultiUserCaseManagerException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs an instance of the exception type thrown when there is an
+ * error completing a multi-user case manager operation.
+ *
+ * @param message The exception message.
+ */
+ private MultiUserCaseManagerException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an instance of the exception type thrown when there is an
+ * error completing a multi-user case manager operation.
+ *
+ * @param message The exception message.
+ * @param cause A Throwable cause for the error.
+ */
+ private MultiUserCaseManagerException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ }
+
+ /**
+ * A representation of a multi-user case.
+ */
+ static class MultiUserCase implements Comparable {
+
+ private final Path caseDirectoryPath;
+ private final String caseDisplayName;
+ private final String metadataFileName;
+ private final Date createDate;
+ private final Date lastAccessedDate;
+
+ /**
+ * Constructs a representation of a multi-user case
+ *
+ * @param caseDirectoryPath The case directory path.
+ * @param caseMetadata The case metadata.
+ *
+ * @throws MultiUserCaseException If no case metadata (.aut)
+ * file is found in the case
+ * directory.
+ */
+ MultiUserCase(Path caseDirectoryPath, CaseMetadata caseMetadata) throws MultiUserCaseException {
+ this.caseDirectoryPath = caseDirectoryPath;
+ caseDisplayName = caseMetadata.getCaseDisplayName();
+ metadataFileName = caseMetadata.getFilePath().getFileName().toString();
+ BasicFileAttributes fileAttrs = null;
+ try {
+ fileAttrs = Files.readAttributes(Paths.get(caseDirectoryPath.toString(), metadataFileName), BasicFileAttributes.class);
+ } catch (IOException ex) {
+ LOGGER.log(Level.SEVERE, String.format("Error reading file attributes of case metadata file in %s, will use current time for case createDate/lastModfiedDate", caseDirectoryPath), ex);
+ }
+ if (null != fileAttrs) {
+ createDate = new Date(fileAttrs.creationTime().toMillis());
+ lastAccessedDate = new Date(fileAttrs.lastAccessTime().toMillis());
+ } else {
+ createDate = new Date();
+ lastAccessedDate = new Date();
+ }
+ }
+
+ /**
+ * Gets the case directory path.
+ *
+ * @return The case directory path.
+ */
+ Path getCaseDirectoryPath() {
+ return this.caseDirectoryPath;
+ }
+
+ /**
+ * Gets the case display name. This may differ from the name supplied to the
+ * directory or metadata file names if a case has been renamed.
+ *
+ * @return The case display name.
+ */
+ String getCaseDisplayName() {
+ return this.caseDisplayName;
+ }
+
+ /**
+ * Gets the creation date for the case, defined as the create time of the
+ * case metadata file.
+ *
+ * @return The case creation date.
+ */
+ Date getCreationDate() {
+ return this.createDate;
+ }
+
+ /**
+ * Gets the last accessed date for the case, defined as the last accessed
+ * time of the case metadata file.
+ *
+ * @return The last accessed date.
+ */
+ Date getLastAccessedDate() {
+ return this.lastAccessedDate;
+ }
+
+ /**
+ * Gets metadata (.aut) file name.
+ *
+ * @return The metadata file name.
+ */
+ String getMetadataFileName() {
+ return this.metadataFileName;
+ }
+
+ /**
+ * Gets the status of this case based on the auto ingest result file in the
+ * case directory.
+ *
+ * @return See CaseStatus enum definition.
+ */
+ CaseStatus getStatus() {
+ if(caseDirectoryPath.resolve("autoingest.alert").toFile().exists()) {
+ return CaseStatus.ALERT;
+ } else {
+ return CaseStatus.OK;
+ }
+ }
+
+ /**
+ * Gets the case metadata from a case directory path.
+ *
+ * @param caseDirectoryPath The case directory path.
+ *
+ * @return Case metadata.
+ *
+ * @throws CaseMetadata.CaseMetadataException If the CaseMetadata object
+ * cannot be constructed.
+ * @throws MultiUserCaseException If no case metadata (.aut)
+ * file is found in the case
+ * directory.
+ */
+ private CaseMetadata getCaseMetadataFromCaseDirectoryPath(Path caseDirectoryPath) throws CaseMetadata.CaseMetadataException, MultiUserCaseException {
+ CaseMetadata caseMetadata = null;
+
+ File directory = new File(caseDirectoryPath.toString());
+ if (directory.isDirectory()) {
+ File autFile = null;
+
+ /*
+ * Attempt to find an AUT file via a directory scan.
+ */
+ for (File file : directory.listFiles()) {
+ if (file.getName().toLowerCase().endsWith(CaseMetadata.getFileExtension()) && file.isFile()) {
+ autFile = file;
+ break;
+ }
+ }
+
+ if(autFile == null || !autFile.isFile()) {
+ throw new MultiUserCaseException(String.format("No case metadata (.aut) file found in the case directory '%s'.", caseDirectoryPath.toString()));
+ }
+
+ caseMetadata = new CaseMetadata(Paths.get(autFile.getAbsolutePath()));
+ }
+
+ return caseMetadata;
+ }
+
+ /**
+ * Indicates whether or not some other object is "equal to" this
+ * MultiUserCase object.
+ *
+ * @param other The other object.
+ *
+ * @return True or false.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof MultiUserCase)) {
+ return false;
+ }
+ if (other == this) {
+ return true;
+ }
+ return this.caseDirectoryPath.toString().equals(((MultiUserCase) other).caseDirectoryPath.toString());
+ }
+
+ /**
+ * Returns a hash code value for this MultiUserCase object.
+ *
+ * @return The has code.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 71 * hash + Objects.hashCode(this.caseDirectoryPath);
+ hash = 71 * hash + Objects.hashCode(this.createDate);
+ hash = 71 * hash + Objects.hashCode(this.caseDisplayName);
+ return hash;
+ }
+
+ /**
+ * Compares this MultiUserCase object with another MultiUserCase object
+ * for order.
+ */
+ @Override
+ public int compareTo(MultiUserCase other) {
+ return -this.lastAccessedDate.compareTo(other.getLastAccessedDate());
+ }
+
+ /**
+ * Comparator for a descending order sort on date created.
+ */
+ static class LastAccessedDateDescendingComparator implements Comparator {
+
+ /**
+ * Compares two MultiUserCase objects for order based on last accessed
+ * date (descending).
+ *
+ * @param object The first MultiUserCase object
+ * @param otherObject The second MultiUserCase object.
+ *
+ * @return A negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ @Override
+ public int compare(MultiUserCase object, MultiUserCase otherObject) {
+ return -object.getLastAccessedDate().compareTo(otherObject.getLastAccessedDate());
+ }
+ }
+
+ /**
+ * Exception thrown when there is a problem creating a multi-user case.
+ */
+ final class MultiUserCaseException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs an exception to throw when there is a problem creating a
+ * multi-user case.
+ *
+ * @param message The exception message.
+ */
+ private MultiUserCaseException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an exception to throw when there is a problem creating a
+ * multi-user case.
+ *
+ * @param message The exception message.
+ * @param cause The cause of the exception, if it was an exception.
+ */
+ private MultiUserCaseException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ }
+
+ static enum CaseStatus {
+ OK,
+ ALERT
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesDialog.java
new file mode 100755
index 0000000000..8c90aeccb4
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesDialog.java
@@ -0,0 +1,89 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Dialog;
+import java.awt.event.KeyEvent;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.KeyStroke;
+import org.openide.windows.WindowManager;
+
+/**
+ * This class extends a JDialog and maintains the MultiUserCasesPanel.
+ */
+final class MultiUserCasesDialog extends JDialog {
+
+ private static final long serialVersionUID = 1L;
+ private static final String REVIEW_MODE_TITLE = "Open Multi-User Case";
+ private static MultiUserCasesPanel multiUserCasesPanel;
+ private static MultiUserCasesDialog instance;
+
+ /**
+ * Gets the instance of the MultiuserCasesDialog.
+ *
+ * @return The instance.
+ */
+ static public MultiUserCasesDialog getInstance() {
+ if(instance == null) {
+ instance = new MultiUserCasesDialog();
+ instance.init();
+ }
+ return instance;
+ }
+
+ /**
+ * Constructs a MultiUserCasesDialog object.
+ */
+ private MultiUserCasesDialog() {
+ super(WindowManager.getDefault().getMainWindow(),
+ REVIEW_MODE_TITLE,
+ Dialog.ModalityType.APPLICATION_MODAL);
+ }
+
+ /**
+ * Initializes the multi-user cases panel.
+ */
+ private void init() {
+ getRootPane().registerKeyboardAction(
+ e -> {
+ setVisible(false);
+ },
+ KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
+
+ multiUserCasesPanel = new MultiUserCasesPanel(this);
+ add(multiUserCasesPanel);
+ pack();
+ setResizable(false);
+ }
+
+ /**
+ * Set the dialog visibility. When setting it to visible, the contents will
+ * refresh.
+ *
+ * @param value True or false.
+ */
+ @Override
+ public void setVisible(boolean value) {
+ if(value) {
+ multiUserCasesPanel.refresh();
+ }
+ super.setVisible(value);
+ }
+}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCasePanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form
similarity index 84%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCasePanel.form
rename to Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form
index cb0f275809..179bc23bb8 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCasePanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form
@@ -45,7 +45,7 @@
-
+
@@ -82,7 +82,7 @@
-
+
@@ -118,7 +118,7 @@
-
+
@@ -153,7 +153,7 @@
-
+
@@ -165,10 +165,10 @@
-
+
-
+
@@ -182,7 +182,7 @@
-
+
@@ -196,7 +196,7 @@
-
+
@@ -209,7 +209,7 @@
-
+
@@ -222,7 +222,7 @@
-
+
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCasePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java
similarity index 64%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCasePanel.java
rename to Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java
index 2bcd335916..7e87ce8947 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCasePanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java
@@ -16,52 +16,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.casemodule;
import java.awt.Cursor;
import java.awt.Desktop;
-import java.awt.EventQueue;
-import java.awt.event.ActionEvent;
-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.ExecutionException;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
-import org.openide.util.NbBundle;
-import org.openide.util.lookup.ServiceProvider;
-import org.openide.windows.WindowManager;
-import org.sleuthkit.autopsy.casemodule.CaseActionCancelledException;
-import org.sleuthkit.autopsy.casemodule.CaseMetadata;
-import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
+import org.sleuthkit.autopsy.casemodule.MultiUserCaseManager.MultiUserCase;
+import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.guiutils.LongDateCellRenderer;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
-import org.sleuthkit.autopsy.casemodule.AutoIngestCasePanelInterface;
-import org.sleuthkit.autopsy.casemodule.CueBannerPanel;
-import org.sleuthkit.autopsy.coreutils.NetworkUtils;
-import org.sleuthkit.autopsy.experimental.configuration.StartupWindow;
+import org.sleuthkit.autopsy.guiutils.GrayableCellRenderer;
+import org.sleuthkit.autopsy.guiutils.StatusIconCellRenderer;
/**
* A panel that allows a user to open cases created by auto ingest.
*/
-@ServiceProvider(service = AutoIngestCasePanelInterface.class)
-public final class AutoIngestCasePanel extends JPanel implements AutoIngestCasePanelInterface {
+final class MultiUserCasesPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
- private static final Logger logger = Logger.getLogger(AutoIngestCasePanel.class.getName());
- private static final AutoIngestCase.LastAccessedDateDescendingComparator reverseDateModifiedComparator = new AutoIngestCase.LastAccessedDateDescendingComparator();
+ private static final Logger LOGGER = Logger.getLogger(MultiUserCasesPanel.class.getName());
+ private static final String LOG_FILE_NAME = "auto_ingest_log.txt";
+ private static final MultiUserCaseManager.MultiUserCase.LastAccessedDateDescendingComparator REVERSE_DATE_MODIFIED_COMPARATOR = new MultiUserCaseManager.MultiUserCase.LastAccessedDateDescendingComparator();
private static final int CASE_COL_MIN_WIDTH = 30;
private static final int CASE_COL_MAX_WIDTH = 2000;
private static final int CASE_COL_PREFERRED_WIDTH = 300;
@@ -71,9 +57,6 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
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 MILLIS_TO_WAIT_BEFORE_STARTING = 500;
- private static final int MILLIS_TO_WAIT_BETWEEN_UPDATES = 300000;
- private ScheduledThreadPoolExecutor casesTableRefreshExecutor;
/*
* The JTable table model for the cases table presented by this view is
@@ -82,11 +65,12 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
* 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(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");
+ private static final String CASE_HEADER = org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.CaseHeaderText");
+ private static final String CREATEDTIME_HEADER = org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.CreatedTimeHeaderText");
+ private static final String COMPLETEDTIME_HEADER = org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.LastAccessedTimeHeaderText");
+ private static final String STATUS_ICON_HEADER = org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.StatusIconHeaderText");
+ private static final String OUTPUT_FOLDER_HEADER = org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.OutputFolderHeaderText");
+ private static final String METADATA_FILE_HEADER = org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.MetadataFileHeaderText");
enum COLUMN_HEADERS {
@@ -94,51 +78,20 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
CREATEDTIME,
COMPLETEDTIME,
STATUS_ICON,
- OUTPUTFOLDER
+ OUTPUTFOLDER,
+ METADATA_FILE
}
- private final String[] columnNames = {CASE_HEADER, CREATEDTIME_HEADER, COMPLETEDTIME_HEADER, STATUS_ICON_HEADER, OUTPUT_FOLDER_HEADER};
+ private final String[] columnNames = {CASE_HEADER, CREATEDTIME_HEADER, COMPLETEDTIME_HEADER, STATUS_ICON_HEADER, OUTPUT_FOLDER_HEADER, METADATA_FILE_HEADER};
private DefaultTableModel caseTableModel;
private Path currentlySelectedCase = null;
-
- public AutoIngestCasePanel() {
- init(null);
- }
-
- @Override
- public void addWindowStateListener(JDialog parent) {
- /*
- * Add a window state listener that starts and stops refreshing of the
- * cases table.
- */
- parent.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- stopCasesTableRefreshes();
- }
-
- @Override
- public void windowActivated(WindowEvent e) {
- startCasesTableRefreshes();
- }
-
- @Override
- public void windowClosed(WindowEvent e) {
- stopCasesTableRefreshes();
- }
- });
- }
+ private JDialog parentDialog;
/**
* Constructs a panel that allows a user to open cases created by automated
* ingest.
- *
- * @param parent The parent dialog for this panel.
*/
- public AutoIngestCasePanel(JDialog parent) {
- init(parent);
- }
-
- public void init(JDialog parent) {
+ MultiUserCasesPanel(JDialog parentDialog) {
+ this.parentDialog = parentDialog;
caseTableModel = new DefaultTableModel(columnNames, 0) {
private static final long serialVersionUID = 1L;
@@ -146,6 +99,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
public boolean isCellEditable(int row, int column) {
return false;
}
+
@Override
public Class> getColumnClass(int col) {
if (this.getColumnName(col).equals(CREATEDTIME_HEADER) || this.getColumnName(col).equals(COMPLETEDTIME_HEADER)) {
@@ -184,13 +138,14 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
theColumn.setWidth(TIME_COL_PREFERRED_WIDTH);
theColumn = casesTable.getColumn(STATUS_ICON_HEADER);
- theColumn.setCellRenderer(new CaseStatusIconCellRenderer());
+ theColumn.setCellRenderer(new StatusIconCellRenderer());
theColumn.setMinWidth(STATUS_COL_MIN_WIDTH);
theColumn.setMaxWidth(STATUS_COL_MAX_WIDTH);
theColumn.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH);
theColumn.setWidth(STATUS_COL_PREFERRED_WIDTH);
casesTable.removeColumn(casesTable.getColumn(OUTPUT_FOLDER_HEADER));
+ casesTable.removeColumn(casesTable.getColumn(METADATA_FILE_HEADER));
/*
* Listen for row selection changes and set button state for the current
@@ -203,75 +158,39 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
}
setButtons();
});
-
- /*
- * Add a window state listener that starts and stops refreshing of the
- * cases table.
- */
- if (parent != null) {
- parent.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- stopCasesTableRefreshes();
- }
-
- @Override
- public void windowActivated(WindowEvent e) {
- startCasesTableRefreshes();
- }
-
- @Override
- public void windowClosed(WindowEvent e) {
- stopCasesTableRefreshes();
- }
- });
- }
- }
-
- /**
- * Start doing periodic refreshes of the cases table.
- */
- private void startCasesTableRefreshes() {
- if (null == casesTableRefreshExecutor) {
- casesTableRefreshExecutor = new ScheduledThreadPoolExecutor(1);
- this.casesTableRefreshExecutor.scheduleAtFixedRate(() -> {
- refreshCasesTable();
- }, MILLIS_TO_WAIT_BEFORE_STARTING, MILLIS_TO_WAIT_BETWEEN_UPDATES, TimeUnit.MILLISECONDS);
- }
- }
-
- /**
- * Stop doing periodic refreshes of the cases table.
- */
- private void stopCasesTableRefreshes() {
- if (null != casesTableRefreshExecutor) {
- casesTableRefreshExecutor.shutdown();
- }
- this.casesTableRefreshExecutor = null;
- }
-
- /*
- * Updates the view presented by the panel.
- */
- public void updateView() {
- Thread thread = new Thread(() -> {
- refreshCasesTable();
- });
- thread.start();
}
/**
* Gets the list of cases known to the review mode cases manager and
* refreshes the cases table.
*/
- private void refreshCasesTable() {
+ void refresh() {
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
try {
currentlySelectedCase = getSelectedCase();
- AutoIngestCaseManager manager = AutoIngestCaseManager.getInstance();
- List theModel = manager.getCases();
- EventQueue.invokeLater(new CaseTableRefreshTask(theModel));
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Unexpected exception in refreshCasesTable", ex); //NON-NLS
+ MultiUserCaseManager manager = MultiUserCaseManager.getInstance();
+ List cases = manager.getCases();
+ cases.sort(REVERSE_DATE_MODIFIED_COMPARATOR);
+ caseTableModel.setRowCount(0);
+ long now = new Date().getTime();
+ for (MultiUserCase autoIngestCase : cases) {
+ if (passesTimeFilter(now, autoIngestCase.getLastAccessedDate().getTime())) {
+ caseTableModel.addRow(new Object[]{
+ autoIngestCase.getCaseDisplayName(),
+ autoIngestCase.getCreationDate(),
+ autoIngestCase.getLastAccessedDate(),
+ (MultiUserCaseManager.CaseStatus.OK != autoIngestCase.getStatus()) ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK,
+ autoIngestCase.getCaseDirectoryPath().toString(),
+ autoIngestCase.getMetadataFileName()});
+ }
+ }
+ setSelectedCase(currentlySelectedCase);
+ setButtons();
+ } catch (MultiUserCaseManager.MultiUserCaseManagerException | CoordinationService.CoordinationServiceException ex) {
+ LOGGER.log(Level.SEVERE, "Unexpected exception while refreshing the table.", ex); //NON-NLS
+ } finally {
+ setCursor(null);
}
}
@@ -320,103 +239,78 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
* in the cases table.
*/
private void setButtons() {
- boolean enabled = casesTable.getSelectedRow() >= 0 && casesTable.getSelectedRow() < casesTable.getRowCount();
- bnOpen.setEnabled(enabled);
- bnShowLog.setEnabled(enabled);
+ boolean openEnabled = casesTable.getSelectedRow() >= 0 && casesTable.getSelectedRow() < casesTable.getRowCount();
+ bnOpen.setEnabled(openEnabled);
+
+ Path pathToLog = getSelectedCaseLogFilePath();
+ boolean showLogEnabled = openEnabled && pathToLog != null && pathToLog.toFile().exists();
+ bnShowLog.setEnabled(showLogEnabled);
}
/**
- * Opens a case.
+ * Retrieves the log file path for the selected case in the cases table.
+ *
+ * @return The case log path.
+ */
+ private Path getSelectedCaseLogFilePath() {
+ Path retValue = null;
+
+ int selectedRow = casesTable.getSelectedRow();
+ int rowCount = casesTable.getRowCount();
+ if (selectedRow >= 0 && selectedRow < rowCount) {
+ String caseDirectory = (String) caseTableModel.getValueAt(casesTable.convertRowIndexToModel(selectedRow), COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
+ retValue = Paths.get(caseDirectory, LOG_FILE_NAME);
+ }
+
+ return retValue;
+ }
+
+ /**
+ * Open a case.
*
* @param caseMetadataFilePath The path to the case metadata file.
*/
private void openCase(Path caseMetadataFilePath) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- new SwingWorker() {
-
- @Override
- protected Void doInBackground() throws Exception {
- AutoIngestCaseManager.getInstance().openCase(caseMetadataFilePath);
- stopCasesTableRefreshes();
- StartupWindowProvider.getInstance().close();
- CueBannerPanel.closeAutoIngestCasesWindow();
- return null;
+ try {
+ StartupWindowProvider.getInstance().close();
+ if (parentDialog != null) {
+ parentDialog.setVisible(false);
}
-
- @Override
- protected void done() {
- try {
- get();
- } catch (InterruptedException | ExecutionException ex) {
- 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
- MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
- }
- StartupWindowProvider.getInstance().open();
- } finally {
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- }
+ MultiUserCaseManager.getInstance().openCase(caseMetadataFilePath);
+ } catch (CaseActionException | MultiUserCaseManager.MultiUserCaseManagerException ex) {
+ 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
+ MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
}
- }.execute();
+ StartupWindowProvider.getInstance().open();
+ } finally {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
}
/**
- * A task that refreshes the cases table using a list of auto ingest cases.
+ * Indicates whether or not a time satisfies a time filter defined by this
+ * panel's time filter radio buttons.
+ *
+ * @param currentTime The current date and time in milliseconds from the
+ * Unix epoch.
+ * @param inputTime The date and time to be tested as milliseconds from
+ * the Unix epoch.
*/
- private class CaseTableRefreshTask implements Runnable {
-
- private final List cases;
-
- CaseTableRefreshTask(List cases) {
- setButtons();
- this.cases = cases;
+ private boolean passesTimeFilter(long currentTime, long inputTime) {
+ long numberOfUnits = 10;
+ 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;
}
-
- /**
- * @inheritDoc
- */
- @Override
- public void run() {
- cases.sort(reverseDateModifiedComparator);
- caseTableModel.setRowCount(0);
- long now = new Date().getTime();
- for (AutoIngestCase autoIngestCase : cases) {
- if (passesTimeFilter(now, autoIngestCase.getLastAccessedDate().getTime())) {
- caseTableModel.addRow(new Object[]{
- autoIngestCase.getCaseName(),
- autoIngestCase.getCreationDate(),
- autoIngestCase.getLastAccessedDate(),
- (AutoIngestCase.CaseStatus.OK != autoIngestCase.getStatus()),
- autoIngestCase.getCaseDirectoryPath().toString()});
- }
- }
- setSelectedCase(currentlySelectedCase);
- }
-
- /**
- * Indicates whether or not a time satisfies a time filter defined by
- * this panel's time filter radio buttons.
- *
- * @param currentTime The current date and time in milliseconds from the
- * Unix epoch.
- * @param inputTime The date and time to be tested as milliseconds
- * from the Unix epoch.
- */
- private boolean passesTimeFilter(long currentTime, long inputTime) {
- long numberOfUnits = 10;
- 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;
- }
- return ((currentTime - inputTime) / (1000 * 60 * 60 * 24)) < (numberOfUnits * multiplier);
- }
-
+ return ((currentTime - inputTime) / (1000 * 60 * 60 * 24)) < (numberOfUnits * multiplier);
}
/**
@@ -443,7 +337,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
setName("Completed Cases"); // NOI18N
- org.openide.awt.Mnemonics.setLocalizedText(bnOpen, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.bnOpen.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(bnOpen, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnOpen.text")); // NOI18N
bnOpen.setEnabled(false);
bnOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -463,7 +357,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
});
scrollPaneTable.setViewportView(casesTable);
- org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.bnRefresh.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnRefresh.text")); // NOI18N
bnRefresh.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnRefreshActionPerformed(evt);
@@ -472,7 +366,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
rbGroupHistoryLength.add(rbAllCases);
rbAllCases.setSelected(true);
- org.openide.awt.Mnemonics.setLocalizedText(rbAllCases, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbAllCases.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(rbAllCases, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbAllCases.text")); // NOI18N
rbAllCases.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbAllCasesItemStateChanged(evt);
@@ -494,8 +388,8 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
.addComponent(rbAllCases))
);
- 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
+ org.openide.awt.Mnemonics.setLocalizedText(bnShowLog, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnShowLog.text")); // NOI18N
+ bnShowLog.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnShowLog.toolTipText")); // NOI18N
bnShowLog.setEnabled(false);
bnShowLog.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -504,7 +398,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
});
rbGroupHistoryLength.add(rbDays);
- org.openide.awt.Mnemonics.setLocalizedText(rbDays, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbDays.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(rbDays, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbDays.text")); // NOI18N
rbDays.setName(""); // NOI18N
rbDays.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
@@ -513,7 +407,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
});
rbGroupHistoryLength.add(rbWeeks);
- org.openide.awt.Mnemonics.setLocalizedText(rbWeeks, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbWeeks.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(rbWeeks, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbWeeks.text")); // NOI18N
rbWeeks.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbWeeksItemStateChanged(evt);
@@ -521,7 +415,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
});
rbGroupHistoryLength.add(rbMonths);
- org.openide.awt.Mnemonics.setLocalizedText(rbMonths, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbMonths.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(rbMonths, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbMonths.text")); // NOI18N
rbMonths.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbMonthsItemStateChanged(evt);
@@ -529,7 +423,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
});
rbGroupLabel.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
- org.openide.awt.Mnemonics.setLocalizedText(rbGroupLabel, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "AutoIngestCasePanel.rbGroupLabel.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(rbGroupLabel, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbGroupLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@@ -556,7 +450,7 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnRefresh)
.addGap(4, 4, 4))
- .addComponent(scrollPaneTable, javax.swing.GroupLayout.DEFAULT_SIZE, 1007, Short.MAX_VALUE))
+ .addComponent(scrollPaneTable))
.addContainerGap())
);
layout.setVerticalGroup(
@@ -588,10 +482,12 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
*/
private void bnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenActionPerformed
int modelRow = casesTable.convertRowIndexToModel(casesTable.getSelectedRow());
- Path caseMetadataFilePath = Paths.get((String) caseTableModel.getValueAt(modelRow,
- COLUMN_HEADERS.OUTPUTFOLDER.ordinal()),
- caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.CASE.ordinal()) + CaseMetadata.getFileExtension());
- openCase(caseMetadataFilePath);
+ String caseDirectory = (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
+ Path caseMetadataFilePath = Paths.get(caseDirectory, (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.METADATA_FILE.ordinal()));
+
+ new Thread(() -> {
+ openCase(caseMetadataFilePath);
+ }).start();
}//GEN-LAST:event_bnOpenActionPerformed
/**
@@ -599,53 +495,50 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
*
* @param evt -- The event that caused this to be called
*/
- private void bnRefreshActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bnRefreshActionPerformed
- {//GEN-HEADEREND:event_bnRefreshActionPerformed
- updateView();
- }//GEN-LAST:event_bnRefreshActionPerformed
+ private void bnRefreshActionPerformed(java.awt.event.ActionEvent evt) {
+ refresh();
+ }
- private void rbDaysItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbDaysItemStateChanged
+ private void rbDaysItemStateChanged(java.awt.event.ItemEvent evt) {
if (rbDays.isSelected()) {
- updateView();
+ refresh();
}
- }//GEN-LAST:event_rbDaysItemStateChanged
+ }
private void rbAllCasesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbAllCasesItemStateChanged
if (rbAllCases.isSelected()) {
- updateView();
+ refresh();
}
}//GEN-LAST:event_rbAllCasesItemStateChanged
private void rbMonthsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbMonthsItemStateChanged
if (rbMonths.isSelected()) {
- updateView();
+ refresh();
}
}//GEN-LAST:event_rbMonthsItemStateChanged
private void rbWeeksItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbWeeksItemStateChanged
if (rbWeeks.isSelected()) {
- updateView();
+ refresh();
}
}//GEN-LAST:event_rbWeeksItemStateChanged
private void bnShowLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnShowLogActionPerformed
- int selectedRow = casesTable.convertRowIndexToModel(casesTable.getSelectedRow());
- int rowCount = casesTable.getRowCount();
- if (selectedRow >= 0 && selectedRow < rowCount) {
- String thePath = (String) caseTableModel.getValueAt(selectedRow, COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
- Path pathToLog = AutoIngestJobLogger.getLogPath(Paths.get(thePath));
+ Path pathToLog = getSelectedCaseLogFilePath();
+ if (pathToLog != null) {
try {
if (pathToLog.toFile().exists()) {
Desktop.getDesktop().edit(pathToLog.toFile());
+
} else {
- JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.cannotFindLog"),
- org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.unableToShowLogFile"), JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.cannotFindLog"),
+ org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.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);
+ 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(AutoIngestCasePanel.class, "DisplayLogDialog.cannotOpenLog"),
- org.openide.util.NbBundle.getMessage(AutoIngestCasePanel.class, "DisplayLogDialog.unableToShowLogFile"),
+ org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.cannotOpenLog"),
+ org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.unableToShowLogFile"),
JOptionPane.PLAIN_MESSAGE);
}
}
@@ -654,9 +547,8 @@ public final class AutoIngestCasePanel extends JPanel implements AutoIngestCaseP
private void casesTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_casesTableMouseClicked
if (evt.getClickCount() == 2) {
int modelRow = casesTable.convertRowIndexToModel(casesTable.getSelectedRow());
- Path caseMetadataFilePath = Paths.get((String) caseTableModel.getValueAt(modelRow,
- COLUMN_HEADERS.OUTPUTFOLDER.ordinal()),
- caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.CASE.ordinal()) + CaseMetadata.getFileExtension());
+ String caseDirectory = (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
+ Path caseMetadataFilePath = Paths.get(caseDirectory, (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.METADATA_FILE.ordinal()));
openCase(caseMetadataFilePath);
}
}//GEN-LAST:event_casesTableMouseClicked
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form
index 72b0a6cb9b..5eb64d5756 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form
@@ -29,10 +29,6 @@
-
-
-
-
@@ -49,7 +45,7 @@
-
+
@@ -72,9 +68,7 @@
-
-
-
+
@@ -97,24 +91,12 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java
index d3f19f872c..d736aae980 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java
@@ -202,7 +202,6 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
private void initComponents() {
caseTypeButtonGroup = new javax.swing.ButtonGroup();
- jLabel1 = new javax.swing.JLabel();
caseNameLabel = new javax.swing.JLabel();
caseDirLabel = new javax.swing.JLabel();
caseNameTextField = new javax.swing.JTextField();
@@ -215,9 +214,6 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
caseParentDirWarningLabel = new javax.swing.JLabel();
caseTypeLabel = new javax.swing.JLabel();
- jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD, 14));
- org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.jLabel1.text_1")); // NOI18N
-
caseNameLabel.setFont(caseNameLabel.getFont().deriveFont(caseNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(caseNameLabel, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseNameLabel.text_1")); // NOI18N
@@ -283,9 +279,6 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(caseDirTextField, javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
- .addComponent(jLabel1)
- .addGap(0, 227, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(caseNameLabel)
.addGap(26, 26, 26)
@@ -300,7 +293,7 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
.addComponent(singleUserCaseRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(multiUserCaseRadioButton)
- .addGap(0, 0, Short.MAX_VALUE))
+ .addGap(0, 192, Short.MAX_VALUE))
.addComponent(caseParentDirTextField))))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(caseDirBrowseButton)))
@@ -312,9 +305,7 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
- .addGap(31, 31, 31)
- .addComponent(jLabel1)
- .addGap(18, 18, 18)
+ .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(caseNameLabel)
.addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
@@ -334,7 +325,7 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
.addComponent(caseDirTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(27, 27, 27)
.addComponent(caseParentDirWarningLabel)
- .addContainerGap(21, Short.MAX_VALUE))
+ .addContainerGap(115, Short.MAX_VALUE))
);
}// //GEN-END:initComponents
@@ -377,7 +368,6 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
private javax.swing.JLabel caseParentDirWarningLabel;
private javax.swing.ButtonGroup caseTypeButtonGroup;
private javax.swing.JLabel caseTypeLabel;
- private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JRadioButton multiUserCaseRadioButton;
private javax.swing.JRadioButton singleUserCaseRadioButton;
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form
index fcce5c4033..1acb2b02db 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form
@@ -11,110 +11,8 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java
index e20fce9aea..2098fc91b3 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java
@@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
- *
- * Copyright 2011 Basis Technology Corp.
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier sleuthkit 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.
@@ -17,7 +17,7 @@
* limitations under the License.
*/
-/*
+ /*
* NewCaseVisualPanel2.java
*
* Created on Mar 7, 2012, 11:01:48 AM
@@ -26,19 +26,25 @@ package org.sleuthkit.autopsy.casemodule;
import org.openide.util.NbBundle;
-import java.awt.*;
-
/**
*
* @author dfickling
*/
-class NewCaseVisualPanel2 extends javax.swing.JPanel {
+final class NewCaseVisualPanel2 extends javax.swing.JPanel {
+
+ private static final long serialVersionUID = 1L;
+
+ private final OptionalCasePropertiesPanel propertiesPanel;
/**
* Creates new form NewCaseVisualPanel2
*/
- public NewCaseVisualPanel2() {
+ NewCaseVisualPanel2() {
initComponents();
+ propertiesPanel = new OptionalCasePropertiesPanel();
+ this.add(propertiesPanel);
+ propertiesPanel.setVisible(true);
+
}
/**
@@ -61,75 +67,61 @@ class NewCaseVisualPanel2 extends javax.swing.JPanel {
// //GEN-BEGIN:initComponents
private void initComponents() {
- caseNumberTextField = new javax.swing.JTextField();
- examinerTextField = new javax.swing.JTextField();
- caseNumberLabel = new javax.swing.JLabel();
- examinerLabel = new javax.swing.JLabel();
- optionalLabel = new javax.swing.JLabel();
-
- caseNumberTextField.setFont(caseNumberTextField.getFont().deriveFont(caseNumberTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- caseNumberTextField.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.caseNumberTextField.text")); // NOI18N
-
- examinerTextField.setFont(examinerTextField.getFont().deriveFont(examinerTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- examinerTextField.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.examinerTextField.text")); // NOI18N
-
- caseNumberLabel.setFont(caseNumberLabel.getFont().deriveFont(caseNumberLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- caseNumberLabel.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.caseNumberLabel.text")); // NOI18N
-
- examinerLabel.setFont(examinerLabel.getFont().deriveFont(examinerLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- examinerLabel.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.examinerLabel.text")); // NOI18N
-
- optionalLabel.setFont(optionalLabel.getFont().deriveFont(optionalLabel.getFont().getStyle() | java.awt.Font.BOLD, 14));
- optionalLabel.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.optionalLabel.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()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(optionalLabel)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(caseNumberLabel)
- .addGap(25, 25, 25)
- .addComponent(caseNumberTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addComponent(examinerLabel)
- .addGap(45, 45, 45)
- .addComponent(examinerTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)))
- .addContainerGap())
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(optionalLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(caseNumberLabel)
- .addComponent(caseNumberTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(18, 18, 18)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(examinerLabel)
- .addComponent(examinerTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
+ setLayout(new java.awt.BorderLayout());
}// //GEN-END:initComponents
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JLabel caseNumberLabel;
- private javax.swing.JTextField caseNumberTextField;
- private javax.swing.JLabel examinerLabel;
- private javax.swing.JTextField examinerTextField;
- private javax.swing.JLabel optionalLabel;
- // End of variables declaration//GEN-END:variables
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
String getCaseNumber() {
- return caseNumberTextField.getText();
+ return propertiesPanel.getCaseNumber();
}
- String getExaminer() {
- return examinerTextField.getText();
+ String getExaminerName() {
+ return propertiesPanel.getExaminerName();
+ }
+
+ String getExaminerPhone() {
+ return propertiesPanel.getExaminerPhone();
+ }
+
+ String getExaminerEmail() {
+ return propertiesPanel.getExaminerEmail();
+ }
+
+ String getCaseNotes() {
+ return propertiesPanel.getCaseNotes();
+ }
+
+ String getOrganization() {
+ return propertiesPanel.getOrganization();
+ }
+
+ void setCaseNumber(String caseNumber) {
+ propertiesPanel.setCaseNumberField(caseNumber);
+ }
+
+ void setExaminerName(String examinerName) {
+ propertiesPanel.setExaminerNameField(examinerName);
+ }
+
+ void setExaminerPhone(String examinerPhone) {
+ propertiesPanel.setExaminerPhoneField(examinerPhone);
+ }
+
+ void setExaminerEmail(String examinerEmail) {
+ propertiesPanel.setExaminerEmailField(examinerEmail);
+ }
+
+ void setCaseNotes(String caseNotes) {
+ propertiesPanel.setCaseNotesField(caseNotes);
+ }
+
+ void setOrganization(String organizationName) {
+ propertiesPanel.setCurrentlySelectedOrganization(organizationName);
+ }
+
+ void refreshCaseDetailsFields() {
+ propertiesPanel.setUpCaseDetailsFields();
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
index 3679587491..7a4a1f7bf4 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
@@ -37,6 +37,10 @@ import org.openide.util.actions.SystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
+import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
@@ -75,11 +79,32 @@ final class NewCaseWizardAction extends CallableSystemAction {
@Override
protected Void doInBackground() throws Exception {
String caseNumber = (String) wizardDescriptor.getProperty("caseNumber"); //NON-NLS
- String examiner = (String) wizardDescriptor.getProperty("caseExaminer"); //NON-NLS
+ String examinerName = (String) wizardDescriptor.getProperty("caseExaminerName"); //NON-NLS
+ String examinerPhone = (String) wizardDescriptor.getProperty("caseExaminerPhone"); //NON-NLS
+ String examinerEmail = (String) wizardDescriptor.getProperty("caseExaminerEmail"); //NON-NLS
+ String caseNotes = (String) wizardDescriptor.getProperty("caseNotes"); //NON-NLS
+ String organizationName = (String) wizardDescriptor.getProperty("caseOrganization"); //NON-NLS
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.createAsCurrentCase(createdDirectory, caseName, caseNumber, examiner, caseType);
+ Case.createAsCurrentCase(caseType, createdDirectory, new CaseDetails(caseName, caseNumber, examinerName, examinerPhone, examinerEmail, caseNotes));
+ if (EamDb.isEnabled()) { //if the eam is enabled we need to save the case organization information now
+ EamDb dbManager = EamDb.getInstance();
+ if (dbManager != null) {
+ CorrelationCase cRCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ if (cRCase == null) {
+ cRCase = dbManager.newCase(Case.getCurrentCase());
+ }
+ if (!organizationName.isEmpty()) {
+ for (EamOrganization org : dbManager.getOrganizations()) {
+ if (org.getName().equals(organizationName)) {
+ cRCase.setOrg(org);
+ dbManager.updateCase(cRCase);
+ }
+ }
+ }
+ }
+ }
return null;
}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java
index d8888a8865..7752611202 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel2.java
@@ -28,12 +28,22 @@ import org.openide.WizardValidationException;
import org.openide.util.HelpCtx;
import org.openide.windows.WindowManager;
import java.awt.Cursor;
+import java.util.logging.Level;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/**
* The second panel of the New Case wizard.
*/
class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel {
+ private static final Logger logger = Logger.getLogger(NewCaseWizardPanel2.class.getName());
+ private static final String PROP_EXAMINER_NAME = "LBL_EXAMINER_NAME"; //NON-NLS
+ private static final String PROP_EXAMINER_PHONE = "LBL_EXAMINER_PHONE"; //NON-NLS
+ private static final String PROP_EXAMINER_EMAIL = "LBL_EXAMINER_EMAIL"; //NON-NLS
+ private static final String PROP_CASE_NOTES = "LBL_CASE_NOTES"; //NON-NLS
+ private static final String PROP_ORGANIZATION_NAME = "LBL_ORGANIZATION_NAME"; //NON-NLS
private NewCaseVisualPanel2 component;
private final Set listeners = new HashSet<>(1);
@@ -46,7 +56,10 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java
new file mode 100644
index 0000000000..a2793ec295
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java
@@ -0,0 +1,609 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Cursor;
+import java.util.logging.Level;
+import javax.swing.JComboBox;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle.Messages;
+import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
+import org.sleuthkit.autopsy.centralrepository.optionspanel.ManageOrganizationsDialog;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
+
+/**
+ * Panel which allows for editing and setting of the case details which are
+ * optional or otherwise able to be edited.
+ */
+final class OptionalCasePropertiesPanel extends javax.swing.JPanel {
+
+ private final static Logger LOGGER = Logger.getLogger(OptionalCasePropertiesPanel.class.getName());
+ private static final long serialVersionUID = 1L;
+ private EamOrganization selectedOrg = null;
+ private java.util.List orgs = null;
+
+ /**
+ * Creates new form OptionalCasePropertiesPanel
+ */
+ OptionalCasePropertiesPanel() {
+ initComponents();
+ caseDisplayNameLabel.setVisible(false);
+ caseDisplayNameTextField.setVisible(false);
+ lbPointOfContactNameLabel.setVisible(false);
+ lbPointOfContactNameText.setVisible(false);
+ lbPointOfContactPhoneLabel.setVisible(false);
+ lbPointOfContactPhoneText.setVisible(false);
+ lbPointOfContactEmailLabel.setVisible(false);
+ lbPointOfContactEmailText.setVisible(false);
+ setUpCaseDetailsFields();
+ }
+
+ OptionalCasePropertiesPanel(boolean editCurrentCase) {
+ initComponents();
+ if (editCurrentCase) {
+ caseDisplayNameTextField.setText(Case.getCurrentCase().getDisplayName());
+ caseNumberTextField.setText(Case.getCurrentCase().getNumber());
+ examinerTextField.setText(Case.getCurrentCase().getExaminer());
+ tfExaminerEmailText.setText(Case.getCurrentCase().getExaminerEmail());
+ tfExaminerPhoneText.setText(Case.getCurrentCase().getExaminerPhone());
+ taNotesText.setText(Case.getCurrentCase().getCaseNotes());
+ setUpCaseDetailsFields();
+ setUpOrganizationData();
+ } else {
+ caseDisplayNameLabel.setVisible(false);
+ caseDisplayNameTextField.setVisible(false);
+ lbPointOfContactNameLabel.setVisible(false);
+ lbPointOfContactNameText.setVisible(false);
+ lbPointOfContactPhoneLabel.setVisible(false);
+ lbPointOfContactPhoneText.setVisible(false);
+ lbPointOfContactEmailLabel.setVisible(false);
+ lbPointOfContactEmailText.setVisible(false);
+ setUpCaseDetailsFields();
+ }
+
+ }
+
+ private void setUpOrganizationData() {
+ if (EamDb.isEnabled()) {
+ Case currentCase = Case.getCurrentCase();
+ if (currentCase != null) {
+ try {
+ EamDb dbManager = EamDb.getInstance();
+ selectedOrg = dbManager.getCaseByUUID(currentCase.getName()).getOrg();
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Unable to get Organization associated with the case from Central Repo", ex);
+ }
+ }
+ if (selectedOrg != null) {
+ setCurrentlySelectedOrganization(selectedOrg.getName());
+ }
+ }
+ }
+
+ void setUpCaseDetailsFields() {
+ boolean cREnabled = EamDb.isEnabled();
+ comboBoxOrgName.setEnabled(cREnabled);
+ bnNewOrganization.setEnabled(cREnabled);
+ lbPointOfContactNameText.setEnabled(cREnabled);
+ lbPointOfContactEmailText.setEnabled(cREnabled);
+ lbPointOfContactPhoneText.setEnabled(cREnabled);
+ lbOrganizationNameLabel.setEnabled(cREnabled);
+ lbPointOfContactNameLabel.setEnabled(cREnabled);
+ lbPointOfContactEmailLabel.setEnabled(cREnabled);
+ lbPointOfContactPhoneLabel.setEnabled(cREnabled);
+ orgainizationPanel.setEnabled(cREnabled);
+ if (!cREnabled) {
+ clearOrganization();
+ } else {
+ loadOrganizationData();
+ }
+
+ }
+
+ private void loadOrganizationData() {
+ Object selectedBeforeLoad = comboBoxOrgName.getSelectedItem();
+ comboBoxOrgName.removeAllItems();
+ try {
+ comboBoxOrgName.addItem(""); // for when a case has a null Org
+ EamDb dbManager = EamDb.getInstance();
+ orgs = dbManager.getOrganizations();
+ orgs.forEach((org) -> {
+ comboBoxOrgName.addItem(org.getName());
+ });
+ comboBoxOrgName.setSelectedItem(selectedBeforeLoad);
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.WARNING, "Unable to populate list of Organizations from Central Repo", ex);
+ }
+ }
+
+ private void clearOrganization() {
+ selectedOrg = null;
+ lbPointOfContactNameText.setText("");
+ lbPointOfContactEmailText.setText("");
+ lbPointOfContactPhoneText.setText("");
+ }
+
+ String getCaseNumber() {
+ return caseNumberTextField.getText();
+ }
+
+ String getExaminerName() {
+ return examinerTextField.getText();
+ }
+
+ String getExaminerPhone() {
+ return tfExaminerPhoneText.getText();
+ }
+
+ String getExaminerEmail() {
+ return tfExaminerEmailText.getText();
+ }
+
+ String getCaseNotes() {
+ return taNotesText.getText();
+ }
+
+ String getOrganization() {
+ if (selectedOrg != null) {
+ return selectedOrg.getName();
+ } else {
+ return "";
+ }
+ }
+
+ void setCaseNumberField(String caseNumber) {
+ caseNumberTextField.setText(caseNumber == null ? "" : caseNumber);
+ }
+
+ void setExaminerNameField(String examinerName) {
+ examinerTextField.setText(examinerName == null ? "" : examinerName);
+ }
+
+ void setExaminerPhoneField(String examinerPhone) {
+ tfExaminerPhoneText.setText(examinerPhone == null ? "" : examinerPhone);
+ }
+
+ void setExaminerEmailField(String examinerEmail) {
+ tfExaminerEmailText.setText(examinerEmail == null ? "" : examinerEmail);
+ }
+
+ void setCaseNotesField(String caseNotes) {
+ taNotesText.setText(caseNotes == null ? "" : caseNotes);
+ }
+
+ @Messages({"OptionalCasePropertiesPanel.caseDisplayNameLabel.text=Name:",
+ "OptionalCasePropertiesPanel.lbPointOfContactEmailLabel.text=Email:",
+ "OptionalCasePropertiesPanel.lbOrganizationNameLabel.text=Organization analysis is being done for:",
+ "OptionalCasePropertiesPanel.bnNewOrganization.text=Manage Organizations",
+ "OptionalCasePropertiesPanel.lbPointOfContactNameLabel.text=Point of Contact:",
+ "OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text=Phone:",
+ "OptionalCasePropertiesPanel.orgainizationPanel.border.title=Organization",
+ "OptionalCasePropertiesPanel.lbNotesLabel.text=Notes:",
+ "OptionalCasePropertiesPanel.examinerLabel.text=Name:",
+ "OptionalCasePropertiesPanel.lbExaminerEmailLabel.text=Email:",
+ "OptionalCasePropertiesPanel.lbExaminerPhoneLabel.text=Phone:",
+ "OptionalCasePropertiesPanel.examinerPanel.border.title=Examiner",
+ "OptionalCasePropertiesPanel.caseNumberLabel.text=Number:",
+ "OptionalCasePropertiesPanel.casePanel.border.title=Case"
+ })
+ /**
+ * 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")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ casePanel = new javax.swing.JPanel();
+ caseNumberLabel = new javax.swing.JLabel();
+ caseNumberTextField = new javax.swing.JTextField();
+ caseDisplayNameLabel = new javax.swing.JLabel();
+ caseDisplayNameTextField = new javax.swing.JTextField();
+ examinerPanel = new javax.swing.JPanel();
+ tfExaminerPhoneText = new javax.swing.JTextField();
+ lbExaminerPhoneLabel = new javax.swing.JLabel();
+ caseNotesScrollPane = new javax.swing.JScrollPane();
+ taNotesText = new javax.swing.JTextArea();
+ tfExaminerEmailText = new javax.swing.JTextField();
+ examinerTextField = new javax.swing.JTextField();
+ lbExaminerEmailLabel = new javax.swing.JLabel();
+ examinerLabel = new javax.swing.JLabel();
+ lbNotesLabel = new javax.swing.JLabel();
+ orgainizationPanel = new javax.swing.JPanel();
+ lbPointOfContactPhoneLabel = new javax.swing.JLabel();
+ comboBoxOrgName = new javax.swing.JComboBox<>();
+ lbPointOfContactNameLabel = new javax.swing.JLabel();
+ bnNewOrganization = new javax.swing.JButton();
+ lbPointOfContactEmailText = new javax.swing.JLabel();
+ lbPointOfContactNameText = new javax.swing.JLabel();
+ lbOrganizationNameLabel = new javax.swing.JLabel();
+ lbPointOfContactEmailLabel = new javax.swing.JLabel();
+ lbPointOfContactPhoneText = new javax.swing.JLabel();
+
+ casePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.casePanel.border.title"))); // NOI18N
+
+ caseNumberLabel.setFont(caseNumberLabel.getFont().deriveFont(caseNumberLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ org.openide.awt.Mnemonics.setLocalizedText(caseNumberLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.caseNumberLabel.text")); // NOI18N
+ caseNumberLabel.setMaximumSize(new java.awt.Dimension(41, 14));
+ caseNumberLabel.setMinimumSize(new java.awt.Dimension(41, 14));
+ caseNumberLabel.setPreferredSize(new java.awt.Dimension(41, 14));
+
+ caseNumberTextField.setFont(caseNumberTextField.getFont().deriveFont(caseNumberTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+
+ caseDisplayNameLabel.setFont(caseDisplayNameLabel.getFont().deriveFont(caseDisplayNameLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ org.openide.awt.Mnemonics.setLocalizedText(caseDisplayNameLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.caseDisplayNameLabel.text")); // NOI18N
+ caseDisplayNameLabel.setMaximumSize(new java.awt.Dimension(41, 14));
+ caseDisplayNameLabel.setMinimumSize(new java.awt.Dimension(41, 14));
+ caseDisplayNameLabel.setPreferredSize(new java.awt.Dimension(41, 14));
+ caseDisplayNameLabel.setVerifyInputWhenFocusTarget(false);
+
+ caseDisplayNameTextField.setFont(caseDisplayNameTextField.getFont().deriveFont(caseDisplayNameTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+
+ javax.swing.GroupLayout casePanelLayout = new javax.swing.GroupLayout(casePanel);
+ casePanel.setLayout(casePanelLayout);
+ casePanelLayout.setHorizontalGroup(
+ casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(caseDisplayNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(caseNumberLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(caseDisplayNameTextField)
+ .addComponent(caseNumberTextField))
+ .addContainerGap())
+ );
+ casePanelLayout.setVerticalGroup(
+ casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(casePanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(caseDisplayNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(caseDisplayNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(casePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(caseNumberLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(caseNumberTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6))
+ );
+
+ examinerPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.examinerPanel.border.title"))); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbExaminerPhoneLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbExaminerPhoneLabel.text")); // NOI18N
+ lbExaminerPhoneLabel.setMaximumSize(new java.awt.Dimension(41, 14));
+ lbExaminerPhoneLabel.setMinimumSize(new java.awt.Dimension(41, 14));
+ lbExaminerPhoneLabel.setPreferredSize(new java.awt.Dimension(41, 14));
+
+ caseNotesScrollPane.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ taNotesText.setColumns(20);
+ taNotesText.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
+ taNotesText.setLineWrap(true);
+ taNotesText.setRows(2);
+ taNotesText.setWrapStyleWord(true);
+ taNotesText.setBorder(null);
+ caseNotesScrollPane.setViewportView(taNotesText);
+
+ examinerTextField.setFont(examinerTextField.getFont().deriveFont(examinerTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbExaminerEmailLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbExaminerEmailLabel.text")); // NOI18N
+ lbExaminerEmailLabel.setMaximumSize(new java.awt.Dimension(41, 14));
+ lbExaminerEmailLabel.setMinimumSize(new java.awt.Dimension(41, 14));
+ lbExaminerEmailLabel.setPreferredSize(new java.awt.Dimension(41, 14));
+
+ examinerLabel.setFont(examinerLabel.getFont().deriveFont(examinerLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
+ org.openide.awt.Mnemonics.setLocalizedText(examinerLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.examinerLabel.text")); // NOI18N
+ examinerLabel.setMaximumSize(new java.awt.Dimension(41, 14));
+ examinerLabel.setMinimumSize(new java.awt.Dimension(41, 14));
+ examinerLabel.setPreferredSize(new java.awt.Dimension(41, 14));
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbNotesLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbNotesLabel.text")); // NOI18N
+ lbNotesLabel.setMaximumSize(new java.awt.Dimension(41, 14));
+ lbNotesLabel.setMinimumSize(new java.awt.Dimension(41, 14));
+ lbNotesLabel.setPreferredSize(new java.awt.Dimension(41, 14));
+
+ javax.swing.GroupLayout examinerPanelLayout = new javax.swing.GroupLayout(examinerPanel);
+ examinerPanel.setLayout(examinerPanelLayout);
+ examinerPanelLayout.setHorizontalGroup(
+ examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbNotesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbExaminerPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(10, 10, 10)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(caseNotesScrollPane)
+ .addComponent(tfExaminerPhoneText)))
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(lbExaminerEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(examinerLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(examinerTextField)
+ .addComponent(tfExaminerEmailText))))
+ .addGap(11, 11, 11))
+ );
+ examinerPanelLayout.setVerticalGroup(
+ examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(examinerPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(examinerLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(examinerTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(tfExaminerPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbExaminerPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(tfExaminerEmailText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbExaminerEmailLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(examinerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbNotesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(caseNotesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6))
+ );
+
+ orgainizationPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.orgainizationPanel.border.title"))); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactPhoneLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text")); // NOI18N
+ lbPointOfContactPhoneLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactPhoneLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactPhoneLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ comboBoxOrgName.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ comboBoxOrgNameActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactNameLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbPointOfContactNameLabel.text")); // NOI18N
+ lbPointOfContactNameLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactNameLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactNameLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnNewOrganization, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.bnNewOrganization.text")); // NOI18N
+ bnNewOrganization.setMargin(new java.awt.Insets(2, 6, 2, 6));
+ bnNewOrganization.setMaximumSize(new java.awt.Dimension(123, 23));
+ bnNewOrganization.setMinimumSize(new java.awt.Dimension(123, 23));
+ bnNewOrganization.setPreferredSize(new java.awt.Dimension(123, 23));
+ bnNewOrganization.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnNewOrganizationActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbOrganizationNameLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbOrganizationNameLabel.text")); // NOI18N
+ lbOrganizationNameLabel.setMaximumSize(new java.awt.Dimension(189, 14));
+ lbOrganizationNameLabel.setMinimumSize(new java.awt.Dimension(189, 14));
+ lbOrganizationNameLabel.setPreferredSize(new java.awt.Dimension(189, 14));
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactEmailLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbPointOfContactEmailLabel.text")); // NOI18N
+ lbPointOfContactEmailLabel.setMaximumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactEmailLabel.setMinimumSize(new java.awt.Dimension(82, 14));
+ lbPointOfContactEmailLabel.setPreferredSize(new java.awt.Dimension(82, 14));
+
+ javax.swing.GroupLayout orgainizationPanelLayout = new javax.swing.GroupLayout(orgainizationPanel);
+ orgainizationPanel.setLayout(orgainizationPanelLayout);
+ orgainizationPanelLayout.setHorizontalGroup(
+ orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(orgainizationPanelLayout.createSequentialGroup()
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(orgainizationPanelLayout.createSequentialGroup()
+ .addGap(106, 106, 106)
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(15, 15, 15)
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ .addGroup(orgainizationPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(comboBoxOrgName, 0, 161, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(bnNewOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addContainerGap())
+ );
+ orgainizationPanelLayout.setVerticalGroup(
+ orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(orgainizationPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(comboBoxOrgName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(bnNewOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(6, 6, 6))
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGap(6, 6, 6)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(casePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(examinerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(orgainizationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(6, 6, 6))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(casePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(examinerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(orgainizationPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0))
+ );
+ }// //GEN-END:initComponents
+
+ private void comboBoxOrgNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboBoxOrgNameActionPerformed
+ @SuppressWarnings("unchecked")
+ JComboBox cb = (JComboBox) evt.getSource();
+ String orgName = (String) cb.getSelectedItem();
+ if (null == orgName) {
+ return;
+ }
+ if ("".equals(orgName)) {
+ clearOrganization();
+ return;
+ }
+ for (EamOrganization org : orgs) {
+ if (org.getName().equals(orgName)) {
+ selectedOrg = org;
+ lbPointOfContactNameText.setText(selectedOrg.getPocName());
+ lbPointOfContactEmailText.setText(selectedOrg.getPocEmail());
+ lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone());
+ return;
+ }
+ }
+ }//GEN-LAST:event_comboBoxOrgNameActionPerformed
+
+ private void bnNewOrganizationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnNewOrganizationActionPerformed
+ ManageOrganizationsDialog dialog = new ManageOrganizationsDialog();
+ // update the combobox options and org data fields
+ loadOrganizationData();
+ if (dialog.isChanged()) {
+ selectedOrg = dialog.getNewOrg();
+ setCurrentlySelectedOrganization(dialog.getNewOrg().getName());
+ }
+ validate();
+ repaint();
+ }//GEN-LAST:event_bnNewOrganizationActionPerformed
+
+ void setCurrentlySelectedOrganization(String orgName) {
+ comboBoxOrgName.setSelectedItem(orgName == null ? "" : orgName);
+ }
+
+ @Messages({
+ "OptionalCasePropertiesPanel.errorDialog.emptyCaseNameMessage=No case name entered.",
+ "OptionalCasePropertiesPanel.errorDialog.invalidCaseNameMessage=Case names cannot include the following symbols: \\, /, :, *, ?, \", <, >, |"
+ })
+ void saveUpdatedCaseDetails() {
+ if (caseDisplayNameTextField.getText().trim().isEmpty()) {
+ MessageNotifyUtil.Message.error(Bundle.OptionalCasePropertiesPanel_errorDialog_emptyCaseNameMessage());
+ return;
+ }
+ if (!Case.isValidName(caseDisplayNameTextField.getText())) {
+ MessageNotifyUtil.Message.error(Bundle.OptionalCasePropertiesPanel_errorDialog_invalidCaseNameMessage());
+ return;
+ }
+ updateCaseDetails();
+ updateCorrelationCase();
+ }
+
+ private void updateCaseDetails() {
+ if (caseDisplayNameTextField.isVisible()) {
+ try {
+ Case.getCurrentCase().updateCaseDetails(new CaseDetails(
+ caseDisplayNameTextField.getText(), caseNumberTextField.getText(),
+ examinerTextField.getText(), tfExaminerPhoneText.getText(),
+ tfExaminerEmailText.getText(), taNotesText.getText()));
+ } catch (CaseActionException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ }
+
+ /**
+ * Save changed value from text fields and text areas into the EamCase
+ * object.
+ */
+ private void updateCorrelationCase() {
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ if (EamDb.isEnabled()) {
+ try {
+ EamDb dbManager = EamDb.getInstance();
+ CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ if (caseDisplayNameTextField.isVisible()) {
+ correlationCase.setDisplayName(caseDisplayNameTextField.getText());
+ }
+ correlationCase.setOrg(selectedOrg);
+ correlationCase.setCaseNumber(caseNumberTextField.getText());
+ correlationCase.setExaminerName(examinerTextField.getText());
+ correlationCase.setExaminerEmail(tfExaminerEmailText.getText());
+ correlationCase.setExaminerPhone(tfExaminerPhoneText.getText());
+ correlationCase.setNotes(taNotesText.getText());
+ dbManager.updateCase(correlationCase);
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error connecting to central repository database", ex); // NON-NLS
+ } finally {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ }
+ }
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton bnNewOrganization;
+ private javax.swing.JLabel caseDisplayNameLabel;
+ private javax.swing.JTextField caseDisplayNameTextField;
+ private javax.swing.JScrollPane caseNotesScrollPane;
+ private javax.swing.JLabel caseNumberLabel;
+ private javax.swing.JTextField caseNumberTextField;
+ private javax.swing.JPanel casePanel;
+ private javax.swing.JComboBox comboBoxOrgName;
+ private javax.swing.JLabel examinerLabel;
+ private javax.swing.JPanel examinerPanel;
+ private javax.swing.JTextField examinerTextField;
+ private javax.swing.JLabel lbExaminerEmailLabel;
+ private javax.swing.JLabel lbExaminerPhoneLabel;
+ private javax.swing.JLabel lbNotesLabel;
+ private javax.swing.JLabel lbOrganizationNameLabel;
+ private javax.swing.JLabel lbPointOfContactEmailLabel;
+ private javax.swing.JLabel lbPointOfContactEmailText;
+ private javax.swing.JLabel lbPointOfContactNameLabel;
+ private javax.swing.JLabel lbPointOfContactNameText;
+ private javax.swing.JLabel lbPointOfContactPhoneLabel;
+ private javax.swing.JLabel lbPointOfContactPhoneText;
+ private javax.swing.JPanel orgainizationPanel;
+ private javax.swing.JTextArea taNotesText;
+ private javax.swing.JTextField tfExaminerEmailText;
+ private javax.swing.JTextField tfExaminerPhoneText;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java b/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java
index 446c03b6c8..46727fc570 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/SingleUserCaseConverter.java
@@ -199,12 +199,15 @@ public class SingleUserCaseConverter {
copyImages(icd);
// Create new .aut file
- CaseMetadata newCaseMetadata = new CaseMetadata(icd.getCaseOutputFolder().toString(),
- CaseType.MULTI_USER_CASE,
- icd.getNewCaseName(),
+ CaseMetadata newCaseMetadata = new CaseMetadata(CaseType.MULTI_USER_CASE,
+ icd.getCaseOutputFolder().toString(),
icd.getNewCaseName(),
+ new CaseDetails(icd.getNewCaseName(),
oldCaseMetadata.getCaseNumber(),
- oldCaseMetadata.getExaminer());
+ oldCaseMetadata.getExaminer(),
+ oldCaseMetadata.getExaminerPhone(),
+ oldCaseMetadata.getExaminerEmail(),
+ oldCaseMetadata.getCaseNotes()));
newCaseMetadata.setCaseDatabaseName(dbName);
// Set created date. This calls writefile, no need to call it again
newCaseMetadata.setCreatedDate(oldCaseMetadata.getCreatedDate());
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/actions/Bundle.properties
deleted file mode 100755
index 6a2b388e78..0000000000
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/Bundle.properties
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Enterprise Artifacts Manager
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.
- */
-EamCaseEditDetailsDialog.lbExaminerEmailLabel.text=Email:
-EamCaseEditDetailsDialog.lbCaseNameLabel.text=Case Name:
-EamCaseEditDetailsDialog.lbExaminerNameLabel.text=Name:
-EamCaseEditDetailsDialog.bnOk.text=OK
-EamCaseEditDetailsDialog.bnClose.text=Close
-EamCaseEditDetailsDialog.bnNewOrganization.text=New Organization
-EamCaseEditDetailsDialog.lbPointOfContactPhoneLabel.text=Phone:
-EamCaseEditDetailsDialog.lbPointOfContactEmailLabel.text=Email:
-EamCaseEditDetailsDialog.lbPointOfContactNameLabel.text=Name:
-EamCaseEditDetailsDialog.lbPointOfContactGroupLabel.text=Point of Contact:
-EamCaseEditDetailsDialog.lbOrganizationNameLabel.text=Organization Name:
-EamCaseEditDetailsDialog.lbNotesLabel.text=Notes:
-EamCaseEditDetailsDialog.lbCaseUUIDLabel.text=Case UUID:
-EamCaseEditDetailsDialog.lbExaminerPhoneLabel.text=Phone:
-EamCaseEditDetailsDialog.lbCaseNumberLabel.text=Case Number:
-EamCaseEditDetailsDialog.lbCreationDateLabel.text=Creation Date:
-EamCaseEditDetailsDialog.pnCaseMetadata.title=Case Metadata
-EamCaseEditDetailsDialog.pnOrganization.title=Organization
-EamCaseEditDetailsDialog.pnExaminer.title=Examiner
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.form
deleted file mode 100755
index 0ef78a860c..0000000000
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.form
+++ /dev/null
@@ -1,456 +0,0 @@
-
-
-
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java
deleted file mode 100755
index 3e34bf9dd2..0000000000
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Central Repository
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.centralrepository.actions;
-
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Toolkit;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.logging.Level;
-import javax.swing.JComboBox;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import org.openide.util.NbBundle.Messages;
-import org.openide.windows.WindowManager;
-import org.sleuthkit.autopsy.casemodule.Case;
-import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
-import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
-import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
-import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
-import org.sleuthkit.autopsy.centralrepository.optionspanel.AddNewOrganizationDialog;
-
-/**
- * Handle editing details of cases within the central repository
- */
-public class EamCaseEditDetailsDialog extends JDialog {
-
- private final static Logger LOGGER = Logger.getLogger(EamCaseEditDetailsDialog.class.getName());
- private CorrelationCase eamCase;
- private EamDb dbManager;
- private Boolean contentChanged = false;
- private final Collection textBoxes = new ArrayList<>();
- private final Collection textAreas = new ArrayList<>();
- private final TextBoxChangedListener textBoxChangedListener = new TextBoxChangedListener();
- private EamOrganization selectedOrg = null;
- private List orgs = null;
- private boolean comboboxOrganizationActionListenerActive;
-
- /**
- * Creates new EamCaseEditDetailsDialog form
- */
- @Messages({"EamCaseEditDetailsDialog.window.title=Central Repository Case Properties"})
- public EamCaseEditDetailsDialog() {
- super((JFrame) WindowManager.getDefault().getMainWindow(),
- Bundle.EamCaseEditDetailsDialog_window_title(),
- true); // NON-NLS
-
- try {
- this.dbManager = EamDb.getInstance();
- this.eamCase = this.dbManager.getCaseByUUID(Case.getCurrentCase().getName());
- if(this.eamCase == null){
- this.eamCase = dbManager.newCase(Case.getCurrentCase());
- }
- initComponents();
- loadData();
- customizeComponents();
- display();
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error getting current case.", ex);
- }
- }
-
- private void customizeComponents() {
- setTextBoxListeners();
- setTextAreaListeners();
- }
-
- private void setTextBoxListeners() {
- // Register for notifications when the text boxes get updated.
- textBoxes.add(tfExaminerNameText);
- textBoxes.add(tfExaminerEmailText);
- textBoxes.add(tfExaminerPhoneText);
- addTextFieldDocumentListeners(textBoxes, textBoxChangedListener);
- }
-
- private void setTextAreaListeners() {
- // Register for notifications when the text areas get updated.
- textAreas.add(taNotesText);
- addTextAreaDocumentListeners(textAreas, textBoxChangedListener);
- }
-
- /**
- * Adds a change listener to a collection of text fields.
- *
- * @param textFields The text fields.
- * @param listener The change listener.
- */
- private static void addTextFieldDocumentListeners(Collection textFields, TextBoxChangedListener listener) {
- textFields.forEach((textField) -> {
- textField.getDocument().addDocumentListener(listener);
- });
- }
-
- /**
- * Adds a change listener to a collection of text areas.
- *
- * @param textAreas The text areas.
- * @param listener The change listener.
- */
- private static void addTextAreaDocumentListeners(Collection textAreas, TextBoxChangedListener listener) {
- textAreas.forEach((textArea) -> {
- textArea.getDocument().addDocumentListener(listener);
- });
- }
-
- private void display() {
- pack();
- Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
- setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
- setVisible(true);
- }
-
- /**
- * 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.
- */
- // //GEN-BEGIN:initComponents
- private void initComponents() {
-
- bnClose = new javax.swing.JButton();
- bnOk = new javax.swing.JButton();
- pnCaseMetadata = new javax.swing.JPanel();
- lbCaseNameLabel = new javax.swing.JLabel();
- lbCreationDateLabel = new javax.swing.JLabel();
- lbCaseNumberLabel = new javax.swing.JLabel();
- lbCaseUUIDLabel = new javax.swing.JLabel();
- lbCaseUUIDText = new javax.swing.JLabel();
- lbCaseNameText = new javax.swing.JLabel();
- lbCeationDateText = new javax.swing.JLabel();
- lbCaseNumberText = new javax.swing.JLabel();
- pnOrganization = new javax.swing.JPanel();
- lbOrganizationNameLabel = new javax.swing.JLabel();
- comboBoxOrgName = new javax.swing.JComboBox<>();
- lbPointOfContactGroupLabel = new javax.swing.JLabel();
- lbPointOfContactNameLabel = new javax.swing.JLabel();
- lbPointOfContactEmailLabel = new javax.swing.JLabel();
- lbPointOfContactPhoneLabel = new javax.swing.JLabel();
- lbPointOfContactNameText = new javax.swing.JLabel();
- lbPointOfContactEmailText = new javax.swing.JLabel();
- lbPointOfContactPhoneText = new javax.swing.JLabel();
- bnNewOrganization = new javax.swing.JButton();
- pnExaminer = new javax.swing.JPanel();
- lbExaminerNameLabel = new javax.swing.JLabel();
- tfExaminerNameText = new javax.swing.JTextField();
- lbExaminerEmailLabel = new javax.swing.JLabel();
- tfExaminerEmailText = new javax.swing.JTextField();
- lbExaminerPhoneLabel = new javax.swing.JLabel();
- tfExaminerPhoneText = new javax.swing.JTextField();
- lbNotesLabel = new javax.swing.JLabel();
- jScrollPane2 = new javax.swing.JScrollPane();
- taNotesText = new javax.swing.JTextArea();
-
- setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
-
- org.openide.awt.Mnemonics.setLocalizedText(bnClose, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.bnClose.text")); // NOI18N
- bnClose.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnCloseActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(bnOk, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.bnOk.text")); // NOI18N
- bnOk.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnOkActionPerformed(evt);
- }
- });
-
- pnCaseMetadata.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.pnCaseMetadata.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbCaseNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbCaseNameLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbCreationDateLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbCreationDateLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbCaseNumberLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbCaseNumberLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbCaseUUIDLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbCaseUUIDLabel.text")); // NOI18N
-
- javax.swing.GroupLayout pnCaseMetadataLayout = new javax.swing.GroupLayout(pnCaseMetadata);
- pnCaseMetadata.setLayout(pnCaseMetadataLayout);
- pnCaseMetadataLayout.setHorizontalGroup(
- pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnCaseMetadataLayout.createSequentialGroup()
- .addGap(25, 25, 25)
- .addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addComponent(lbCaseNumberLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbCreationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbCaseNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbCaseUUIDLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbCaseNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbCeationDateText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbCaseNumberText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbCaseUUIDText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addContainerGap())
- );
- pnCaseMetadataLayout.setVerticalGroup(
- pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnCaseMetadataLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(lbCaseUUIDLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbCaseUUIDText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbCaseNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbCaseNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbCreationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbCeationDateText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbCaseNumberLabel)
- .addComponent(lbCaseNumberText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(26, 26, 26))
- );
-
- pnOrganization.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.pnOrganization.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbOrganizationNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbOrganizationNameLabel.text")); // NOI18N
-
- comboBoxOrgName.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- comboBoxOrgNameActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactGroupLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbPointOfContactGroupLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbPointOfContactNameLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactEmailLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbPointOfContactEmailLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactPhoneLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbPointOfContactPhoneLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(bnNewOrganization, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.bnNewOrganization.text")); // NOI18N
- bnNewOrganization.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnNewOrganizationActionPerformed(evt);
- }
- });
-
- javax.swing.GroupLayout pnOrganizationLayout = new javax.swing.GroupLayout(pnOrganization);
- pnOrganization.setLayout(pnOrganizationLayout);
- pnOrganizationLayout.setHorizontalGroup(
- pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOrganizationLayout.createSequentialGroup()
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOrganizationLayout.createSequentialGroup()
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnOrganizationLayout.createSequentialGroup()
- .addGap(25, 25, 25)
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(lbPointOfContactGroupLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
- .addGroup(pnOrganizationLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
- .addGap(18, 18, 18)
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(comboBoxOrgName, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnOrganizationLayout.createSequentialGroup()
- .addGap(0, 0, Short.MAX_VALUE)
- .addComponent(bnNewOrganization)))
- .addContainerGap())
- );
- pnOrganizationLayout.setVerticalGroup(
- pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOrganizationLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbOrganizationNameLabel)
- .addComponent(comboBoxOrgName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(lbPointOfContactGroupLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(bnNewOrganization)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
-
- pnExaminer.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.pnExaminer.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbExaminerNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbExaminerNameLabel.text")); // NOI18N
-
- tfExaminerNameText.setEditable(false);
-
- org.openide.awt.Mnemonics.setLocalizedText(lbExaminerEmailLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbExaminerEmailLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbExaminerPhoneLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbExaminerPhoneLabel.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbNotesLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsDialog.class, "EamCaseEditDetailsDialog.lbNotesLabel.text")); // NOI18N
-
- taNotesText.setColumns(20);
- taNotesText.setRows(5);
- jScrollPane2.setViewportView(taNotesText);
-
- javax.swing.GroupLayout pnExaminerLayout = new javax.swing.GroupLayout(pnExaminer);
- pnExaminer.setLayout(pnExaminerLayout);
- pnExaminerLayout.setHorizontalGroup(
- pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnExaminerLayout.createSequentialGroup()
- .addGap(28, 28, 28)
- .addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbExaminerEmailLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbExaminerNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbExaminerPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbNotesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(25, 25, 25)
- .addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(tfExaminerEmailText)
- .addComponent(tfExaminerPhoneText)
- .addComponent(tfExaminerNameText)
- .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE))
- .addContainerGap())
- );
- pnExaminerLayout.setVerticalGroup(
- pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnExaminerLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbExaminerNameLabel)
- .addComponent(tfExaminerNameText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(tfExaminerEmailText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbExaminerEmailLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(tfExaminerPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbExaminerPhoneLabel))
- .addGap(24, 24, 24)
- .addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbNotesLabel)
- .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
-
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addGap(0, 0, Short.MAX_VALUE)
- .addComponent(bnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(bnClose))
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnCaseMetadata, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(pnOrganization, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(pnExaminer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
- .addContainerGap())
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(23, 23, 23)
- .addComponent(pnCaseMetadata, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pnOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pnExaminer, 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.BASELINE)
- .addComponent(bnOk)
- .addComponent(bnClose))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
- }// //GEN-END:initComponents
-
- private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed
- if (contentChanged) {
- updateEamCase();
- updateDb();
- }
- dispose();
- }//GEN-LAST:event_bnOkActionPerformed
-
- private void bnNewOrganizationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnNewOrganizationActionPerformed
- AddNewOrganizationDialog dialogO = new AddNewOrganizationDialog();
- // update the combobox options and org data fields
- if (dialogO.isChanged()) {
- loadOrganizationData();
- }
- }//GEN-LAST:event_bnNewOrganizationActionPerformed
-
- @SuppressWarnings({"unchecked"})
- private void comboBoxOrgNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboBoxOrgNameActionPerformed
- JComboBox cb = (JComboBox) evt.getSource();
- String orgName = (String) cb.getSelectedItem();
- if (null == orgName || false == comboboxOrganizationActionListenerActive) {
- return;
- }
-
- if ("".equals(orgName)) {
- selectedOrg = null;
- lbPointOfContactNameText.setText("");
- lbPointOfContactEmailText.setText("");
- lbPointOfContactPhoneText.setText("");
- contentChanged = true;
- return;
- }
-
- for (EamOrganization org : orgs) {
- if (org.getName().equals(orgName)) {
- selectedOrg = org;
- lbPointOfContactNameText.setText(selectedOrg.getPocName());
- lbPointOfContactEmailText.setText(selectedOrg.getPocEmail());
- lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone());
- contentChanged = true;
- return;
- }
- }
- }//GEN-LAST:event_comboBoxOrgNameActionPerformed
-
- private void bnCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCloseActionPerformed
- dispose();
- }//GEN-LAST:event_bnCloseActionPerformed
-
- private void loadCaseMetaData() {
- lbCaseUUIDText.setText(eamCase.getCaseUUID());
- lbCaseNameText.setText(eamCase.getDisplayName());
- lbCeationDateText.setText(eamCase.getCreationDate());
- lbCaseNumberText.setText(eamCase.getCaseNumber());
- }
-
- private void loadExaminerData() {
- tfExaminerNameText.setText(eamCase.getExaminerName());
- tfExaminerEmailText.setText(eamCase.getExaminerEmail());
- tfExaminerPhoneText.setText(eamCase.getExaminerPhone());
- taNotesText.setText(eamCase.getNotes());
- }
-
- private void loadOrganizationData() {
- comboboxOrganizationActionListenerActive = false; // don't fire action listener while loading combobox content
- comboBoxOrgName.removeAllItems();
- try {
- orgs = dbManager.getOrganizations();
- comboBoxOrgName.addItem(""); // for when a case has a null Org
- orgs.forEach((org) -> {
- comboBoxOrgName.addItem(org.getName());
- });
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Failure populating combobox with organizations.", ex);
- }
- comboboxOrganizationActionListenerActive = true;
-
- if (!orgs.isEmpty() && null != eamCase.getOrg()) {
- selectedOrg = eamCase.getOrg();
- comboBoxOrgName.setSelectedItem(selectedOrg.getName());
- lbPointOfContactNameText.setText(selectedOrg.getPocName());
- lbPointOfContactEmailText.setText(selectedOrg.getPocEmail());
- lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone());
- } else {
- comboBoxOrgName.setSelectedItem("");
- lbPointOfContactNameText.setText("");
- lbPointOfContactEmailText.setText("");
- lbPointOfContactPhoneText.setText("");
- }
- }
-
- private void loadData() {
- loadCaseMetaData();
- loadExaminerData();
- loadOrganizationData();
- }
-
- /**
- * Save changed value from text fields and text areas into the EamCase
- * object.
- */
- private void updateEamCase() {
- eamCase.setOrg(selectedOrg);
- eamCase.setExaminerName(tfExaminerNameText.getText());
- eamCase.setExaminerEmail(tfExaminerEmailText.getText());
- eamCase.setExaminerPhone(tfExaminerPhoneText.getText());
- eamCase.setNotes(taNotesText.getText());
- }
-
- private void updateDb() {
- setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
- if (!EamDb.isEnabled()) {
- LOGGER.log(Level.SEVERE, "Central repository database not enabled"); // NON-NLS
- return;
- }
-
- try {
- dbManager.updateCase(eamCase);
- } catch (IllegalArgumentException | EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error connecting to central repository database", ex); // NON-NLS
- } finally {
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- }
- }
-
- /**
- * Used to listen for changes in text areas/boxes. Let the panel know text
- * content has changed.
- */
- private class TextBoxChangedListener implements DocumentListener {
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- setChanged();
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- setChanged();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- setChanged();
- }
-
- private void setChanged() {
- contentChanged = true;
- }
- }
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton bnClose;
- private javax.swing.JButton bnNewOrganization;
- private javax.swing.JButton bnOk;
- private javax.swing.JComboBox comboBoxOrgName;
- private javax.swing.JScrollPane jScrollPane2;
- private javax.swing.JLabel lbCaseNameLabel;
- private javax.swing.JLabel lbCaseNameText;
- private javax.swing.JLabel lbCaseNumberLabel;
- private javax.swing.JLabel lbCaseNumberText;
- private javax.swing.JLabel lbCaseUUIDLabel;
- private javax.swing.JLabel lbCaseUUIDText;
- private javax.swing.JLabel lbCeationDateText;
- private javax.swing.JLabel lbCreationDateLabel;
- private javax.swing.JLabel lbExaminerEmailLabel;
- private javax.swing.JLabel lbExaminerNameLabel;
- private javax.swing.JLabel lbExaminerPhoneLabel;
- private javax.swing.JLabel lbNotesLabel;
- private javax.swing.JLabel lbOrganizationNameLabel;
- private javax.swing.JLabel lbPointOfContactEmailLabel;
- private javax.swing.JLabel lbPointOfContactEmailText;
- private javax.swing.JLabel lbPointOfContactGroupLabel;
- private javax.swing.JLabel lbPointOfContactNameLabel;
- private javax.swing.JLabel lbPointOfContactNameText;
- private javax.swing.JLabel lbPointOfContactPhoneLabel;
- private javax.swing.JLabel lbPointOfContactPhoneText;
- private javax.swing.JPanel pnCaseMetadata;
- private javax.swing.JPanel pnExaminer;
- private javax.swing.JPanel pnOrganization;
- private javax.swing.JTextArea taNotesText;
- private javax.swing.JTextField tfExaminerEmailText;
- private javax.swing.JTextField tfExaminerNameText;
- private javax.swing.JTextField tfExaminerPhoneText;
- // End of variables declaration//GEN-END:variables
-}
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamEditCaseInfoAction.java b/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamEditCaseInfoAction.java
deleted file mode 100755
index 4123e382ff..0000000000
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamEditCaseInfoAction.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Central Repository
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.centralrepository.actions;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import javax.swing.Action;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.awt.ActionRegistration;
-import org.openide.util.HelpCtx;
-import org.openide.util.NbBundle.Messages;
-import org.openide.util.actions.CallableSystemAction;
-import org.sleuthkit.autopsy.casemodule.Case;
-import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
-
-/**
- * Action to update case details in Central Repository database
- */
-@ActionID(
- category = "Case",
- id = "org.sleuthkit.centralrepository.actions.CentralRepositoryCaseProperties"
-)
-@ActionRegistration(
- displayName = "#CTL_CentralRepositoryCaseProperties",
- lazy = false
-)
-@ActionReference(path = "Menu/Case", position = 650, separatorAfter = 824)
-@Messages("CTL_CentralRepositoryCaseProperties=Central Repository Case Properties...")
-public final class EamEditCaseInfoAction extends CallableSystemAction implements ActionListener {
-
- EamEditCaseInfoAction() {
- putValue(Action.NAME, Bundle.CTL_CentralRepositoryCaseProperties()); // put the action Name
- this.setEnabled(true);
- }
-
- @Override
- public boolean isEnabled() {
- return EamDb.isEnabled() && Case.isCaseOpen();
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- performAction();
- }
-
- @Override
- public void performAction() {
-
- EamCaseEditDetailsDialog caseInformationDialog = new EamCaseEditDetailsDialog();
- }
-
- @Override
- public String getName() {
- return Bundle.CTL_CentralRepositoryCaseProperties();
- }
-
- @Override
- public HelpCtx getHelpCtx() {
- return HelpCtx.DEFAULT_HELP;
- }
-}
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java
index 689d5a22fb..b16589c3dd 100644
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java
@@ -28,11 +28,14 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
import java.sql.Types;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
@@ -272,9 +275,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
autopsyCase.getCreatedDate(),
autopsyCase.getNumber(),
autopsyCase.getExaminer(),
- null,
- null,
- null);
+ autopsyCase.getExaminerEmail(),
+ autopsyCase.getExaminerPhone(),
+ autopsyCase.getCaseNotes());
newCase(curCeCase);
return curCeCase;
}
@@ -451,7 +454,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
/**
* Retrieves Data Source details based on data source device ID
*
- * @param correlationCase the current CorrelationCase used for ensuring uniqueness of DataSource
+ * @param correlationCase the current CorrelationCase used for ensuring
+ * uniqueness of DataSource
* @param dataSourceDeviceId the data source device ID number
*
* @return The data source
@@ -572,10 +576,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
* Retrieves eamArtifact instances from the database that are associated
* with the eamArtifactType and eamArtifactValue of the given eamArtifact.
*
- * @param aType The type of the artifact
- * @param value The correlation value
+ * @param aType The type of the artifact
+ * @param value The correlation value
*
* @return List of artifact instances for a given type/value
+ *
* @throws EamDbException
*/
@Override
@@ -675,8 +680,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
* Retrieves number of artifact instances in the database that are
* associated with the ArtifactType and artifactValue of the given artifact.
*
- * @param aType The type of the artifact
- * @param value The correlation value
+ * @param aType The type of the artifact
+ * @param value The correlation value
*
* @return Number of artifact instances having ArtifactType and
* ArtifactValue.
@@ -725,8 +730,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
* database that are associated with the artifactType and artifactValue of
* the given artifact.
*
- * @param aType The type of the artifact
- * @param value The correlation value
+ * @param aType The type of the artifact
+ * @param value The correlation value
*
* @return Number of unique tuples
*/
@@ -1019,7 +1024,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
* given status.
*
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
- * @param knownStatus The status to change the artifact to
+ * @param knownStatus The status to change the artifact to
*/
@Override
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
@@ -1290,29 +1295,38 @@ public abstract class AbstractSqlEamDb implements EamDb {
/**
* Add a new organization
*
+ * @return the Organization ID of the newly created organization.
+ *
* @param eamOrg The organization to add
*
* @throws EamDbException
*/
@Override
- public void newOrganization(EamOrganization eamOrg) throws EamDbException {
+ public long newOrganization(EamOrganization eamOrg) throws EamDbException {
Connection conn = connect();
-
+ ResultSet generatedKeys = null;
PreparedStatement preparedStatement = null;
String sql = "INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?)";
try {
- preparedStatement = conn.prepareStatement(sql);
+ preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, eamOrg.getName());
preparedStatement.setString(2, eamOrg.getPocName());
preparedStatement.setString(3, eamOrg.getPocEmail());
preparedStatement.setString(4, eamOrg.getPocPhone());
preparedStatement.executeUpdate();
+ generatedKeys = preparedStatement.getGeneratedKeys();
+ if (generatedKeys.next()) {
+ return generatedKeys.getLong(1);
+ } else {
+ throw new SQLException("Creating user failed, no ID obtained.");
+ }
} catch (SQLException ex) {
throw new EamDbException("Error inserting new organization.", ex); // NON-NLS
} finally {
EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(generatedKeys);
EamDbUtil.closeConnection(conn);
}
}
@@ -1383,6 +1397,68 @@ public abstract class AbstractSqlEamDb implements EamDb {
}
}
+ /**
+ * Update an existing organization.
+ *
+ * @param updatedOrganization the values the Organization with the same ID
+ * will be updated to in the database.
+ *
+ * @throws EamDbException
+ */
+ @Override
+ public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
+ Connection conn = connect();
+ PreparedStatement preparedStatement = null;
+ String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
+ try {
+ preparedStatement = conn.prepareStatement(sql);
+ preparedStatement.setString(1, updatedOrganization.getName());
+ preparedStatement.setString(2, updatedOrganization.getPocName());
+ preparedStatement.setString(3, updatedOrganization.getPocEmail());
+ preparedStatement.setString(4, updatedOrganization.getPocPhone());
+ preparedStatement.setInt(5, updatedOrganization.getOrgID());
+ preparedStatement.executeUpdate();
+ } catch (SQLException ex) {
+ throw new EamDbException("Error updating organization.", ex); // NON-NLS
+ } finally {
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
+ }
+ }
+
+ @Messages({"AbstractSqlEamDb.deleteOrganization.inUseException.message=Can not delete organization "
+ + "which is currently in use by a case or reference set in the central repository.",
+ "AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
+ @Override
+ public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
+ Connection conn = connect();
+ PreparedStatement checkIfUsedStatement = null;
+ ResultSet resultSet = null;
+ String checkIfUsedSql = "SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
+ PreparedStatement deleteOrgStatement = null;
+ String deleteOrgSql = "DELETE FROM organizations WHERE id=?";
+ try {
+ checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
+ checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
+ checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
+ resultSet = checkIfUsedStatement.executeQuery();
+ resultSet.next();
+ if (resultSet.getLong(1) > 0) {
+ throw new EamDbException(Bundle.AbstractSqlEamDb_deleteOrganization_inUseException_message());
+ }
+ deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
+ deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
+ deleteOrgStatement.executeUpdate();
+ } catch (SQLException ex) {
+ throw new EamDbException(Bundle.AbstractSqlEamDb_deleteOrganization_errorDeleting_message(), ex); // NON-NLS
+ } finally {
+ EamDbUtil.closePreparedStatement(checkIfUsedStatement);
+ EamDbUtil.closePreparedStatement(deleteOrgStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
+ }
+ }
+
/**
* Add a new Global Set
*
@@ -1851,7 +1927,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
resultSet.getInt("id"),
resultSet.getInt("case_id"),
resultSet.getString("device_id"),
- resultSet.getString("name")
+ resultSet.getString("name")
);
return eamDataSource;
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java
index c3f3c09730..70ab104fa4 100644
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java
@@ -314,7 +314,7 @@ public interface EamDb {
* exists, it is updated. If eamArtifact does not exist nothing happens
*
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
- * @param knownStatus The status to change the artifact to
+ * @param knownStatus The status to change the artifact to
*/
void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException;
@@ -368,9 +368,11 @@ public interface EamDb {
*
* @param eamOrg The organization to add
*
+ * @return the Organization ID of the newly created organization.
+ *
* @throws EamDbException
*/
- void newOrganization(EamOrganization eamOrg) throws EamDbException;
+ long newOrganization(EamOrganization eamOrg) throws EamDbException;
/**
* Get all organizations
@@ -392,6 +394,26 @@ public interface EamDb {
*/
EamOrganization getOrganizationByID(int orgID) throws EamDbException;
+ /**
+ * Update an existing organization.
+ *
+ * @param updatedOrganization the values the Organization with the same ID
+ * will be updated to in the database.
+ *
+ * @throws EamDbException
+ */
+ void updateOrganization(EamOrganization updatedOrganization) throws EamDbException;
+
+ /**
+ * Delete an organization if it is not being used by any case.
+ *
+ * @param organizationToDelete the organization to be deleted
+ *
+ * @throws EamDbException
+ */
+ void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException;
+
+
/**
* Add a new Global Set
*
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java
index a048d95f9c..5890dd2a67 100644
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java
@@ -656,15 +656,17 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
* Add a new organization
*
+ * @return the Organization ID of the newly created organization.
+ *
* @param eamOrg The organization to add
*
* @throws EamDbException
*/
@Override
- public void newOrganization(EamOrganization eamOrg) throws EamDbException {
+ public long newOrganization(EamOrganization eamOrg) throws EamDbException {
try{
acquireExclusiveLock();
- super.newOrganization(eamOrg);
+ return super.newOrganization(eamOrg);
} finally {
releaseExclusiveLock();
}
@@ -704,8 +706,27 @@ public class SqliteEamDb extends AbstractSqlEamDb {
} finally {
releaseSharedLock();
}
- }
+ }
+ @Override
+ public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
+ try{
+ acquireExclusiveLock();
+ super.updateOrganization(updatedOrganization);
+ } finally {
+ releaseExclusiveLock();
+ }
+ }
+
+ @Override
+ public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
+ try{
+ acquireExclusiveLock();
+ super.deleteOrganization(organizationToDelete);
+ } finally {
+ releaseExclusiveLock();
+ }
+ }
/**
* Add a new Global Set
*
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java
index 7f4f97d08a..a68b0cba8d 100644
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java
@@ -18,9 +18,12 @@
*/
package org.sleuthkit.autopsy.centralrepository.eventlisteners;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.util.NbBundle.Messages;
@@ -39,6 +42,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
+import org.sleuthkit.autopsy.coreutils.ThreadUtils;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
@@ -53,9 +57,19 @@ import org.sleuthkit.datamodel.TskDataException;
* accordingly
*/
@Messages({"caseeventlistener.evidencetag=Evidence"})
-public class CaseEventListener implements PropertyChangeListener {
+final class CaseEventListener implements PropertyChangeListener {
private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName());
+ private final ExecutorService jobProcessingExecutor;
+ private static final String CASE_EVENT_THREAD_NAME = "Case-Event-Listener-%d";
+
+ CaseEventListener() {
+ jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build());
+ }
+
+ void shutdown() {
+ ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
+ }
@Override
public void propertyChange(PropertyChangeEvent evt) {
@@ -69,222 +83,290 @@ public class CaseEventListener implements PropertyChangeListener {
switch (Case.Events.valueOf(evt.getPropertyName())) {
case CONTENT_TAG_ADDED:
case CONTENT_TAG_DELETED: {
- if (!EamDb.isEnabled()) {
+ jobProcessingExecutor.submit(new ContentTagTask(dbManager, evt));
+ }
+ break;
+
+ case BLACKBOARD_ARTIFACT_TAG_DELETED:
+ case BLACKBOARD_ARTIFACT_TAG_ADDED: {
+ jobProcessingExecutor.submit(new BlackboardTagTask(dbManager, evt));
+ }
+ break;
+
+ case DATA_SOURCE_ADDED: {
+ jobProcessingExecutor.submit(new DataSourceAddedTask(dbManager, evt));
+ }
+ break;
+
+ case CURRENT_CASE: {
+ jobProcessingExecutor.submit(new CurrentCaseTask(dbManager, evt));
+ }
+ break;
+ }
+ }
+
+ private final class ContentTagTask implements Runnable {
+
+ private final EamDb dbManager;
+ private final PropertyChangeEvent event;
+
+ private ContentTagTask(EamDb db, PropertyChangeEvent evt) {
+ dbManager = db;
+ event = evt;
+ }
+
+ @Override
+ public void run() {
+ if (!EamDb.isEnabled()) {
+ return;
+ }
+
+ AbstractFile af;
+ TskData.FileKnown knownStatus;
+ String comment;
+ if (Case.Events.valueOf(event.getPropertyName()) == Case.Events.CONTENT_TAG_ADDED) {
+ // For added tags, we want to change the known status to BAD if the
+ // tag that was just added is in the list of central repo tags.
+ final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) event;
+ final ContentTag tagAdded = tagAddedEvent.getAddedTag();
+
+ if (dbManager.getBadTags().contains(tagAdded.getName().getDisplayName())) {
+ if (tagAdded.getContent() instanceof AbstractFile) {
+ af = (AbstractFile) tagAdded.getContent();
+ knownStatus = TskData.FileKnown.BAD;
+ comment = tagAdded.getComment();
+ } else {
+ LOGGER.log(Level.WARNING, "Error updating non-file object");
+ return;
+ }
+ } else {
+ // The added tag isn't flagged as bad in central repo, so do nothing
+ return;
+ }
+ } else { // CONTENT_TAG_DELETED
+ // For deleted tags, we want to set the file status to UNKNOWN if:
+ // - The tag that was just removed is notable in central repo
+ // - There are no remaining tags that are notable
+ final ContentTagDeletedEvent tagDeletedEvent = (ContentTagDeletedEvent) event;
+ long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
+
+ String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
+ if (!dbManager.getBadTags().contains(tagName)) {
+ // If the tag that got removed isn't on the list of central repo tags, do nothing
return;
}
- AbstractFile af;
- TskData.FileKnown knownStatus;
- String comment;
- if (Case.Events.valueOf(evt.getPropertyName()) == Case.Events.CONTENT_TAG_ADDED) {
- // For added tags, we want to change the known status to BAD if the
- // tag that was just added is in the list of central repo tags.
- final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) evt;
- final ContentTag tagAdded = tagAddedEvent.getAddedTag();
+ try {
+ // Get the remaining tags on the content object
+ Content content = Case.getCurrentCase().getSleuthkitCase().getContentById(contentID);
+ TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
+ List tags = tagsManager.getContentTagsByContent(content);
- if (dbManager.getBadTags().contains(tagAdded.getName().getDisplayName())) {
- if (tagAdded.getContent() instanceof AbstractFile) {
- af = (AbstractFile) tagAdded.getContent();
- knownStatus = TskData.FileKnown.BAD;
- comment = tagAdded.getComment();
+ if (tags.stream()
+ .map(tag -> tag.getName().getDisplayName())
+ .filter(dbManager.getBadTags()::contains)
+ .collect(Collectors.toList())
+ .isEmpty()) {
+
+ // There are no more bad tags on the object
+ if (content instanceof AbstractFile) {
+ af = (AbstractFile) content;
+ knownStatus = TskData.FileKnown.UNKNOWN;
+ comment = "";
} else {
LOGGER.log(Level.WARNING, "Error updating non-file object");
return;
}
} else {
- // The added tag isn't flagged as bad in central repo, so do nothing
+ // There's still at least one bad tag, so leave the known status as is
return;
}
- } else { // CONTENT_TAG_DELETED
- // For deleted tags, we want to set the file status to UNKNOWN if:
- // - The tag that was just removed is notable in central repo
- // - There are no remaining tags that are notable
- final ContentTagDeletedEvent tagDeletedEvent = (ContentTagDeletedEvent) evt;
- long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
-
- String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
- if (!dbManager.getBadTags().contains(tagName)) {
- // If the tag that got removed isn't on the list of central repo tags, do nothing
- return;
- }
-
- try {
- // Get the remaining tags on the content object
- Content content = Case.getCurrentCase().getSleuthkitCase().getContentById(contentID);
- TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
- List tags = tagsManager.getContentTagsByContent(content);
-
- if (tags.stream()
- .map(tag -> tag.getName().getDisplayName())
- .filter(dbManager.getBadTags()::contains)
- .collect(Collectors.toList())
- .isEmpty()) {
-
- // There are no more bad tags on the object
- if (content instanceof AbstractFile) {
- af = (AbstractFile) content;
- knownStatus = TskData.FileKnown.UNKNOWN;
- comment = "";
- } else {
- LOGGER.log(Level.WARNING, "Error updating non-file object");
- return;
- }
- } else {
- // There's still at least one bad tag, so leave the known status as is
- return;
- }
- } catch (TskCoreException ex) {
- LOGGER.log(Level.SEVERE, "Failed to find content", ex);
- return;
- }
- }
-
- final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(af,
- knownStatus, comment);
-
- if (eamArtifact != null) {
- // send update to Central Repository db
- Runnable r = new KnownStatusChangeRunner(eamArtifact, knownStatus);
- // TODO: send r into a thread pool instead
- Thread t = new Thread(r);
- t.start();
- }
- } // CONTENT_TAG_ADDED, CONTENT_TAG_DELETED
- break;
-
- case BLACKBOARD_ARTIFACT_TAG_DELETED:
- case BLACKBOARD_ARTIFACT_TAG_ADDED: {
- if (!EamDb.isEnabled()) {
+ } catch (TskCoreException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to find content", ex);
return;
}
+ }
- Content content;
- BlackboardArtifact bbArtifact;
- TskData.FileKnown knownStatus;
- String comment;
- if (Case.Events.valueOf(evt.getPropertyName()) == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED) {
- // For added tags, we want to change the known status to BAD if the
- // tag that was just added is in the list of central repo tags.
- final BlackBoardArtifactTagAddedEvent tagAddedEvent = (BlackBoardArtifactTagAddedEvent) evt;
- final BlackboardArtifactTag tagAdded = tagAddedEvent.getAddedTag();
+ final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(af,
+ knownStatus, comment);
- if (dbManager.getBadTags().contains(tagAdded.getName().getDisplayName())) {
- content = tagAdded.getContent();
- bbArtifact = tagAdded.getArtifact();
- knownStatus = TskData.FileKnown.BAD;
- comment = tagAdded.getComment();
- } else {
- // The added tag isn't flagged as bad in central repo, so do nothing
- return;
- }
- } else { //BLACKBOARD_ARTIFACT_TAG_DELETED
- // For deleted tags, we want to set the file status to UNKNOWN if:
- // - The tag that was just removed is notable in central repo
- // - There are no remaining tags that are notable
- final BlackBoardArtifactTagDeletedEvent tagDeletedEvent = (BlackBoardArtifactTagDeletedEvent) evt;
- long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
- long artifactID = tagDeletedEvent.getDeletedTagInfo().getArtifactID();
-
- String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
- if (!dbManager.getBadTags().contains(tagName)) {
- // If the tag that got removed isn't on the list of central repo tags, do nothing
- return;
- }
-
- try {
- // Get the remaining tags on the artifact
- content = Case.getCurrentCase().getSleuthkitCase().getContentById(contentID);
- bbArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(artifactID);
- TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
- List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
-
- if (tags.stream()
- .map(tag -> tag.getName().getDisplayName())
- .filter(dbManager.getBadTags()::contains)
- .collect(Collectors.toList())
- .isEmpty()) {
-
- // There are no more bad tags on the object
- knownStatus = TskData.FileKnown.UNKNOWN;
- comment = "";
-
- } else {
- // There's still at least one bad tag, so leave the known status as is
- return;
- }
- } catch (TskCoreException ex) {
- LOGGER.log(Level.SEVERE, "Failed to find content", ex);
- return;
- }
+ if (eamArtifact != null) {
+ // send update to Central Repository db
+ try {
+ dbManager.setArtifactInstanceKnownStatus(eamArtifact, knownStatus);
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
}
+ }
+ } // CONTENT_TAG_ADDED, CONTENT_TAG_DELETED
+ }
- if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) {
+ private final class BlackboardTagTask implements Runnable {
+
+ private final EamDb dbManager;
+ private final PropertyChangeEvent event;
+
+ private BlackboardTagTask(EamDb db, PropertyChangeEvent evt) {
+ dbManager = db;
+ event = evt;
+ }
+
+ @Override
+ public void run() {
+ if (!EamDb.isEnabled()) {
+ return;
+ }
+
+ Content content;
+ BlackboardArtifact bbArtifact;
+ TskData.FileKnown knownStatus;
+ String comment;
+ if (Case.Events.valueOf(event.getPropertyName()) == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED) {
+ // For added tags, we want to change the known status to BAD if the
+ // tag that was just added is in the list of central repo tags.
+ final BlackBoardArtifactTagAddedEvent tagAddedEvent = (BlackBoardArtifactTagAddedEvent) event;
+ final BlackboardArtifactTag tagAdded = tagAddedEvent.getAddedTag();
+
+ if (dbManager.getBadTags().contains(tagAdded.getName().getDisplayName())) {
+ content = tagAdded.getContent();
+ bbArtifact = tagAdded.getArtifact();
+ knownStatus = TskData.FileKnown.BAD;
+ comment = tagAdded.getComment();
+ } else {
+ // The added tag isn't flagged as bad in central repo, so do nothing
return;
}
+ } else { //BLACKBOARD_ARTIFACT_TAG_DELETED
+ // For deleted tags, we want to set the file status to UNKNOWN if:
+ // - The tag that was just removed is notable in central repo
+ // - There are no remaining tags that are notable
+ final BlackBoardArtifactTagDeletedEvent tagDeletedEvent = (BlackBoardArtifactTagDeletedEvent) event;
+ long contentID = tagDeletedEvent.getDeletedTagInfo().getContentID();
+ long artifactID = tagDeletedEvent.getDeletedTagInfo().getArtifactID();
- List convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
- for (CorrelationAttribute eamArtifact : convertedArtifacts) {
- eamArtifact.getInstances().get(0).setComment(comment);
- Runnable r = new KnownStatusChangeRunner(eamArtifact, knownStatus);
- // TODO: send r into a thread pool instead
- Thread t = new Thread(r);
- t.start();
+ String tagName = tagDeletedEvent.getDeletedTagInfo().getName().getDisplayName();
+ if (!dbManager.getBadTags().contains(tagName)) {
+ // If the tag that got removed isn't on the list of central repo tags, do nothing
+ return;
}
- } // BLACKBOARD_ARTIFACT_TAG_ADDED, BLACKBOARD_ARTIFACT_TAG_DELETED
- break;
-
- case DATA_SOURCE_ADDED: {
- if (!EamDb.isEnabled()) {
- break;
- }
-
- final DataSourceAddedEvent dataSourceAddedEvent = (DataSourceAddedEvent) evt;
- Content newDataSource = dataSourceAddedEvent.getDataSource();
-
try {
- String deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId();
- CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
- if (null == correlationCase) {
- dbManager.newCase(Case.getCurrentCase());
- correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ // Get the remaining tags on the artifact
+ content = Case.getCurrentCase().getSleuthkitCase().getContentById(contentID);
+ bbArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(artifactID);
+ TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
+ List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
+
+ if (tags.stream()
+ .map(tag -> tag.getName().getDisplayName())
+ .filter(dbManager.getBadTags()::contains)
+ .collect(Collectors.toList())
+ .isEmpty()) {
+
+ // There are no more bad tags on the object
+ knownStatus = TskData.FileKnown.UNKNOWN;
+ comment = "";
+
+ } else {
+ // There's still at least one bad tag, so leave the known status as is
+ return;
}
- if (null == dbManager.getDataSourceDetails(correlationCase, deviceId)) {
- dbManager.newDataSource(CorrelationDataSource.fromTSKDataSource(correlationCase, newDataSource));
- }
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
- } catch (TskCoreException | TskDataException ex) {
- LOGGER.log(Level.SEVERE, "Error getting data source from DATA_SOURCE_ADDED event content.", ex); //NON-NLS
+ } catch (TskCoreException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to find content", ex);
+ return;
}
- } // DATA_SOURCE_ADDED
- break;
+ }
- case CURRENT_CASE: {
- /*
- * A case has been opened if evt.getOldValue() is null and
- * evt.getNewValue() is a valid Case.
- */
- if ((null == evt.getOldValue()) && (evt.getNewValue() instanceof Case)) {
- Case curCase = (Case) evt.getNewValue();
- IngestEventsListener.resetCeModuleInstanceCount();
- try {
- // only add default evidence tag if case is open and it doesn't already exist in the tags list.
- if (Case.isCaseOpen()
- && Case.getCurrentCase().getServices().getTagsManager().getAllTagNames().stream()
- .map(tag -> tag.getDisplayName())
- .filter(tagName -> Bundle.caseeventlistener_evidencetag().equals(tagName))
- .collect(Collectors.toList())
- .isEmpty()) {
- curCase.getServices().getTagsManager().addTagName(Bundle.caseeventlistener_evidencetag());
- }
- } catch (TagsManager.TagNameAlreadyExistsException ex) {
- LOGGER.info("Evidence tag already exists"); // NON-NLS
- } catch (TskCoreException ex) {
- LOGGER.log(Level.SEVERE, "Error adding tag.", ex); // NON-NLS
+ if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) {
+ return;
+ }
+
+ List convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
+ for (CorrelationAttribute eamArtifact : convertedArtifacts) {
+ eamArtifact.getInstances().get(0).setComment(comment);
+ try {
+ dbManager.setArtifactInstanceKnownStatus(eamArtifact, knownStatus);
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
+ }
+ }
+ } // BLACKBOARD_ARTIFACT_TAG_ADDED, BLACKBOARD_ARTIFACT_TAG_DELETED
+
+ }
+
+ private final class DataSourceAddedTask implements Runnable {
+
+ private final EamDb dbManager;
+ private final PropertyChangeEvent event;
+
+ private DataSourceAddedTask(EamDb db, PropertyChangeEvent evt) {
+ dbManager = db;
+ event = evt;
+ }
+
+ @Override
+ public void run() {
+ if (!EamDb.isEnabled()) {
+ return;
+ }
+
+ final DataSourceAddedEvent dataSourceAddedEvent = (DataSourceAddedEvent) event;
+ Content newDataSource = dataSourceAddedEvent.getDataSource();
+
+ try {
+ String deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId();
+ CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ if (null == correlationCase) {
+ dbManager.newCase(Case.getCurrentCase());
+ correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
+ }
+ if (null == dbManager.getDataSourceDetails(correlationCase, deviceId)) {
+ dbManager.newDataSource(CorrelationDataSource.fromTSKDataSource(correlationCase, newDataSource));
+ }
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
+ } catch (TskCoreException | TskDataException ex) {
+ LOGGER.log(Level.SEVERE, "Error getting data source from DATA_SOURCE_ADDED event content.", ex); //NON-NLS
+ }
+ } // DATA_SOURCE_ADDED
+ }
+
+ private final class CurrentCaseTask implements Runnable {
+
+ private final EamDb dbManager;
+ private final PropertyChangeEvent event;
+
+ private CurrentCaseTask(EamDb db, PropertyChangeEvent evt) {
+ dbManager = db;
+ event = evt;
+ }
+
+ @Override
+ public void run() {
+ /*
+ * A case has been opened if evt.getOldValue() is null and
+ * evt.getNewValue() is a valid Case.
+ */
+ if ((null == event.getOldValue()) && (event.getNewValue() instanceof Case)) {
+ Case curCase = (Case) event.getNewValue();
+ IngestEventsListener.resetCeModuleInstanceCount();
+ try {
+ // only add default evidence tag if case is open and it doesn't already exist in the tags list.
+ if (Case.isCaseOpen()
+ && Case.getCurrentCase().getServices().getTagsManager().getAllTagNames().stream()
+ .map(tag -> tag.getDisplayName())
+ .filter(tagName -> Bundle.caseeventlistener_evidencetag().equals(tagName))
+ .collect(Collectors.toList())
+ .isEmpty()) {
+ curCase.getServices().getTagsManager().addTagName(Bundle.caseeventlistener_evidencetag());
}
+ } catch (TagsManager.TagNameAlreadyExistsException ex) {
+ LOGGER.info("Evidence tag already exists"); // NON-NLS
+ } catch (TskCoreException ex) {
+ LOGGER.log(Level.SEVERE, "Error adding tag.", ex); // NON-NLS
+ }
- CorrelationCase curCeCase = new CorrelationCase(
+ CorrelationCase curCeCase = new CorrelationCase(
-1,
curCase.getName(), // unique case ID
EamOrganization.getDefault(),
@@ -292,52 +374,26 @@ public class CaseEventListener implements PropertyChangeListener {
curCase.getCreatedDate(),
curCase.getNumber(),
curCase.getExaminer(),
- null,
- null,
- null);
+ curCase.getExaminerEmail(),
+ curCase.getExaminerPhone(),
+ curCase.getCaseNotes());
if (!EamDb.isEnabled()) {
- break;
+ return;
}
- try {
- // NOTE: Cannot determine if the opened case is a new case or a reopened case,
- // so check for existing name in DB and insert if missing.
- CorrelationCase existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID());
+ try {
+ // NOTE: Cannot determine if the opened case is a new case or a reopened case,
+ // so check for existing name in DB and insert if missing.
+ CorrelationCase existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID());
- if (null == existingCase) {
- dbManager.newCase(curCeCase);
- }
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
+ if (null == existingCase) {
+ dbManager.newCase(curCeCase);
}
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
}
- } // CURRENT_CASE
- break;
-
- case NAME: {
- // The display name of the case has been changed
-
- if (!EamDb.isEnabled()) {
- break;
- }
-
- if (evt.getNewValue() instanceof String) {
- String newName = (String) evt.getNewValue();
- try {
- // See if the case is in the database. If it is, update the display name.
- CorrelationCase existingCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
-
- if (null != existingCase) {
- existingCase.setDisplayName(newName);
- dbManager.updateCase(existingCase);
- }
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
- }
- }
- } // NAME
- break;
- }
+ }
+ } // CURRENT_CASE
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java
index 496dbe2f33..02d64904a4 100644
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java
@@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.centralrepository.eventlisteners;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import static java.lang.Boolean.FALSE;
@@ -25,6 +26,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.util.NbBundle;
@@ -42,6 +45,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
+import org.sleuthkit.autopsy.coreutils.ThreadUtils;
/**
* Listen for ingest events and update entries in the Central Repository
@@ -53,9 +57,19 @@ public class IngestEventsListener {
final Collection recentlyAddedCeArtifacts = new LinkedHashSet<>();
private static int ceModuleInstanceCount = 0;
+ private final ExecutorService jobProcessingExecutor;
+ private static final String INGEST_EVENT_THREAD_NAME = "Ingest-Event-Listener-%d";
private final PropertyChangeListener pcl1 = new IngestModuleEventListener();
private final PropertyChangeListener pcl2 = new IngestJobEventListener();
+ IngestEventsListener() {
+ jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(INGEST_EVENT_THREAD_NAME).build());
+ }
+
+ void shutdown() {
+ ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
+ }
+
/*
* Add all of our Ingest Event Listeners to the IngestManager Instance.
*/
@@ -86,7 +100,7 @@ public class IngestEventsListener {
* Engine.
*/
public synchronized static void decrementCorrelationEngineModuleCount() {
- if (getCeModuleInstanceCount()>0) { //prevent it ingestJobCounter from going negative
+ if (getCeModuleInstanceCount() > 0) { //prevent it ingestJobCounter from going negative
ceModuleInstanceCount--; //Should be called once in the Correlation Engine module's shutdown method.
}
}
@@ -109,89 +123,10 @@ public class IngestEventsListener {
return ceModuleInstanceCount;
}
- private class IngestModuleEventListener implements PropertyChangeListener {
-
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- if (getCeModuleInstanceCount() > 0) {
- EamDb dbManager;
- try {
- dbManager = EamDb.getInstance();
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database.", ex);
- return;
- }
- switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
- case DATA_ADDED: {
- if (!EamDb.isEnabled()) {
- return;
- }
- final ModuleDataEvent mde = (ModuleDataEvent) evt.getOldValue();
- Collection bbArtifacts = mde.getArtifacts();
- if (null == bbArtifacts) { //the ModuleDataEvents don't always have a collection of artifacts set
- return;
- }
- List eamArtifacts = new ArrayList<>();
-
- for (BlackboardArtifact bbArtifact : bbArtifacts) {
- // eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance.
- List convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
- for (CorrelationAttribute eamArtifact : convertedArtifacts) {
- try {
- // Only do something with this artifact if it's unique within the job
- if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
- // Was it previously marked as bad?
- // query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
- // if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
- // create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
- List caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
- if (!caseDisplayNames.isEmpty()) {
- postCorrelatedBadArtifactToBlackboard(bbArtifact,
- caseDisplayNames);
- }
- eamArtifacts.add(eamArtifact);
- }
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex);
- }
- }
- }
-
- if (FALSE == eamArtifacts.isEmpty()) {
- // send update to entperirse artifact manager db
- Runnable r = new NewArtifactsRunner(eamArtifacts);
- // TODO: send r into a thread pool instead
- Thread t = new Thread(r);
- t.start();
- } // DATA_ADDED
- break;
- }
- }
- }
- }
- }
-
- private class IngestJobEventListener implements PropertyChangeListener {
-
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) {
- case DATA_SOURCE_ANALYSIS_COMPLETED: {
- // clear the tracker to reduce memory usage
- if (getCeModuleInstanceCount() == 0) {
- recentlyAddedCeArtifacts.clear();
- }
- //else another instance of the Correlation Engine Module is still being run.
- } // DATA_SOURCE_ANALYSIS_COMPLETED
- break;
- }
- }
- }
-
@NbBundle.Messages({"IngestEventsListener.prevTaggedSet.text=Previously Tagged As Notable (Central Repository)",
- "IngestEventsListener.prevCaseComment.text=Previous Case: ",
+ "IngestEventsListener.prevCaseComment.text=Previous Case: ",
"IngestEventsListener.ingestmodule.name=Correlation Engine"})
- private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List caseDisplayNames) {
+ static private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List caseDisplayNames) {
try {
AbstractFile af = bbArtifact.getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
@@ -222,4 +157,109 @@ public class IngestEventsListener {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS
}
}
+
+ private class IngestModuleEventListener implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (getCeModuleInstanceCount() > 0) {
+ EamDb dbManager;
+ try {
+ dbManager = EamDb.getInstance();
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to connect to Central Repository database.", ex);
+ return;
+ }
+ switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
+ case DATA_ADDED: {
+ jobProcessingExecutor.submit(new DataAddedTask(dbManager, evt));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private class IngestJobEventListener implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) {
+ case DATA_SOURCE_ANALYSIS_COMPLETED: {
+ jobProcessingExecutor.submit(new AnalysisCompleteTask());
+ break;
+ }
+ }
+ }
+
+ }
+
+ private final class AnalysisCompleteTask implements Runnable {
+
+ @Override
+ public void run() {
+ // clear the tracker to reduce memory usage
+ if (getCeModuleInstanceCount() == 0) {
+ recentlyAddedCeArtifacts.clear();
+ }
+ //else another instance of the Correlation Engine Module is still being run.
+ } // DATA_SOURCE_ANALYSIS_COMPLETED
+ }
+
+ private final class DataAddedTask implements Runnable {
+
+ private final EamDb dbManager;
+ private final PropertyChangeEvent event;
+
+ private DataAddedTask(EamDb db, PropertyChangeEvent evt) {
+ dbManager = db;
+ event = evt;
+ }
+
+ @Override
+ public void run() {
+ if (!EamDb.isEnabled()) {
+ return;
+ }
+ final ModuleDataEvent mde = (ModuleDataEvent) event.getOldValue();
+ Collection bbArtifacts = mde.getArtifacts();
+ if (null == bbArtifacts) { //the ModuleDataEvents don't always have a collection of artifacts set
+ return;
+ }
+ List eamArtifacts = new ArrayList<>();
+
+ for (BlackboardArtifact bbArtifact : bbArtifacts) {
+ // eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance.
+ List convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbArtifact, true, true);
+ for (CorrelationAttribute eamArtifact : convertedArtifacts) {
+ try {
+ // Only do something with this artifact if it's unique within the job
+ if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) {
+ // Was it previously marked as bad?
+ // query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
+ // if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
+ // create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
+ List caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact.getCorrelationType(), eamArtifact.getCorrelationValue());
+ if (!caseDisplayNames.isEmpty()) {
+ postCorrelatedBadArtifactToBlackboard(bbArtifact,
+ caseDisplayNames);
+ }
+ eamArtifacts.add(eamArtifact);
+ }
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error counting notable artifacts.", ex);
+ }
+ }
+ }
+ if (FALSE == eamArtifacts.isEmpty()) {
+ try {
+ for (CorrelationAttribute eamArtifact : eamArtifacts) {
+ dbManager.addArtifact(eamArtifact);
+ }
+ } catch (EamDbException ex) {
+ LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
+ }
+ } // DATA_ADDED
+ }
+ }
}
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java
index d2b1beebbb..8af34bc718 100755
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java
@@ -18,12 +18,9 @@
*/
package org.sleuthkit.autopsy.centralrepository.eventlisteners;
-import java.beans.PropertyChangeListener;
import org.openide.modules.ModuleInstall;
-import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.centralrepository.actions.EamEditCaseInfoAction;
/**
* Install event listeners during module initialization
@@ -32,7 +29,7 @@ public class Installer extends ModuleInstall {
private static final Logger LOGGER = Logger.getLogger(Installer.class.getName());
private static final long serialVersionUID = 1L;
- private final PropertyChangeListener pcl = new CaseEventListener();
+ private final CaseEventListener pcl = new CaseEventListener();
private final IngestEventsListener ieListener = new IngestEventsListener();
private static Installer instance;
@@ -54,8 +51,6 @@ public class Installer extends ModuleInstall {
Case.addPropertyChangeListener(pcl);
ieListener.installListeners();
- CallableSystemAction.get(EamEditCaseInfoAction.class).setEnabled(true);
-
// TODO: create a thread pool to process Runners.
}
@@ -71,6 +66,8 @@ public class Installer extends ModuleInstall {
//module is being unloaded
Case.removePropertyChangeListener(pcl);
+ pcl.shutdown();
+ ieListener.shutdown();
ieListener.uninstallListeners();
// TODO: remove thread pool
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/KnownStatusChangeRunner.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/KnownStatusChangeRunner.java
deleted file mode 100755
index 4761f77370..0000000000
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/KnownStatusChangeRunner.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Central Repository
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.centralrepository.eventlisteners;
-
-import java.util.logging.Level;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute;
-import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
-import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
-import org.sleuthkit.datamodel.TskData.FileKnown;
-
-/**
- * Thread to send info to remote DB that tags a file as known, unknown, or notable.
- */
-public class KnownStatusChangeRunner implements Runnable {
-
- private static final Logger LOGGER = Logger.getLogger(KnownStatusChangeRunner.class.getName());
- private static final long serialVersionUID = 1L;
-
- private final CorrelationAttribute artifact;
- private final FileKnown knownStatus;
-
- public KnownStatusChangeRunner(CorrelationAttribute artifact, FileKnown knownStatus) {
- this.artifact = artifact;
- this.knownStatus = knownStatus;
- }
-
- @Override
- public void run() {
- if (!EamDb.isEnabled()) {
- LOGGER.log(Level.WARNING, "Central Repository database not configured"); // NON-NLS
- return;
- }
-
- try {
- EamDb dbManager = EamDb.getInstance();
- dbManager.setArtifactInstanceKnownStatus(this.artifact, this.knownStatus);
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
- }
- }
-}
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java
index fc8d100c37..31d989d74a 100644
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java
@@ -241,9 +241,9 @@ class IngestModule implements FileIngestModule {
curCase.getCreatedDate(),
curCase.getNumber(),
curCase.getExaminer(),
- null,
- null,
- null);
+ curCase.getExaminerEmail(),
+ curCase.getExaminerPhone(),
+ curCase.getCaseNotes());
try {
dbManager.newCase(curCeCase);
eamCase = dbManager.getCaseByUUID(curCase.getName());
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/AddNewOrganizationDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/AddNewOrganizationDialog.java
index 0721c92ca7..db26739a9c 100755
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/AddNewOrganizationDialog.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/AddNewOrganizationDialog.java
@@ -41,10 +41,13 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
public class AddNewOrganizationDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(AddNewOrganizationDialog.class.getName());
+ private static final long serialVersionUID = 1L;
private final Collection textBoxes;
private final TextBoxChangedListener textBoxChangedListener;
private boolean hasChanged;
+ private EamOrganization newOrg;
+ private final EamOrganization organizationToEdit;
/**
* Creates new form AddNewOrganizationDialog
@@ -57,8 +60,28 @@ public class AddNewOrganizationDialog extends javax.swing.JDialog {
textBoxes = new ArrayList<>();
textBoxChangedListener = new TextBoxChangedListener();
hasChanged = false;
+ newOrg = null;
initComponents();
customizeComponents();
+ organizationToEdit = null;
+ display();
+ }
+
+ public AddNewOrganizationDialog(EamOrganization orgToEdit) {
+ super((JFrame) WindowManager.getDefault().getMainWindow(),
+ Bundle.AddNewOrganizationDialog_addNewOrg_msg(),
+ true); // NON-NLS
+ organizationToEdit = orgToEdit;
+ textBoxes = new ArrayList<>();
+ textBoxChangedListener = new TextBoxChangedListener();
+ hasChanged = false;
+ newOrg = null;
+ initComponents();
+ customizeComponents();
+ tfOrganizationName.setText(orgToEdit.getName());
+ tfPocName.setText(orgToEdit.getPocName());
+ tfPocEmail.setText(orgToEdit.getPocEmail());
+ tfPocPhone.setText(orgToEdit.getPocPhone());
display();
}
@@ -177,6 +200,10 @@ public class AddNewOrganizationDialog extends javax.swing.JDialog {
return hasChanged;
}
+ public EamOrganization getNewOrg() {
+ return newOrg;
+ }
+
/**
* 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
@@ -304,14 +331,25 @@ public class AddNewOrganizationDialog extends javax.swing.JDialog {
@Messages({"AddNewOrganizationDialog.bnOk.addFailed.text=Failed to add new organization."})
private void bnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOKActionPerformed
- EamOrganization newOrg = new EamOrganization(
- tfOrganizationName.getText(),
- tfPocName.getText(),
- tfPocEmail.getText(),
- tfPocPhone.getText());
+
try {
EamDb dbManager = EamDb.getInstance();
- dbManager.newOrganization(newOrg);
+ if (organizationToEdit != null) {
+ //check if new name exists with ID other than the one in use here
+ newOrg = new EamOrganization(organizationToEdit.getOrgID(),
+ tfOrganizationName.getText(),
+ tfPocName.getText(),
+ tfPocEmail.getText(),
+ tfPocPhone.getText());
+ dbManager.updateOrganization(newOrg);
+ } else {
+ newOrg = new EamOrganization(
+ tfOrganizationName.getText(),
+ tfPocName.getText(),
+ tfPocEmail.getText(),
+ tfPocPhone.getText());
+ newOrg.setOrgID((int)dbManager.newOrganization(newOrg));
+ }
hasChanged = true;
dispose();
} catch (EamDbException ex) {
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties
index 32a8938df1..7ab2c9b2e4 100755
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties
@@ -75,4 +75,4 @@ ImportHashDatabaseDialog.lbInstructions.text=Choose an .idx file to import into
ImportHashDatabaseDialog.lbFilePath.text=File Path:
ImportHashDatabaseDialog.tfFilePath.text=
EamDbSettingsDialog.lbDatabaseDesc.text=Database File:
-EamDbSettingsDialog.lbFullDbPath.text=jLabel2
+EamDbSettingsDialog.lbFullDbPath.text=
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form
index c9c19a90ff..49d525511b 100755
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form
@@ -25,17 +25,13 @@
+
-
-
-
-
-
-
-
+
+
@@ -56,9 +52,12 @@
+
+
+
@@ -312,9 +311,6 @@
-
-
-
@@ -415,5 +411,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java
index 77b9a63288..58eb9fbe40 100755
--- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java
@@ -41,7 +41,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(GlobalSettingsPanel.class.getName());
-
+
private final IngestJobEventPropertyChangeListener ingestJobEventListener;
/**
@@ -61,12 +61,17 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
"GlobalSettingsPanel.pnCorrelationProperties.border.title=Correlation Properties",
"GlobalSettingsPanel.lbCentralRepository.text=A central repository allows you to correlate files and results between cases.",
"GlobalSettingsPanel.manageTagsTextArea.text=Configure which tag names are associated with notable items. "
- + "When these tags are used, the file or result will be recorded in the central repository. "
- + "If that file or result is seen again in future cases, it will be flagged.",
- "GlobalSettingsPanel.correlationPropertiesTextArea.text=Choose which file and result properties to store in the central repository for later correlation."})
+ + "When these tags are used, the file or result will be recorded in the central repository. "
+ + "If that file or result is seen again in future cases, it will be flagged.",
+ "GlobalSettingsPanel.correlationPropertiesTextArea.text=Choose which file and result properties to store in the central repository for later correlation.",
+ "GlobalSettingsPanel.organizationPanel.border.title=Organizations",
+ "GlobalSettingsPanel.manageOrganizationButton.text=Manage Organizations",
+ "GlobalSettingsPanel.organizationTextArea.text=Organization information can be tracked in the central repository"
+ })
+
private void customizeComponents() {
setName(Bundle.GlobalSettingsPanel_title());
-
+
// The hash set functions of central repo are not being included in the current release.
bnImportDatabase.setVisible(false);
}
@@ -105,6 +110,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
correlationPropertiesScrollPane = new javax.swing.JScrollPane();
correlationPropertiesTextArea = new javax.swing.JTextArea();
lbCentralRepository = new javax.swing.JLabel();
+ organizationPanel = new javax.swing.JPanel();
+ manageOrganizationButton = new javax.swing.JButton();
+ organizationScrollPane = new javax.swing.JScrollPane();
+ organizationTextArea = new javax.swing.JTextArea();
setName(""); // NOI18N
@@ -234,11 +243,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
tbOops.setBorder(null);
- tbOops.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- tbOopsActionPerformed(evt);
- }
- });
pnCorrelationProperties.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
pnCorrelationProperties.setPreferredSize(new java.awt.Dimension(674, 93));
@@ -289,6 +293,51 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
org.openide.awt.Mnemonics.setLocalizedText(lbCentralRepository, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbCentralRepository.text")); // NOI18N
+ organizationPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.organizationPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(manageOrganizationButton, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.manageOrganizationButton.text")); // NOI18N
+ manageOrganizationButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ manageOrganizationButtonActionPerformed(evt);
+ }
+ });
+
+ organizationScrollPane.setBorder(null);
+
+ organizationTextArea.setEditable(false);
+ organizationTextArea.setBackground(new java.awt.Color(240, 240, 240));
+ organizationTextArea.setColumns(20);
+ organizationTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
+ organizationTextArea.setLineWrap(true);
+ organizationTextArea.setRows(2);
+ organizationTextArea.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.organizationTextArea.text")); // NOI18N
+ organizationTextArea.setWrapStyleWord(true);
+ organizationTextArea.setBorder(null);
+ organizationScrollPane.setViewportView(organizationTextArea);
+
+ javax.swing.GroupLayout organizationPanelLayout = new javax.swing.GroupLayout(organizationPanel);
+ organizationPanel.setLayout(organizationPanelLayout);
+ organizationPanelLayout.setHorizontalGroup(
+ organizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(organizationPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(organizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(organizationScrollPane)
+ .addGroup(organizationPanelLayout.createSequentialGroup()
+ .addComponent(manageOrganizationButton)
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+ organizationPanelLayout.setVerticalGroup(
+ organizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, organizationPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(organizationScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(manageOrganizationButton)
+ .addGap(8, 8, 8))
+ );
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@@ -299,15 +348,13 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addComponent(tbOops, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(organizationPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbCentralRepository, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnTagManagement, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(cbUseCentralRepo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(bnImportDatabase, javax.swing.GroupLayout.Alignment.LEADING))
- .addGap(0, 0, Short.MAX_VALUE)))
+ .addComponent(cbUseCentralRepo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(bnImportDatabase, javax.swing.GroupLayout.Alignment.LEADING))
.addContainerGap())))
);
layout.setVerticalGroup(
@@ -323,9 +370,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
.addGap(0, 0, 0)
.addComponent(pnCorrelationProperties, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
+ .addComponent(organizationPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
.addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
- .addComponent(bnImportDatabase))
+ .addComponent(bnImportDatabase)
+ .addContainerGap())
);
pnTagManagement.getAccessibleContext().setAccessibleName("");
@@ -366,9 +416,10 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_cbUseCentralRepoActionPerformed
- private void tbOopsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbOopsActionPerformed
- // TODO add your handling code here:
- }//GEN-LAST:event_tbOopsActionPerformed
+ private void manageOrganizationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageOrganizationButtonActionPerformed
+ store();
+ ManageOrganizationsDialog dialog = new ManageOrganizationsDialog();
+ }//GEN-LAST:event_manageOrganizationButtonActionPerformed
@Override
@Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."})
@@ -427,6 +478,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventListener);
super.finalize();
+
}
/**
@@ -511,7 +563,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
* @return True
*/
private boolean enableButtonSubComponents(Boolean enable) {
- boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
+ boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
pnCorrelationProperties.setEnabled(enable && !ingestRunning);
pnTagManagement.setEnabled(enable && !ingestRunning);
bnManageTypes.setEnabled(enable && !ingestRunning);
@@ -519,6 +571,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
bnManageTags.setEnabled(enable && !ingestRunning);
manageTagsTextArea.setEnabled(enable && !ingestRunning);
correlationPropertiesTextArea.setEnabled(enable && !ingestRunning);
+ organizationPanel.setEnabled(enable && !ingestRunning);
+ organizationTextArea.setEnabled(enable && !ingestRunning);
+ manageOrganizationButton.setEnabled(enable && !ingestRunning);
return true;
}
@@ -537,8 +592,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private javax.swing.JLabel lbDbNameValue;
private javax.swing.JLabel lbDbPlatformTypeLabel;
private javax.swing.JLabel lbDbPlatformValue;
+ private javax.swing.JButton manageOrganizationButton;
private javax.swing.JScrollPane manageTagsScrollPane;
private javax.swing.JTextArea manageTagsTextArea;
+ private javax.swing.JPanel organizationPanel;
+ private javax.swing.JScrollPane organizationScrollPane;
+ private javax.swing.JTextArea organizationTextArea;
private javax.swing.JPanel pnCorrelationProperties;
private javax.swing.JPanel pnDatabaseConfiguration;
private javax.swing.JPanel pnTagManagement;
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.form
new file mode 100644
index 0000000000..0655ced314
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.form
@@ -0,0 +1,356 @@
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java
new file mode 100644
index 0000000000..ad6c26e4d8
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java
@@ -0,0 +1,456 @@
+/*
+ * Central Repository
+ *
+ * Copyright 2015-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.centralrepository.optionspanel;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.util.List;
+import java.util.logging.Level;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle.Messages;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
+import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization;
+import org.sleuthkit.autopsy.coreutils.Logger;
+
+public final class ManageOrganizationsDialog extends JDialog {
+
+ private static final long serialVersionUID = 1L;
+
+ private EamDb dbManager;
+ private EamOrganization newOrg;
+ private final DefaultListModel rulesListModel = new DefaultListModel<>();
+ private final static Logger LOGGER = Logger.getLogger(ManageOrganizationsDialog.class.getName());
+
+ @Messages({"ManageOrganizationsDialog.title.text=Manage Organizations"})
+ /**
+ * Creates new form ManageOrganizationsPanel
+ */
+ public ManageOrganizationsDialog() {
+ super((JFrame) WindowManager.getDefault().getMainWindow(),
+ Bundle.ManageOrganizationsDialog_title_text(),
+ true); // NON-NLS
+ initComponents();
+ try {
+ this.dbManager = EamDb.getInstance();
+ organizationList.setCellRenderer(new DefaultListCellRenderer() {
+ private static final long serialVersionUID = 1L;
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Component getListCellRendererComponent(javax.swing.JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ setText(((EamOrganization) value).getName());
+ return c;
+ }
+ });
+ organizationList.setModel(rulesListModel);
+ organizationList.addListSelectionListener(new OrganizationListSelectionListener());
+ populateList();
+ setButtonsEnabled(organizationList.getSelectedValue() != null);
+ newOrg = null;
+ } catch (EamDbException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ display();
+ }
+
+ private void display() {
+ Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+ setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
+ setVisible(true);
+ }
+
+ private void populateListAndSelect(EamOrganization selected) throws EamDbException {
+ rulesListModel.clear();
+ List orgs = dbManager.getOrganizations();
+ if (orgs.size() > 0) {
+ for (EamOrganization org : orgs) {
+ rulesListModel.addElement(org);
+ if (selected != null && org.getOrgID() == selected.getOrgID()) {
+ selected = org;
+ }
+ }
+ if (orgs.contains(selected)) {
+ organizationList.setSelectedValue(selected, true);
+ } else {
+ organizationList.setSelectedIndex(0);
+ }
+ organizationList.validate();
+ organizationList.repaint();
+ }
+ }
+
+ private void populateList() throws EamDbException {
+ EamOrganization selected = organizationList.getSelectedValue();
+ populateListAndSelect(selected);
+ }
+
+ @Messages({"ManageOrganizationsDialog.pocNameLabel.text=Point of Contact Name:",
+ "ManageOrganizationsDialog.deleteButton.text=Delete",
+ "ManageOrganizationsDialog.newButton.text=New",
+ "ManageOrganizationsDialog.closeButton.text=Close",
+ "ManageOrganizationsDialog.orgNameLabel.text=Organization Name:",
+ "ManageOrganizationsDialog.pocEmailLabel.text=Point of Contact Email:",
+ "ManageOrganizationsDialog.editButton.text=Edit",
+ "ManageOrganizationsDialog.pocPhoneLabel.text=Point of Contact Phone:",
+ "ManageOrganizationsDialog.orgDescriptionTextArea.text=Organizations are used to provide additional contact information for the content they are associated with.",
+ "ManageOrganizationsDialog.orgListLabel.text=Organizations",
+ "ManageOrganizationsDialog.orgDetailsLabel.text=Organization Details",
+ "ManageOrganizationsDialog.confirmDeletion.title=Confirm Deletion",
+ "ManageOrganizationsDialog.confirmDeletion.message=Are you sure you want to delete the selected organization from the central repo?",
+ "ManageOrganizationsDialog.unableToDeleteOrg.title=Unable to Delete",
+ "ManageOrganizationsDialog.unableToDeleteOrg.message=Unable to delete selected organizaiton."})
+ /**
+ * 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")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ manageOrganizationsScrollPane = new javax.swing.JScrollPane();
+ manageOrganizationsPanel = new javax.swing.JPanel();
+ orgListScrollPane = new javax.swing.JScrollPane();
+ organizationList = new javax.swing.JList<>();
+ orgDescriptionScrollPane = new javax.swing.JScrollPane();
+ orgDescriptionTextArea = new javax.swing.JTextArea();
+ newButton = new javax.swing.JButton();
+ deleteButton = new javax.swing.JButton();
+ closeButton = new javax.swing.JButton();
+ orgListLabel = new javax.swing.JLabel();
+ jSeparator1 = new javax.swing.JSeparator();
+ pocNameLabel = new javax.swing.JLabel();
+ pocPhoneLabel = new javax.swing.JLabel();
+ pocEmailLabel = new javax.swing.JLabel();
+ orgNameLabel = new javax.swing.JLabel();
+ orgNameTextField = new javax.swing.JTextField();
+ pocNameTextField = new javax.swing.JTextField();
+ pocPhoneTextField = new javax.swing.JTextField();
+ pocEmailTextField = new javax.swing.JTextField();
+ editButton = new javax.swing.JButton();
+ orgDetailsLabel = new javax.swing.JLabel();
+
+ setMinimumSize(new java.awt.Dimension(545, 450));
+
+ manageOrganizationsScrollPane.setMinimumSize(null);
+ manageOrganizationsScrollPane.setPreferredSize(new java.awt.Dimension(535, 415));
+
+ manageOrganizationsPanel.setPreferredSize(new java.awt.Dimension(527, 407));
+
+ organizationList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
+ orgListScrollPane.setViewportView(organizationList);
+
+ orgDescriptionTextArea.setEditable(false);
+ orgDescriptionTextArea.setBackground(new java.awt.Color(240, 240, 240));
+ orgDescriptionTextArea.setColumns(20);
+ orgDescriptionTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
+ orgDescriptionTextArea.setLineWrap(true);
+ orgDescriptionTextArea.setRows(3);
+ orgDescriptionTextArea.setText(org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.orgDescriptionTextArea.text")); // NOI18N
+ orgDescriptionTextArea.setWrapStyleWord(true);
+ orgDescriptionScrollPane.setViewportView(orgDescriptionTextArea);
+
+ org.openide.awt.Mnemonics.setLocalizedText(newButton, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.newButton.text")); // NOI18N
+ newButton.setMargin(new java.awt.Insets(2, 6, 2, 6));
+ newButton.setMaximumSize(new java.awt.Dimension(70, 23));
+ newButton.setMinimumSize(new java.awt.Dimension(70, 23));
+ newButton.setPreferredSize(new java.awt.Dimension(70, 23));
+ newButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ newButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(deleteButton, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.deleteButton.text")); // NOI18N
+ deleteButton.setMargin(new java.awt.Insets(2, 6, 2, 6));
+ deleteButton.setMaximumSize(new java.awt.Dimension(70, 23));
+ deleteButton.setMinimumSize(new java.awt.Dimension(70, 23));
+ deleteButton.setPreferredSize(new java.awt.Dimension(70, 23));
+ deleteButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ deleteButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.closeButton.text")); // NOI18N
+ closeButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ closeButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(orgListLabel, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.orgListLabel.text")); // NOI18N
+
+ jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
+
+ org.openide.awt.Mnemonics.setLocalizedText(pocNameLabel, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.pocNameLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(pocPhoneLabel, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.pocPhoneLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(pocEmailLabel, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.pocEmailLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(orgNameLabel, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.orgNameLabel.text")); // NOI18N
+
+ orgNameTextField.setEditable(false);
+
+ pocNameTextField.setEditable(false);
+
+ pocPhoneTextField.setEditable(false);
+
+ pocEmailTextField.setEditable(false);
+
+ org.openide.awt.Mnemonics.setLocalizedText(editButton, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.editButton.text")); // NOI18N
+ editButton.setMaximumSize(new java.awt.Dimension(70, 23));
+ editButton.setMinimumSize(new java.awt.Dimension(70, 23));
+ editButton.setPreferredSize(new java.awt.Dimension(70, 23));
+ editButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ editButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(orgDetailsLabel, org.openide.util.NbBundle.getMessage(ManageOrganizationsDialog.class, "ManageOrganizationsDialog.orgDetailsLabel.text")); // NOI18N
+
+ javax.swing.GroupLayout manageOrganizationsPanelLayout = new javax.swing.GroupLayout(manageOrganizationsPanel);
+ manageOrganizationsPanel.setLayout(manageOrganizationsPanelLayout);
+ manageOrganizationsPanelLayout.setHorizontalGroup(
+ manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(orgDescriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(orgListLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(orgListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 224, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(closeButton))
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addGap(29, 29, 29)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(pocNameLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(orgNameLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pocPhoneLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pocEmailLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(pocNameTextField)
+ .addComponent(pocPhoneTextField)
+ .addComponent(pocEmailTextField, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(orgNameTextField))))
+ .addContainerGap())
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(orgDetailsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+ );
+ manageOrganizationsPanelLayout.setVerticalGroup(
+ manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addComponent(orgDetailsLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(orgNameLabel)
+ .addComponent(orgNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(pocNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(pocNameLabel))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(pocPhoneTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(pocPhoneLabel))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(pocEmailTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(pocEmailLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 235, Short.MAX_VALUE)
+ .addComponent(closeButton))
+ .addComponent(jSeparator1)
+ .addGroup(manageOrganizationsPanelLayout.createSequentialGroup()
+ .addComponent(orgDescriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(orgListLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(orgListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(manageOrganizationsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
+ .addContainerGap())
+ );
+
+ manageOrganizationsScrollPane.setViewportView(manageOrganizationsPanel);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(manageOrganizationsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(manageOrganizationsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ }// //GEN-END:initComponents
+
+ private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
+ EamOrganization orgToDelete = organizationList.getSelectedValue();
+ if (orgToDelete != null) {
+ if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(),
+ Bundle.ManageOrganizationsDialog_confirmDeletion_message(),
+ Bundle.ManageOrganizationsDialog_confirmDeletion_title(),
+ JOptionPane.YES_NO_OPTION)) {
+ try {
+ EamDb.getInstance().deleteOrganization(orgToDelete);
+ populateList();
+ } catch (EamDbException ex) {
+ JOptionPane.showMessageDialog(null,
+ ex.getMessage(), Bundle.ManageOrganizationsDialog_unableToDeleteOrg_title(), JOptionPane.WARNING_MESSAGE);
+ LOGGER.log(Level.INFO, "Was unable to delete organization from central repository", ex);
+ }
+ }
+ }
+ }//GEN-LAST:event_deleteButtonActionPerformed
+
+ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
+ dispose();
+ }//GEN-LAST:event_closeButtonActionPerformed
+
+ private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed
+ AddNewOrganizationDialog dialogO = new AddNewOrganizationDialog();
+ if (dialogO.isChanged()) {
+ try {
+ newOrg = dialogO.getNewOrg();
+ populateListAndSelect(dialogO.getNewOrg());
+ } catch (EamDbException ex) {
+
+ }
+ }
+ }//GEN-LAST:event_newButtonActionPerformed
+
+ private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed
+ EamOrganization orgToEdit = organizationList.getSelectedValue();
+ if (orgToEdit != null) {
+ AddNewOrganizationDialog dialogO = new AddNewOrganizationDialog(orgToEdit);
+ if (dialogO.isChanged()) {
+ try {
+ newOrg = dialogO.getNewOrg();
+ populateListAndSelect(dialogO.getNewOrg());
+ } catch (EamDbException ex) {
+
+ }
+ }
+ }
+ }//GEN-LAST:event_editButtonActionPerformed
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton closeButton;
+ private javax.swing.JButton deleteButton;
+ private javax.swing.JButton editButton;
+ private javax.swing.JSeparator jSeparator1;
+ private javax.swing.JPanel manageOrganizationsPanel;
+ private javax.swing.JScrollPane manageOrganizationsScrollPane;
+ private javax.swing.JButton newButton;
+ private javax.swing.JScrollPane orgDescriptionScrollPane;
+ private javax.swing.JTextArea orgDescriptionTextArea;
+ private javax.swing.JLabel orgDetailsLabel;
+ private javax.swing.JLabel orgListLabel;
+ private javax.swing.JScrollPane orgListScrollPane;
+ private javax.swing.JLabel orgNameLabel;
+ private javax.swing.JTextField orgNameTextField;
+ private javax.swing.JList organizationList;
+ private javax.swing.JLabel pocEmailLabel;
+ private javax.swing.JTextField pocEmailTextField;
+ private javax.swing.JLabel pocNameLabel;
+ private javax.swing.JTextField pocNameTextField;
+ private javax.swing.JLabel pocPhoneLabel;
+ private javax.swing.JTextField pocPhoneTextField;
+ // End of variables declaration//GEN-END:variables
+ public boolean isChanged() {
+ return newOrg != null;
+ }
+
+ public EamOrganization getNewOrg() {
+ return newOrg;
+ }
+
+ private void setButtonsEnabled(boolean isSelected) {
+ editButton.setEnabled(isSelected);
+ deleteButton.setEnabled(isSelected);
+ }
+
+ /**
+ * A list events listener for the interesting files sets list component.
+ */
+ private final class OrganizationListSelectionListener implements ListSelectionListener {
+
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ if (e.getValueIsAdjusting()) {
+ return;
+ }
+ EamOrganization selected = organizationList.getSelectedValue();
+ boolean isSelected = (selected != null);
+ setButtonsEnabled(isSelected);
+ if (selected != null) {
+ orgNameTextField.setText(selected.getName());
+ pocNameTextField.setText(selected.getPocName());
+ pocPhoneTextField.setText(selected.getPocPhone());
+ pocEmailTextField.setText(selected.getPocEmail());
+ } else {
+ orgNameTextField.setText("");
+ pocNameTextField.setText("");
+ pocPhoneTextField.setText("");
+ pocEmailTextField.setText("");
+ }
+ }
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/core/Installer.java b/Core/src/org/sleuthkit/autopsy/core/Installer.java
index 0b660acd2a..83250f719d 100755
--- a/Core/src/org/sleuthkit/autopsy/core/Installer.java
+++ b/Core/src/org/sleuthkit/autopsy/core/Installer.java
@@ -29,15 +29,15 @@ import java.util.logging.Handler;
import java.util.logging.Level;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
-import javax.swing.SwingWorker;
-import org.openide.LifecycleManager;
import org.openide.modules.ModuleInstall;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.actions.IngestRunningCheck;
import org.sleuthkit.autopsy.casemodule.Case;
+import static org.sleuthkit.autopsy.core.UserPreferences.SETTINGS_PROPERTIES;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
+import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
/**
@@ -206,6 +206,9 @@ public class Installer extends ModuleInstall {
// Prevent the Autopsy UI from shrinking on high DPI displays
System.setProperty("sun.java2d.dpiaware", "false");
System.setProperty("prism.allowhidpi", "false");
+
+ // Update existing configuration in case of unsupported settings
+ updateConfig();
packageInstallers = new ArrayList<>();
packageInstallers.add(org.sleuthkit.autopsy.coreutils.Installer.getDefault());
@@ -214,6 +217,21 @@ public class Installer extends ModuleInstall {
packageInstallers.add(org.sleuthkit.autopsy.ingest.Installer.getDefault());
packageInstallers.add(org.sleuthkit.autopsy.centralrepository.eventlisteners.Installer.getDefault());
}
+
+ /**
+ * If the mode in the configuration file is 'REVIEW' (2, now invalid), this
+ * method will set it to 'STANDALONE' (0) and disable auto ingest.
+ */
+ private void updateConfig() {
+ String mode = ModuleSettings.getConfigSetting(SETTINGS_PROPERTIES, "AutopsyMode");
+ if(mode != null) {
+ int ordinal = Integer.parseInt(mode);
+ if(ordinal > 1) {
+ UserPreferences.setMode(UserPreferences.SelectedMode.STANDALONE);
+ ModuleSettings.setConfigSetting(UserPreferences.SETTINGS_PROPERTIES, "JoinAutoModeCluster", Boolean.toString(false));
+ }
+ }
+ }
/**
* Check if JavaFx initialized
diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
index df63b0fa1f..86f68e1df5 100755
--- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2014 Basis Technology Corp.
+ * Copyright 2014-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@ import java.util.prefs.BackingStoreException;
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
-import org.openide.util.Exceptions;
import org.openide.util.NbPreferences;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
@@ -76,8 +75,7 @@ public final class UserPreferences {
public enum SelectedMode {
STANDALONE,
- AUTOINGEST,
- REVIEW
+ AUTOINGEST
};
/**
diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml
index 09514caddf..e06fc9ac45 100755
--- a/Core/src/org/sleuthkit/autopsy/core/layer.xml
+++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml
@@ -51,7 +51,7 @@
-
+
@@ -157,7 +157,7 @@
-
+
@@ -165,11 +165,11 @@
-
+
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java
index 753ccd598a..4c7c022871 100755
--- a/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/ExecUtil.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2016 Basis Technology Corp.
+ * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ThreadUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ThreadUtils.java
new file mode 100644
index 0000000000..80f0467781
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/ThreadUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.coreutils;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/*
+ * General purpose actions which can be performed on Threads.
+ */
+final public class ThreadUtils {
+
+ private static final long DEFAULT_TIMEOUT = 5;
+ private static final TimeUnit DEFAULT_TIMEOUT_UNITS = TimeUnit.SECONDS;
+
+ /**
+ * Shuts down a task executor service, waiting until all tasks are
+ * terminated.
+ *
+ * @param executor The executor.
+ */
+ public static void shutDownTaskExecutor(ExecutorService executor) {
+ executor.shutdown();
+ boolean taskCompleted = false;
+ while (!taskCompleted) {
+ try {
+ taskCompleted = executor.awaitTermination(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNITS);
+ } catch (InterruptedException ignored) {
+ /*
+ * The current policy is to wait for the task to finish so that
+ * the case can be left in a consistent state.
+ *
+ * For a specific example of the motivation for this policy,
+ * note that a application service (Solr search service)
+ * experienced an error condition when opening case resources
+ * that left the service blocked uninterruptibly on a socket
+ * read. This eventually led to a mysterious "freeze" as the
+ * user-cancelled service task continued to run holdiong a lock
+ * that a UI thread soon tried to acquire. Thus it has been
+ * deemed better to make the "freeze" happen in a more
+ * informative way, i.e., with the progress indicator for the
+ * unfinished task on the screen, if a similar error condition
+ * arises again.
+ */
+ }
+ }
+ }
+
+ private ThreadUtils() {
+ }
+}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/TimeStampUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/TimeStampUtils.java
similarity index 73%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/TimeStampUtils.java
rename to Core/src/org/sleuthkit/autopsy/coreutils/TimeStampUtils.java
index fe53871dd5..e14b5c5897 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/TimeStampUtils.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/TimeStampUtils.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2015 Basis Technology Corp.
+ * Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.coreutils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -24,32 +24,32 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * Utility methods for working with strings with the time-stamp suffixes used by
- * auto ingest.
+ * Utility methods for working with time stamps of the form
+ * 'yyyy_MM_dd_HH_mm_ss'.
*/
public final class TimeStampUtils {
/*
* Sample time stamp suffix: 2015_02_02_12_10_31
*/
- private static final Pattern timeStampPattern = Pattern.compile("\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2}_\\d{2}$");
+ private static final Pattern TIME_STAMP_PATTERN = Pattern.compile("\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2}_\\d{2}$");
private static final int LENGTH_OF_DATE_TIME_STAMP = 20; // length of the above time stamp
- private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
/**
- * Checks whether a string ends with an auto ingest time stamp.
+ * Checks whether a string ends with a time stamp.
*
* @param inputString The string to check.
*
* @return True or false.
*/
public static boolean endsWithTimeStamp(String inputString) {
- Matcher m = timeStampPattern.matcher(inputString);
+ Matcher m = TIME_STAMP_PATTERN.matcher(inputString);
return m.find();
}
/**
- * Gets the fixed length of the auto-ingest time stamp suffix.
+ * Gets the fixed length of the time stamp suffix.
*
* @return The length.
*/
@@ -58,16 +58,16 @@ public final class TimeStampUtils {
}
/**
- * Creates an auto ingest time stamp suffix using the current time.
+ * Creates a time stamp suffix using the current time.
*
* @return The suffix.
*/
public static String createTimeStamp() {
- return dateFormat.format(Calendar.getInstance().getTime());
+ return DATE_FORMAT.format(Calendar.getInstance().getTime());
}
/**
- * Removes an auto ingest timestamp suffix, if it present.
+ * Removes the time stamp suffix from a string, if present.
*
* @param inputString The string to trim.
*
@@ -82,7 +82,7 @@ public final class TimeStampUtils {
}
/**
- * Gets the auto ingest time stamp suffix from a string, if it is present.
+ * Gets the time stamp suffix from a string, if present.
*
* @param inputString the name to check for a timestamp
*
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java
index 67f65be80b..149e11afa5 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java
@@ -31,9 +31,20 @@ import javax.swing.JComponent;
abstract class AbstractFileSearchFilter implements FileSearchFilter {
final private T component;
-
+ private String lastErrorMessage;
+
AbstractFileSearchFilter(T component) {
this.component = component;
+ this.lastErrorMessage = "";
+ }
+
+ void setLastError(String mes){
+ lastErrorMessage = mes;
+ }
+
+ @Override
+ public String getLastError(){
+ return this.lastErrorMessage;
}
@Override
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties
index fff8007fd4..bb91c8e05c 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties
@@ -57,4 +57,5 @@ MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected
FileSearchPanel.searchButton.text=Search
MimeTypePanel.mimeTypeCheckBox.text=MIME Type:
HashSearchPanel.md5CheckBox.text=MD5:
-HashSearchPanel.emptyHashMsg.text=Must enter something for hash search.
\ No newline at end of file
+HashSearchPanel.emptyHashMsg.text=Must enter something for hash search.
+FileSearchPanel.errorLabel.text=\
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java
index 205db56998..3291c5ae42 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java
@@ -42,6 +42,7 @@ import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
+import org.openide.util.NbBundle.Messages;
/**
* Filters file date properties (modified/created/etc.. times)
@@ -79,25 +80,10 @@ class DateSearchFilter extends AbstractFileSearchFilter {
String query = "NULL";
DateSearchPanel panel = this.getComponent();
- // first, get the selected timeZone from the dropdown list
- String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
- String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
- TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
-
// convert the date from the selected timezone to get the GMT
long fromDate = 0;
String startDateValue = panel.getDateFromTextField().getText();
- Calendar startDate = null;
- try {
- DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
- sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
- Date temp = sdf.parse(startDateValue);
-
- startDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
- startDate.setTime(temp); // convert to GMT
- } catch (ParseException ex) {
- // for now, no need to show the error message to the user here
- }
+ Calendar startDate = getCalendarDate(startDateValue);
if (!startDateValue.isEmpty()) {
if (startDate != null) {
fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
@@ -106,31 +92,13 @@ class DateSearchFilter extends AbstractFileSearchFilter {
long toDate = 0;
String endDateValue = panel.getDateToTextField().getText();
- Calendar endDate = null;
- try {
- DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
- sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
- Date temp2 = sdf.parse(endDateValue);
-
- endDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
- endDate.setTime(temp2); // convert to GMT
- endDate.set(Calendar.HOUR, endDate.get(Calendar.HOUR) + 24); // get the next 24 hours
- } catch (ParseException ex) {
- // for now, no need to show the error message to the user here
- }
+ Calendar endDate = getCalendarDate(endDateValue);
if (!endDateValue.isEmpty()) {
if (endDate != null) {
toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
}
}
- // If they put the dates in backwards, help them out.
- if (fromDate > toDate) {
- long temp = toDate;
- toDate = fromDate;
- fromDate = temp;
- }
-
final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected();
final boolean changedChecked = panel.getChangedCheckBox().isSelected();
final boolean accessedChecked = panel.getAccessedCheckBox().isSelected();
@@ -206,14 +174,56 @@ class DateSearchFilter extends AbstractFileSearchFilter {
return timeZones;
}
+ private TimeZone getSelectedTimeZone() {
+ String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
+ String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
+ TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
+ return selectedTZ;
+ }
+
+ private Calendar getCalendarDate(String dateValue) {
+ TimeZone selectedTZ = getSelectedTimeZone();
+ Calendar inputDate = null;
+ try {
+ DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
+ sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
+ Date temp = sdf.parse(dateValue);
+
+ inputDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
+ inputDate.setTime(temp); // convert to GMT
+ } catch (ParseException ex) {
+ // for now, no need to show the error message to the user here
+ }
+ return inputDate;
+ }
+
@Override
public void addActionListener(ActionListener l) {
getComponent().addActionListener(l);
}
@Override
+ @Messages ({
+ "DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.",
+ "DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected."
+ })
public boolean isValid() {
- return this.getComponent().isValidSearch();
+
+ DateSearchPanel panel = this.getComponent();
+ Calendar startDate = getCalendarDate(panel.getDateFromTextField().getText());
+ Calendar endDate = getCalendarDate(panel.getDateToTextField().getText());
+
+ if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) {
+ setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate());
+ return false;
+ }
+
+ if (!panel.isValidSearch()) {
+ setLastError(Bundle.DateSearchFilter_errorMessage_noCheckboxSelected());
+ return false;
+ }
+
+ return true;
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form
index e92d57fdd9..59082745da 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form
@@ -149,6 +149,7 @@
+
@@ -208,6 +209,7 @@
+
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java
index 7867a5ebd6..b9f490041b 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java
@@ -29,6 +29,8 @@ import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
/**
* Subpanel with controls for file data filtering.
@@ -50,6 +52,7 @@ class DateSearchPanel extends javax.swing.JPanel {
dateFromTextField.setComponentPopupMenu(rightClickMenu);
dateToTextField.setComponentPopupMenu(rightClickMenu);
+
ActionListener actList = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -74,6 +77,41 @@ class DateSearchPanel extends javax.swing.JPanel {
copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
+ this.dateFromTextField.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+ });
+
+ this.dateToTextField.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+ });
+
+
this.setComponentsEnabled();
}
@@ -176,6 +214,7 @@ class DateSearchPanel extends javax.swing.JPanel {
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.selectAllMenuItem.text")); // NOI18N
rightClickMenu.add(selectAllMenuItem);
+ dateToTextField.setEditable(false);
dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N
dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) {
@@ -197,6 +236,7 @@ class DateSearchPanel extends javax.swing.JPanel {
jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
+ dateFromTextField.setEditable(false);
dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N
dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) {
@@ -365,6 +405,7 @@ class DateSearchPanel extends javax.swing.JPanel {
if (evt.getNewValue() instanceof Date) {
setToDate((Date) evt.getNewValue());
}
+
}//GEN-LAST:event_dateToPopupChanged
private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed
@@ -399,6 +440,7 @@ class DateSearchPanel extends javax.swing.JPanel {
if (date != null) {
dateStringResult = dateFormat.format(date);
}
+
dateFromTextField.setText(dateStringResult);
dateFromButtonCalendar.setTargetDate(date);
}
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java
index 457db56570..db16fdd1e0 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java
@@ -47,6 +47,13 @@ interface FileSearchFilter {
* @return Whether the panel has valid input for search.
*/
boolean isValid();
+
+ /**
+ * Get the last error recorded during the call to isValid
+ *
+ * @return Description of why the filter is invalid
+ */
+ String getLastError();
/**
* Gets predicate expression to include in the SQL filter expression
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form
index dbb90bea12..a64489bb01 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form
@@ -23,7 +23,9 @@
-
+
+
+
@@ -32,9 +34,14 @@
-
-
-
+
+
+
+
+
+
+
+
@@ -63,6 +70,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java
index d7efb0b46f..f6c72df611 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java
@@ -27,7 +27,6 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
-import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -111,13 +110,7 @@ class FileSearchPanel extends javax.swing.JPanel {
}
});
}
-
- addListenerToAll(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- search();
- }
- });
+
searchButton.setEnabled(isValidSearch());
}
@@ -130,11 +123,13 @@ class FileSearchPanel extends javax.swing.JPanel {
if (filter.isEnabled()) {
enabled = true;
if (!filter.isValid()) {
+ errorLabel.setText(filter.getLastError());
return false;
}
}
}
+ errorLabel.setText("");
return enabled;
}
@@ -280,6 +275,7 @@ class FileSearchPanel extends javax.swing.JPanel {
filterPanel = new javax.swing.JPanel();
searchButton = new javax.swing.JButton();
+ errorLabel = new javax.swing.JLabel();
setPreferredSize(new java.awt.Dimension(300, 300));
@@ -288,6 +284,14 @@ class FileSearchPanel extends javax.swing.JPanel {
filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS));
searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N
+ searchButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ searchButtonActionPerformed(evt);
+ }
+ });
+
+ errorLabel.setForeground(new java.awt.Color(255, 51, 51));
+ errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@@ -295,21 +299,31 @@ class FileSearchPanel extends javax.swing.JPanel {
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap()
+ .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(searchButton)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
- .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGap(0, 0, 0)
- .addComponent(searchButton)
+ .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(searchButton)
+ .addGroup(layout.createSequentialGroup()
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(errorLabel)))
.addContainerGap())
);
}// //GEN-END:initComponents
+ private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
+ search();
+ }//GEN-LAST:event_searchButtonActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JLabel errorLabel;
private javax.swing.JPanel filterPanel;
private javax.swing.JButton searchButton;
// End of variables declaration//GEN-END:variables
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java
index 951f4b206e..d77fe5826e 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/HashSearchFilter.java
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
/**
@@ -60,7 +61,25 @@ class HashSearchFilter extends AbstractFileSearchFilter {
}
@Override
+ @Messages({
+ "HashSearchFilter.errorMessage.emptyHash=Hash data is empty.",
+ "# {0} - hash data length", "HashSearchFilter.errorMessage.wrongLength=Input length({0}), doesn''t match the MD5 length(32).",
+ "HashSearchFilter.errorMessage.wrongCharacter=MD5 contains invalid hex characters."
+ })
public boolean isValid() {
- return !this.getComponent().getSearchTextField().getText().isEmpty();
+ String inputHashData = this.getComponent().getSearchTextField().getText();
+ if (inputHashData.isEmpty()) {
+ setLastError(Bundle.HashSearchFilter_errorMessage_emptyHash());
+ return false;
+ }
+ if (inputHashData.length() != 32) {
+ setLastError(Bundle.HashSearchFilter_errorMessage_wrongLength(inputHashData.length()));
+ return false;
+ }
+ if (!inputHashData.matches("[0-9a-fA-F]+")) {
+ setLastError(Bundle.HashSearchFilter_errorMessage_wrongCharacter());
+ return false;
+ }
+ return true;
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java
index 5f52afa035..677f0116e9 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
import org.sleuthkit.datamodel.TskData.FileKnown;
/**
@@ -85,7 +86,14 @@ class KnownStatusSearchFilter extends AbstractFileSearchFilter {
}
@Override
+ @Messages ({
+ "MimeTypeFilter.errorMessage.emptyMimeType=At least one MIME type must be selected."
+ })
public boolean isValid() {
- return !this.getComponent().getMimeTypesSelected().isEmpty();
+ if(this.getComponent().getMimeTypesSelected().isEmpty()){
+ setLastError(Bundle.MimeTypeFilter_errorMessage_emptyMimeType());
+ return false;
+ }
+ return true;
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java
index ee70ebd5e1..2b204c8ca8 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java
@@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
/**
@@ -64,7 +65,14 @@ class NameSearchFilter extends AbstractFileSearchFilter {
}
@Override
+ @Messages ({
+ "NameSearchFilter.errorMessage.emtpyName=Please input a name to search."
+ })
public boolean isValid() {
- return !this.getComponent().getSearchTextField().getText().isEmpty();
+ if(this.getComponent().getSearchTextField().getText().isEmpty()) {
+ setLastError(Bundle.NameSearchFilter_errorMessage_emtpyName());
+ return false;
+ }
+ return true;
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java
index ca43dac7e0..cf5d4f9e73 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java
@@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
/**
@@ -74,7 +75,23 @@ class SizeSearchFilter extends AbstractFileSearchFilter {
}
@Override
+ @Messages ({
+ "SizeSearchFilter.errorMessage.nonNegativeNumber=Input size data is a negative number.",
+ "SizeSearchFilter.errorMessage.notANumber=Input size data is not a number."
+ })
public boolean isValid() {
+ String input = this.getComponent().getSizeTextField().getText();
+
+ try {
+ int inputInt = Integer.parseInt(input);
+ if (inputInt < 0) {
+ setLastError(Bundle.SizeSearchFilter_errorMessage_nonNegativeNumber());
+ return false;
+ }
+ } catch (NumberFormatException | NullPointerException e) {
+ setLastError(Bundle.SizeSearchFilter_errorMessage_notANumber());
+ return false;
+ }
return true;
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java
index 3add979247..51aa688619 100755
--- a/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java
@@ -25,6 +25,8 @@ import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JMenuItem;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
/**
*
@@ -65,6 +67,24 @@ class SizeSearchPanel extends javax.swing.JPanel {
copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
+ this.sizeTextField.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
+ }
+ });
+
+
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CenteredGrayableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/guiutils/CenteredGrayableCellRenderer.java
similarity index 91%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CenteredGrayableCellRenderer.java
rename to Core/src/org/sleuthkit/autopsy/guiutils/CenteredGrayableCellRenderer.java
index b9040b674b..af37f3f2e3 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CenteredGrayableCellRenderer.java
+++ b/Core/src/org/sleuthkit/autopsy/guiutils/CenteredGrayableCellRenderer.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2015 Basis Technology Corp.
+ * Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.guiutils;
import static javax.swing.SwingConstants.CENTER;
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DurationCellRenderer.java b/Core/src/org/sleuthkit/autopsy/guiutils/DurationCellRenderer.java
similarity index 71%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DurationCellRenderer.java
rename to Core/src/org/sleuthkit/autopsy/guiutils/DurationCellRenderer.java
index 6bac0a996b..970dafacfc 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DurationCellRenderer.java
+++ b/Core/src/org/sleuthkit/autopsy/guiutils/DurationCellRenderer.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2015 Basis Technology Corp.
+ * Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +16,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.guiutils;
+import java.awt.Color;
import java.awt.Component;
import java.time.Duration;
import javax.swing.JTable;
@@ -28,11 +29,11 @@ import static javax.swing.SwingConstants.CENTER;
* string with days, hours, minutes, and seconds components. It center-aligns
* cell content and grays out the cell if the table is disabled.
*/
-class DurationCellRenderer extends GrayableCellRenderer {
+public class DurationCellRenderer extends GrayableCellRenderer {
private static final long serialVersionUID = 1L;
- DurationCellRenderer() {
+ public DurationCellRenderer() {
setHorizontalAlignment(CENTER);
}
@@ -71,4 +72,26 @@ class DurationCellRenderer extends GrayableCellRenderer {
grayCellIfTableNotEnabled(table, isSelected);
return this;
}
+
+ void grayCellIfTableNotEnabled(JTable table, boolean isSelected) {
+ if (table.isEnabled()) {
+ /*
+ * The table is enabled, make the foreground and background the
+ * normal selected or unselected color.
+ */
+ if (isSelected) {
+ setBackground(table.getSelectionBackground());
+ setForeground(table.getSelectionForeground());
+ } else {
+ setBackground(table.getBackground());
+ setForeground(table.getForeground());
+ }
+ } else {
+ /*
+ * The table is disabled, make the foreground and background gray.
+ */
+ setBackground(Color.lightGray);
+ setForeground(Color.darkGray);
+ }
+ }
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/GrayableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/guiutils/GrayableCellRenderer.java
similarity index 91%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/GrayableCellRenderer.java
rename to Core/src/org/sleuthkit/autopsy/guiutils/GrayableCellRenderer.java
index 60d3b77ccd..53031faae3 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/GrayableCellRenderer.java
+++ b/Core/src/org/sleuthkit/autopsy/guiutils/GrayableCellRenderer.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2015 Basis Technology Corp.
+ * Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.guiutils;
import java.awt.Color;
import java.awt.Component;
@@ -28,11 +28,11 @@ import javax.swing.table.DefaultTableCellRenderer;
* A JTable cell renderer that left-aligns cell content and grays out the cell
* if the table is disabled.
*/
-class GrayableCellRenderer extends DefaultTableCellRenderer {
+public class GrayableCellRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
- GrayableCellRenderer() {
+ public GrayableCellRenderer() {
setHorizontalAlignment(LEFT);
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/LongDateCellRenderer.java b/Core/src/org/sleuthkit/autopsy/guiutils/LongDateCellRenderer.java
similarity index 91%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/LongDateCellRenderer.java
rename to Core/src/org/sleuthkit/autopsy/guiutils/LongDateCellRenderer.java
index cfa2cedb14..373e4e2501 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/LongDateCellRenderer.java
+++ b/Core/src/org/sleuthkit/autopsy/guiutils/LongDateCellRenderer.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2015 Basis Technology Corp.
+ * Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.guiutils;
import java.awt.Component;
import java.text.SimpleDateFormat;
@@ -28,7 +28,7 @@ import static javax.swing.SwingConstants.CENTER;
* center-aligned, long-format date string. It also grays out the cell if the
* table is disabled.
*/
-class LongDateCellRenderer extends GrayableCellRenderer {
+public class LongDateCellRenderer extends GrayableCellRenderer {
private static final long serialVersionUID = 1L;
private static final String FORMAT_STRING = "yyyy/MM/dd HH:mm:ss"; //NON-NLS
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/ShortDateCellRenderer.java b/Core/src/org/sleuthkit/autopsy/guiutils/ShortDateCellRenderer.java
similarity index 66%
rename from Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/ShortDateCellRenderer.java
rename to Core/src/org/sleuthkit/autopsy/guiutils/ShortDateCellRenderer.java
index 713d177c0a..299880f1c0 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/ShortDateCellRenderer.java
+++ b/Core/src/org/sleuthkit/autopsy/guiutils/ShortDateCellRenderer.java
@@ -16,8 +16,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.sleuthkit.autopsy.experimental.autoingest;
+package org.sleuthkit.autopsy.guiutils;
+import java.awt.Color;
import java.awt.Component;
import java.text.SimpleDateFormat;
import javax.swing.JTable;
@@ -46,4 +47,26 @@ class ShortDateCellRenderer extends GrayableCellRenderer {
grayCellIfTableNotEnabled(table, isSelected);
return this;
}
+
+ void grayCellIfTableNotEnabled(JTable table, boolean isSelected) {
+ if (table.isEnabled()) {
+ /*
+ * The table is enabled, make the foreground and background the
+ * normal selected or unselected color.
+ */
+ if (isSelected) {
+ setBackground(table.getSelectionBackground());
+ setForeground(table.getSelectionForeground());
+ } else {
+ setBackground(table.getBackground());
+ setForeground(table.getForeground());
+ }
+ } else {
+ /*
+ * The table is disabled, make the foreground and background gray.
+ */
+ setBackground(Color.lightGray);
+ setForeground(Color.darkGray);
+ }
+ }
}
diff --git a/Core/src/org/sleuthkit/autopsy/guiutils/StatusIconCellRenderer.java b/Core/src/org/sleuthkit/autopsy/guiutils/StatusIconCellRenderer.java
new file mode 100755
index 0000000000..b7ee58e4d4
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/guiutils/StatusIconCellRenderer.java
@@ -0,0 +1,74 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2015-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.guiutils;
+
+import java.awt.Component;
+import javax.swing.ImageIcon;
+import javax.swing.JTable;
+import static javax.swing.SwingConstants.CENTER;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle.Messages;
+
+/**
+ * A JTable cell renderer that represents a status as a center-aligned icon, and
+ * grays out the cell if the table is disabled. The statuses represented are OK,
+ * WARNING, and ERROR.
+ */
+public class StatusIconCellRenderer extends GrayableCellRenderer {
+
+ private static final long serialVersionUID = 1L;
+ static final ImageIcon OK_ICON = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/tick.png", false));
+ static final ImageIcon WARNING_ICON = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/warning16.png", false));
+ static final ImageIcon ERROR_ICON = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/cross-script.png", false));
+
+ @Messages({
+ "StatusIconCellRenderer.tooltiptext.ok=OK",
+ "StatusIconCellRenderer.tooltiptext.warning=A warning occurred",
+ "StatusIconCellRenderer.tooltiptext.error=An error occurred"
+ })
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ setHorizontalAlignment(CENTER);
+ if ((value instanceof Status)) {
+ switch((Status) value) {
+ case OK:
+ setIcon(OK_ICON);
+ setToolTipText(org.openide.util.NbBundle.getMessage(StatusIconCellRenderer.class, "StatusIconCellRenderer.tooltiptext.ok"));
+ break;
+ case WARNING:
+ setIcon(WARNING_ICON);
+ setToolTipText(org.openide.util.NbBundle.getMessage(StatusIconCellRenderer.class, "StatusIconCellRenderer.tooltiptext.warning"));
+ break;
+ case ERROR:
+ setIcon(ERROR_ICON);
+ setToolTipText(org.openide.util.NbBundle.getMessage(StatusIconCellRenderer.class, "StatusIconCellRenderer.tooltiptext.error"));
+ break;
+ }
+ }
+ grayCellIfTableNotEnabled(table, isSelected);
+
+ return this;
+ }
+
+ public enum Status {
+ OK,
+ WARNING,
+ ERROR
+ }
+}
diff --git a/Core/src/org/sleuthkit/autopsy/images/tick.png b/Core/src/org/sleuthkit/autopsy/images/tick.png
new file mode 100755
index 0000000000..a7d7a96be3
Binary files /dev/null and b/Core/src/org/sleuthkit/autopsy/images/tick.png differ
diff --git a/Core/src/org/sleuthkit/autopsy/images/warning16.png b/Core/src/org/sleuthkit/autopsy/images/warning16.png
new file mode 100755
index 0000000000..f5ba881738
Binary files /dev/null and b/Core/src/org/sleuthkit/autopsy/images/warning16.png differ
diff --git a/Core/src/org/sleuthkit/autopsy/ingest/ProfilePanel.java b/Core/src/org/sleuthkit/autopsy/ingest/ProfilePanel.java
index 3110947488..249ded2020 100755
--- a/Core/src/org/sleuthkit/autopsy/ingest/ProfilePanel.java
+++ b/Core/src/org/sleuthkit/autopsy/ingest/ProfilePanel.java
@@ -33,7 +33,8 @@ import org.sleuthkit.autopsy.ingest.IngestProfiles.IngestProfile;
*/
class ProfilePanel extends IngestModuleGlobalSettingsPanel {
- @NbBundle.Messages({"ProfilePanel.profileDescLabel.text=Description:",
+ @NbBundle.Messages({"ProfilePanel.title.text=Profile",
+ "ProfilePanel.profileDescLabel.text=Description:",
"ProfilePanel.profileNameLabel.text=Profile Name:",
"ProfilePanel.newProfileText=NewEmptyProfile",
"ProfilePanel.messages.profilesMustBeNamed=Ingest profile must be named.",
@@ -50,6 +51,7 @@ class ProfilePanel extends IngestModuleGlobalSettingsPanel {
*/
ProfilePanel() {
initComponents();
+ setName(org.openide.util.NbBundle.getMessage(ProfilePanel.class, "ProfilePanel.title.text"));
settings = new IngestJobSettings(NEW_PROFILE_NAME);
ingestSettingsPanel = new IngestJobSettingsPanel(settings);
ingestSettingsPanel.setPastJobsButtonVisible(false);
@@ -59,6 +61,7 @@ class ProfilePanel extends IngestModuleGlobalSettingsPanel {
ProfilePanel(IngestProfile selectedProfile) {
initComponents();
+ setName(org.openide.util.NbBundle.getMessage(ProfilePanel.class, "ProfilePanel.title.text"));
profile = selectedProfile;
profileDescArea.setText(profile.getDescription());
profileNameField.setText(profile.getName());
diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties
index df63e98d2e..f38bcbc815 100755
--- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties
@@ -4,8 +4,6 @@ OpenIDE-Module-Short-Description=Interesting Files Identifier ingest module.
OpenIDE-Module-Name=Interesting Files Identifier
OptionsCategory_Name_InterestingItemDefinitions=Interesting Files
OptionsCategory_Keywords_InterestingItemDefinitions=InterestingItemDefinitions
-OptionsCategory_Name_FileIngestFilterDefinitions=File Ingest Filter
-OptionsCategory_Keywords_FileIngestFilterDefinitions=FileIngestFilterDefinitions
InterestingItemsIdentifierIngestModule.moduleName=Interesting Files Identifier
InterestingItemsIdentifierIngestModule.moduleDescription=Identifies interesting items as defined by interesting item rule sets.
FilesSetPanel.interesting.title=Interesting Files Set
@@ -45,7 +43,7 @@ FilesSetRulePanel.fileSizeCheck.text=File Size:
FilesSetRulePanel.filesRadioButton.text=Files
FilesSetRulePanel.dirsRadioButton.text=Directories
FilesSetDefsPanel.interesting.setsListLabel.text=Rule Sets:
-FilesSetDefsPanel.ingest.setsListLabel.text=File Ingest Filters:
+FilesSetDefsPanel.ingest.setsListLabel.text=File Filters:
FilesSetDefsPanel.interesting.jTextArea1.text=This module allows you to find files that match specified criteria. Each set has a list of rules, which will match on their chosen file characteristics. A file need only match one rule to be found.
FilesSetDefsPanel.ingest.jTextArea1.text=Add rules so that only a subset of the files in a data source are analyzed. Rules are organized into sets and only one set can be used at a time. A file need only match one rule to be analyzed.
FilesSetDefsPanel.interesting.editSetButton.text=Edit Set
diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java
index f989d24971..c67051be97 100755
--- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java
@@ -77,6 +77,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
private final JButton okButton = new JButton("OK");
private final JButton cancelButton = new JButton("Cancel");
private final PANEL_TYPE panelType;
+ private final String filterDialogTitle;
private final String ruleDialogTitle;
private boolean canBeEnabled = true;
@@ -109,7 +110,8 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
this.jLabel7.setVisible(false);
this.fileSizeUnitComboBox.setVisible(false);
this.fileSizeSpinner.setVisible(false);
- this.ruleDialogTitle = "FilesSetPanel.ingest.title";
+ this.filterDialogTitle = "FilesSetPanel.filter.title";
+ this.ruleDialogTitle = "FilesSetPanel.rule.title";
this.jLabel8.setVisible(false);
this.equalitySignComboBox.setVisible(false);
this.ignoreKnownFilesCheckbox.setVisible(false);
@@ -124,13 +126,14 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
org.openide.awt.Mnemonics.setLocalizedText(deleteSetButton, org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.ingest.deleteSetButton.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel6, org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.ingest.jLabel6.text")); // NOI18N
} else {
+ this.filterDialogTitle = "FilesSetPanel.interesting.title";
this.ruleDialogTitle = "FilesSetPanel.interesting.title";
this.ingoreUnallocCheckbox.setVisible(false);
}
}
@NbBundle.Messages({"FilesSetDefsPanel.Interesting.Title=Global Interesting Items Settings",
- "FilesSetDefsPanel.Ingest.Title=File Ingest Filter Settings"})
+ "FilesSetDefsPanel.Ingest.Title=File Filter Settings"})
private void customInit() {
if (panelType == PANEL_TYPE.FILE_INGEST_FILTERS) {
setName(Bundle.FilesSetDefsPanel_Ingest_Title());
@@ -408,7 +411,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
// feedback when isValidDefinition() is called.
int option = JOptionPane.OK_OPTION;
do {
- option = JOptionPane.showConfirmDialog(null, panel, NbBundle.getMessage(FilesSetPanel.class, ruleDialogTitle), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+ option = JOptionPane.showConfirmDialog(null, panel, NbBundle.getMessage(FilesSetPanel.class, filterDialogTitle), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
} while (option == JOptionPane.OK_OPTION && !panel.isValidDefinition());
// While adding new ruleset(selectedSet == null), if rule set with same name already exists, do not add to the filesSets hashMap.
diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetPanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetPanel.java
index 962c18c8e1..51539b5806 100755
--- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetPanel.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2014-2016 Basis Technology Corp.
+ * Copyright 2014-2017 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,7 +29,7 @@ import org.sleuthkit.autopsy.modules.interestingitems.FilesSetDefsPanel.PANEL_TY
*/
public class FilesSetPanel extends javax.swing.JPanel {
- @NbBundle.Messages({"FilesSetPanel.ingest.title=File Ingest Filter", "FilesSetPanel.ingest.createNewFilter=Create/edit file ingest filters...", "FilesSetPanel.ingest.messages.filtersMustBeNamed=File ingest filters must be named."})
+ @NbBundle.Messages({"FilesSetPanel.filter.title=File Filter", "FilesSetPanel.rule.title=File Filter Rule", "FilesSetPanel.ingest.createNewFilter=Create/edit file ingest filters...", "FilesSetPanel.ingest.messages.filtersMustBeNamed=File ingest filters must be named."})
private static final String CREATE_NEW_FILE_INGEST_FILTER = Bundle.FilesSetPanel_ingest_createNewFilter();
private final String mustBeNamedErrorText;
diff --git a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java
index 234ed1509c..2a8235ee08 100755
--- a/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java
+++ b/Core/src/org/sleuthkit/autopsy/report/TableReportGenerator.java
@@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.AbstractFile;
+import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.BlackboardAttribute;
@@ -168,14 +169,27 @@ class TableReportGenerator {
return "unknown";
}
});
- for (String accountType : groupedArtifacts.keySet()) {
+ for (String accountTypeStr : groupedArtifacts.keySet()) {
/* If the report is a ReportHTML, the data type name
* eventualy makes it to useDataTypeIcon which expects but
* does not require a artifact name, so we make a synthetic
* compund name by appending a ":" and the account type.
*/
- final String compundDataTypeName = BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getDisplayName() + ": " + accountType;
- writeTableForDataType(new ArrayList<>(groupedArtifacts.get(accountType)), type, compundDataTypeName, comment);
+ String accountDisplayname = accountTypeStr;
+ if (accountTypeStr != null) {
+ try {
+ Account.Type acctType = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getAccountType(accountTypeStr);
+ if (acctType != null) {
+ accountDisplayname = acctType.getDisplayName();
+ }
+ }
+ catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Unable to get dusplay name for account type.", ex);
+ }
+ }
+
+ final String compundDataTypeName = BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getDisplayName() + ": " + accountDisplayname;
+ writeTableForDataType(new ArrayList<>(groupedArtifacts.get(accountTypeStr)), type, compundDataTypeName, comment);
}
} else {
//all other artifact types are sent to writeTableForDataType directly
diff --git a/Core/src/org/sleuthkit/autopsy/report/taggedhashes/AddTaggedHashesToHashDbConfigPanel.java b/Core/src/org/sleuthkit/autopsy/report/taggedhashes/AddTaggedHashesToHashDbConfigPanel.java
index 93dad76f89..1066973f58 100755
--- a/Core/src/org/sleuthkit/autopsy/report/taggedhashes/AddTaggedHashesToHashDbConfigPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/report/taggedhashes/AddTaggedHashesToHashDbConfigPanel.java
@@ -41,7 +41,6 @@ import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager;
import org.sleuthkit.autopsy.modules.hashdatabase.HashLookupSettingsPanel;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
-
/**
* Instances of this class are used to configure the report module plug in that
* provides a convenient way to add content hashes to hash set databases.
@@ -94,9 +93,11 @@ class AddTaggedHashesToHashDbConfigPanel extends javax.swing.JPanel {
public void mousePressed(MouseEvent evt) {
JList> list = (JList) evt.getSource();
int index = list.locationToIndex(evt.getPoint());
- String value = tagsNamesListModel.getElementAt(index);
- tagNameSelections.put(value, !tagNameSelections.get(value));
- list.repaint();
+ if (index > -1) {
+ String value = tagsNamesListModel.getElementAt(index);
+ tagNameSelections.put(value, !tagNameSelections.get(value));
+ list.repaint();
+ }
}
});
}
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java
new file mode 100755
index 0000000000..843e9e53fa
--- /dev/null
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java
@@ -0,0 +1,71 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.ingest;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import junit.framework.TestCase;
+import org.netbeans.junit.NbModuleSuite;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.casemodule.CaseActionException;
+import org.sleuthkit.autopsy.casemodule.CaseDetails;
+import junit.framework.Test;
+import org.apache.commons.io.FileUtils;
+import org.openide.util.Exceptions;
+
+public class IngestFileFiltersTest extends TestCase {
+
+ private static final Path caseDirectoryPath = Paths.get(System.getProperty("java.io.tmpdir"), "IngestFileFiltersTest");
+ private static final File CASE_DIR = new File(caseDirectoryPath.toString());
+
+ public static Test suite() {
+ NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(IngestFileFiltersTest.class).
+ clusters(".*").
+ enableModules(".*");
+ return conf.suite();
+ }
+
+ @Override
+ public void setUp() {
+ try {
+ Case.createAsCurrentCase(Case.CaseType.SINGLE_USER_CASE, caseDirectoryPath.toString(), new CaseDetails("IngestFiltersTest"));
+ } catch (CaseActionException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ assertTrue(CASE_DIR.exists());
+ }
+
+ @Override
+ public void tearDown() {
+ try {
+ Case.closeCurrentCase();
+ FileUtils.deleteDirectory(CASE_DIR);
+
+ } catch (CaseActionException | IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ assertFalse(CASE_DIR.exists());
+ }
+
+ public void testFilter() {
+ System.out.println("testFilter");
+ }
+}
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/FunctionalTestDspCallback.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/FunctionalTestDspCallback.java
new file mode 100755
index 0000000000..cfa9f3dc59
--- /dev/null
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/FunctionalTestDspCallback.java
@@ -0,0 +1,109 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.testutils;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.concurrent.Immutable;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
+import org.sleuthkit.datamodel.Content;
+
+/**
+ * A data source processor "callback" for unit testing that collects the results
+ * of running a data source processor on a data source and unblocks the job
+ * processing thread when the data source processor finishes running in its own
+ * thread.
+ */
+@Immutable
+public class FunctionalTestDspCallback extends DataSourceProcessorCallback {
+
+ private final Object monitor;
+ private final List errorMessages = new ArrayList<>();
+ private final List dataSourceContent = new ArrayList<>();
+
+ /**
+ * Constructs a data source processor "callback" for unit testing that
+ * collects the results of running a data source processor on a data source
+ * and unblocks the job processing thread when the data source processor
+ * finishes running in its own thread.
+ *
+ * @param monitor A monitor for the callback to signal when the data source
+ * processor completes its processing.
+ */
+ FunctionalTestDspCallback(Object monitor) {
+ this.monitor = monitor;
+ }
+
+ /**
+ * Called by the data source processor when it finishes running in its own
+ * thread.
+ *
+ * @param result The result code for the processing of the data
+ * source.
+ * @param errorMessages Any error messages generated during the
+ * processing of the data source.
+ * @param dataSourceContent The content produced by processing the data
+ * source.
+ */
+ @Override
+ public void done(DataSourceProcessorCallback.DataSourceProcessorResult result, List errorMessages, List dataSourceContent) {
+ this.errorMessages.addAll(errorMessages);
+ this.dataSourceContent.addAll(dataSourceContent);
+ synchronized (monitor) {
+ monitor.notify();
+ }
+ }
+
+ /**
+ * Called by the data source processor when it finishes running in its own
+ * thread, if that thread is the AWT (Abstract Window Toolkit) event
+ * dispatch thread (EDT).
+ *
+ * @param result The result code for the processing of the data
+ * source.
+ * @param errorMessages Any error messages generated during the
+ * processing of the data source.
+ * @param dataSourceContent The content produced by processing the data
+ * source.
+ */
+ @Override
+ public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List errorMessages, List dataSourceContent) {
+ done(result, errorMessages, dataSourceContent);
+ }
+
+ /**
+ * Gets any error messages emitted by the data source processor.
+ *
+ * @return A list of error messages, possibly empty.
+ */
+ public List getDspErrorMessages() {
+ return new ArrayList<>(this.errorMessages);
+ }
+
+ /**
+ * Gets any data source content objects produced by the data source
+ * processor.
+ *
+ * @return A list of content objects, possibly empty.
+ */
+ public List getDataSourceContent() {
+ return new ArrayList<>(this.dataSourceContent);
+ }
+
+}
diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/FunctionalTestDspProgressMonitor.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/FunctionalTestDspProgressMonitor.java
new file mode 100755
index 0000000000..03d26eb9b2
--- /dev/null
+++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/FunctionalTestDspProgressMonitor.java
@@ -0,0 +1,62 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.testutils;
+
+import javax.annotation.concurrent.Immutable;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
+
+/**
+ * A data source processor progress monitor for unit testing.
+ */
+@Immutable
+public class FunctionalTestDspProgressMonitor implements DataSourceProcessorProgressMonitor {
+
+ /**
+ * Switches the progress indicator to indeterminate mode (the total number
+ * of work units to be completed is unknown) or determinate mode (the total
+ * number of work units to be completed is unknown).
+ *
+ * @param indeterminate True for indeterminate mode, false for determinate
+ * mode.
+ */
+ @Override
+ public void setIndeterminate(final boolean indeterminate) {
+ }
+
+ /**
+ * 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 setProgress(final int workUnitsCompleted) {
+ }
+
+ /**
+ * Updates the progress indicator with a progress message.
+ *
+ * @param message The progress message.
+ */
+ @Override
+ public void setProgressText(final String message) {
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AutoIngestCasePanelInterface.java b/Core/test/unit/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java
similarity index 54%
rename from Core/src/org/sleuthkit/autopsy/casemodule/AutoIngestCasePanelInterface.java
rename to Core/test/unit/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java
index 795b636b35..29618e30ec 100755
--- a/Core/src/org/sleuthkit/autopsy/casemodule/AutoIngestCasePanelInterface.java
+++ b/Core/test/unit/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java
@@ -15,15 +15,37 @@
* 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;
+ */package org.sleuthkit.autopsy.ingest;
-import javax.swing.JDialog;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
-/**
- * Interface for startup window implementations
- */
-public interface AutoIngestCasePanelInterface {
+public class IngestFileFiltersTest {
- public void addWindowStateListener(JDialog parent);
+ public IngestFileFiltersTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testFilters() {
+ System.out.println("Test filter");
+ }
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AddArchiveTask.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AddArchiveTask.java
index 3bc76e61fd..b2204f1b2c 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AddArchiveTask.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AddArchiveTask.java
@@ -28,6 +28,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
import org.sleuthkit.datamodel.Content;
/*
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCase.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCase.java
deleted file mode 100755
index ff47423030..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCase.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.Objects;
-import java.util.logging.Level;
-import org.sleuthkit.autopsy.casemodule.CaseMetadata;
-import org.sleuthkit.autopsy.coreutils.Logger;
-
-/**
- * A representation of a case created by automated ingest.
- */
-class AutoIngestCase implements Comparable {
-
- private static final Logger logger = Logger.getLogger(AutoIngestCase.class.getName());
- private final Path caseDirectoryPath;
- private final String caseName;
- private final Path metadataFilePath;
- private final Date createDate;
- private final Date lastAccessedDate;
-
- /**
- * Constructs a representation of case created by automated ingest.
- *
- * @param caseDirectoryPath The case directory path.
- */
- AutoIngestCase(Path caseDirectoryPath) {
- this.caseDirectoryPath = caseDirectoryPath;
- caseName = PathUtils.caseNameFromCaseDirectoryPath(caseDirectoryPath);
- metadataFilePath = caseDirectoryPath.resolve(caseName + CaseMetadata.getFileExtension());
- BasicFileAttributes fileAttrs = null;
- try {
- fileAttrs = Files.readAttributes(metadataFilePath, BasicFileAttributes.class);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, String.format("Error reading file attributes of case metadata file in %s, will use current time for case createDate/lastModfiedDate", caseDirectoryPath), ex);
- }
- if (null != fileAttrs) {
- createDate = new Date(fileAttrs.creationTime().toMillis());
- lastAccessedDate = new Date(fileAttrs.lastAccessTime().toMillis());
- } else {
- createDate = new Date();
- lastAccessedDate = new Date();
- }
- }
-
- /**
- * Gets the case directory path.
- *
- * @return The case directory path.
- */
- Path getCaseDirectoryPath() {
- return this.caseDirectoryPath;
- }
-
- /**
- * Gets the case name.
- *
- * @return The case name.
- */
- String getCaseName() {
- return this.caseName;
- }
-
- /**
- * Gets the creation date for the case, defined as the create time of the
- * case metadata file.
- *
- * @return The case creation date.
- */
- Date getCreationDate() {
- return this.createDate;
- }
-
- /**
- * Gets the last accessed date for the case, defined as the last accessed
- * time of the case metadata file.
- *
- * @return The last accessed date.
- */
- Date getLastAccessedDate() {
- return this.lastAccessedDate;
- }
-
- /**
- * Gets the status of this case based on the auto ingest result file in the
- * case directory.
- *
- * @return See CaseStatus enum definition.
- */
- CaseStatus getStatus() {
- if (AutoIngestAlertFile.exists(caseDirectoryPath)) {
- return CaseStatus.ALERT;
- } else {
- return CaseStatus.OK;
- }
- }
-
- /**
- * Indicates whether or not some other object is "equal to" this
- * AutoIngestCase object.
- *
- * @param other The other object.
- *
- * @return True or false.
- */
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof AutoIngestCase)) {
- return false;
- }
- if (other == this) {
- return true;
- }
- return this.caseDirectoryPath.toString().equals(((AutoIngestCase) other).caseDirectoryPath.toString());
- }
-
- /**
- * Returns a hash code value for this AutoIngestCase object.
- *
- * @return The has code.
- */
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 71 * hash + Objects.hashCode(this.caseDirectoryPath);
- hash = 71 * hash + Objects.hashCode(this.createDate);
- hash = 71 * hash + Objects.hashCode(this.caseName);
- return hash;
- }
-
- /**
- * Compares this AutopIngestCase object with abnother AutoIngestCase object
- * for order.
- */
- @Override
- public int compareTo(AutoIngestCase other) {
- return -this.lastAccessedDate.compareTo(other.getLastAccessedDate());
- }
-
- /**
- * Comparator for a descending order sort on date created.
- */
- static class LastAccessedDateDescendingComparator implements Comparator {
-
- /**
- * Compares two AutoIngestCase objects for order based on last accessed
- * date (descending).
- *
- * @param object The first AutoIngestCase object
- * @param otherObject The second AuotIngestCase object.
- *
- * @return A negative integer, zero, or a positive integer as the first
- * argument is less than, equal to, or greater than the second.
- */
- @Override
- public int compare(AutoIngestCase object, AutoIngestCase otherObject) {
- return -object.getLastAccessedDate().compareTo(otherObject.getLastAccessedDate());
- }
- }
-
- enum CaseStatus {
-
- OK,
- ALERT
- }
-
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCaseManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCaseManager.java
deleted file mode 100755
index 8469ff2315..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCaseManager.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2011-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import org.sleuthkit.autopsy.casemodule.Case;
-import org.sleuthkit.autopsy.casemodule.CaseActionException;
-import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
-import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
-
-/**
- * Handles locating and opening cases created by auto ingest.
- */
-final class AutoIngestCaseManager {
-
- private static AutoIngestCaseManager instance;
-
- private CoordinationService coordinationService;
-
- /**
- * Gets the auto ingest case manager.
- *
- * @return The auto ingest case manager singleton.
- *
- * @throws AutoIngestCaseManagerException
- */
- synchronized static AutoIngestCaseManager getInstance() throws AutoIngestCaseManager.AutoIngestCaseManagerException {
- if (null == instance) {
- instance = new AutoIngestCaseManager();
- }
- return instance;
- }
-
- /**
- * Constructs an object that handles locating and opening cases created by
- * auto ingest.
- *
- * @throws AutoIngestCaseManagerException
- */
- private AutoIngestCaseManager() throws AutoIngestCaseManagerException {
- try {
- coordinationService = CoordinationService.getInstance();
- } catch (CoordinationServiceException ex) {
- throw new AutoIngestCaseManager.AutoIngestCaseManagerException("Failed to get the coordination service.", ex);
- }
- }
-
- /**
- * Gets a list of the cases in the top level case folder used by auto
- * ingest.
- *
- * @return List of cases.
- *
- * @throws AutoIngestCaseManagerException
- */
- List getCases() throws AutoIngestCaseManagerException {
- List cases = new ArrayList<>();
- List casePathList = getCasePaths();
- for (Path casePath : casePathList) {
- cases.add(new AutoIngestCase(casePath));
- }
- return cases;
- }
-
- /**
- * Retrieve all of the case nodes and filter for only those that represent
- * case paths.
- *
- * @return List of case paths.
- *
- * @throws AutoIngestCaseManagerException
- */
- private List getCasePaths() throws AutoIngestCaseManagerException {
- try {
- List nodeList = coordinationService.getNodeList(CoordinationService.CategoryNode.CASES);
- List casePathList = new ArrayList(0);
- for (String node : nodeList) {
- if(node.indexOf('\\') >= 0 || node.indexOf('/') >= 0) {
- /*
- * This is not a case name lock (name specifies a path).
- */
- String nodeUpperCase = node.toUpperCase();
- if(!nodeUpperCase.endsWith("_RESOURCES") && !nodeUpperCase.endsWith("AUTO_INGEST_LOG.TXT")) {
- /*
- * This is not a case resource lock, nor a case auto
- * ingest log lock. Collect the path.
- */
- casePathList.add(Paths.get(node));
- }
- }
- }
- return casePathList;
-
- } catch (CoordinationServiceException ex) {
- throw new AutoIngestCaseManager.AutoIngestCaseManagerException("Failed to get node list from coordination service.", ex);
- }
- }
-
- /**
- * 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());
- }
-
- /**
- * Exception type thrown when there is an error completing an auto ingest
- * case manager operation.
- */
- static final class AutoIngestCaseManagerException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructs an instance of the exception type thrown when there is an
- * error completing an auto ingest case manager operation.
- *
- * @param message The exception message.
- */
- private AutoIngestCaseManagerException(String message) {
- super(message);
- }
-
- /**
- * Constructs an instance of the exception type thrown when there is an
- * error completing an auto ingest case manager operation.
- *
- * @param message The exception message.
- * @param cause A Throwable cause for the error.
- */
- private AutoIngestCaseManagerException(String message, Throwable cause) {
- super(message, cause);
- }
-
- }
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCaseOpenAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCaseOpenAction.java
deleted file mode 100755
index e86a7bcf8a..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestCaseOpenAction.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2015 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.logging.Level;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
-import org.openide.util.actions.CallableSystemAction;
-import org.openide.util.actions.SystemAction;
-import org.sleuthkit.autopsy.casemodule.CaseCloseAction;
-import org.sleuthkit.autopsy.casemodule.CaseOpenAction;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.casemodule.Case;
-import org.sleuthkit.autopsy.casemodule.StartupWindowProvider;
-import org.sleuthkit.autopsy.core.UserPreferences;
-
-final class AutoIngestCaseOpenAction extends CallableSystemAction implements ActionListener {
-
- private static final Logger logger = Logger.getLogger(AutoIngestCaseOpenAction.class.getName());
- private static final long serialVersionUID = 1L;
-
- public AutoIngestCaseOpenAction() {
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
-
- UserPreferences.SelectedMode mode = UserPreferences.getMode();
- switch (mode) {
- case REVIEW:
-
- if (Case.isCaseOpen()) {
- /*
- * In review mode, close the currently open case, if any, and
- * then display the review mode cases panel. This can be
- * accomplished by invoking CaseCloseAction because it calls
- * StartupWindowProvider.getInstance().open() after it closes
- * the current case.
- */
- SystemAction.get(CaseCloseAction.class).actionPerformed(e);
- } else {
- // no case is open, so show the startup window
- StartupWindowProvider.getInstance().open();
- }
- break;
-
- case AUTOINGEST:
- /*
- * New case action is disabled in auto ingest mode.
- */
- break;
-
- case STANDALONE:
- /**
- * In standalone mode, invoke default Autopsy version of CaseOpenAction.
- */
- Lookup.getDefault().lookup(CaseOpenAction.class).actionPerformed(e);
- break;
-
-
- default:
- logger.log(Level.SEVERE, "Attempting to open case in unsupported mode {0}", mode.toString());
- }
- }
-
- @Override
- public void performAction() {
- }
-
- @Override
- public String getName() {
- return NbBundle.getMessage(AutoIngestCaseOpenAction.class, "CTL_OpenAction");
- }
-
- @Override
- public HelpCtx getHelpCtx() {
- return HelpCtx.DEFAULT_HELP;
- }
-
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java
index 891975223a..fa4476d6f5 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java
@@ -60,10 +60,13 @@ import org.sleuthkit.autopsy.core.ServicesMonitor;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
-import org.sleuthkit.autopsy.ingest.IngestManager;
-import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestManager.CaseDeletionResult;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestManager.JobsSnapshot;
+import org.sleuthkit.autopsy.guiutils.DurationCellRenderer;
+import org.sleuthkit.autopsy.guiutils.LongDateCellRenderer;
+import org.sleuthkit.autopsy.guiutils.StatusIconCellRenderer;
+import org.sleuthkit.autopsy.ingest.IngestManager;
+import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
/**
* A panel for monitoring automated ingest by a cluster, and for controlling
@@ -596,7 +599,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
* renderer that will choose an icon to represent the job status.
*/
column = completedTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader());
- column.setCellRenderer(new CaseStatusIconCellRenderer());
+ column.setCellRenderer(new StatusIconCellRenderer());
column.setMinWidth(STATUS_COL_MIN_WIDTH);
column.setMaxWidth(STATUS_COL_MAX_WIDTH);
column.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH);
@@ -1152,7 +1155,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer {
job.getProcessingStageStartDate(), // STARTED_TIME
job.getCompletedDate(), // COMPLETED_TIME
status.getDescription(), // ACTIVITY
- job.getErrorsOccurred(), // STATUS
+ job.getErrorsOccurred() ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK, // STATUS
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // ACTIVITY_TIME
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
job.getProcessingHostName().equals(LOCAL_HOST_NAME), // IS_LOCAL_JOB
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.form b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.form
index 4a943b4924..9a599877f8 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.form
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.form
@@ -29,8 +29,19 @@
+
+
-
+
+
+
+
+
+
+
+
+
+
@@ -39,18 +50,9 @@
-
-
-
-
-
-
-
-
-
@@ -81,6 +83,7 @@
+
@@ -255,5 +258,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java
index 2d10dff258..feafba3f4f 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java
@@ -44,6 +44,9 @@ import org.sleuthkit.autopsy.core.ServicesMonitor;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestMonitor.JobsSnapshot;
+import org.sleuthkit.autopsy.guiutils.DurationCellRenderer;
+import org.sleuthkit.autopsy.guiutils.LongDateCellRenderer;
+import org.sleuthkit.autopsy.guiutils.StatusIconCellRenderer;
/**
* A dashboard for monitoring an automated ingest cluster.
@@ -400,7 +403,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
* renderer that will choose an icon to represent the job status.
*/
column = completedTable.getColumn(JobsTableModelColumns.STATUS.getColumnHeader());
- column.setCellRenderer(new CaseStatusIconCellRenderer());
+ column.setCellRenderer(new StatusIconCellRenderer());
column.setMinWidth(STATUS_COL_MIN_WIDTH);
column.setMaxWidth(STATUS_COL_MAX_WIDTH);
column.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH);
@@ -472,7 +475,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
job.getProcessingStageStartDate(), // STARTED_TIME
job.getCompletedDate(), // COMPLETED_TIME
status.getDescription(), // STAGE
- job.getErrorsOccurred(), // STATUS
+ job.getErrorsOccurred() ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK, // STATUS
((Date.from(Instant.now()).getTime()) - (status.getStartDate().getTime())), // STAGE_TIME
job.getCaseDirectoryPath(), // CASE_DIRECTORY_PATH
job.getManifest().getFilePath(), // MANIFEST_FILE_PATH
@@ -662,6 +665,7 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
tbServicesStatusMessage = new javax.swing.JTextField();
prioritizeJobButton = new javax.swing.JButton();
prioritizeCaseButton = new javax.swing.JButton();
+ clusterMetricsButton = new javax.swing.JButton();
org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.jButton1.text")); // NOI18N
@@ -762,6 +766,13 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
}
});
+ org.openide.awt.Mnemonics.setLocalizedText(clusterMetricsButton, org.openide.util.NbBundle.getMessage(AutoIngestDashboard.class, "AutoIngestDashboard.clusterMetricsButton.text")); // NOI18N
+ clusterMetricsButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ clusterMetricsButtonActionPerformed(evt);
+ }
+ });
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@@ -770,24 +781,26 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(pendingScrollPane)
+ .addComponent(runningScrollPane, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(completedScrollPane, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbPending)
- .addComponent(lbCompleted)
- .addComponent(lbRunning)
- .addGroup(layout.createSequentialGroup()
- .addComponent(lbServicesStatus)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(prioritizeJobButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(prioritizeCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addGap(0, 0, Short.MAX_VALUE))
- .addComponent(runningScrollPane, javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(completedScrollPane, javax.swing.GroupLayout.Alignment.LEADING))
+ .addComponent(prioritizeCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(clusterMetricsButton))
+ .addComponent(lbPending, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbCompleted, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbRunning, javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
+ .addComponent(lbServicesStatus)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
@@ -813,7 +826,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(refreshButton)
.addComponent(prioritizeJobButton)
- .addComponent(prioritizeCaseButton))
+ .addComponent(prioritizeCaseButton)
+ .addComponent(clusterMetricsButton))
.addContainerGap())
);
}// //GEN-END:initComponents
@@ -872,7 +886,12 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
}
}//GEN-LAST:event_prioritizeCaseButtonActionPerformed
+ private void clusterMetricsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clusterMetricsButtonActionPerformed
+ new AutoIngestMetricsDialog(this.getTopLevelAncestor(), autoIngestMonitor);
+ }//GEN-LAST:event_clusterMetricsButtonActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton clusterMetricsButton;
private javax.swing.JScrollPane completedScrollPane;
private javax.swing.JTable completedTable;
private javax.swing.JButton jButton1;
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java
index 7e1b1907af..45563a4f4b 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboardOpenAction.java
@@ -25,7 +25,6 @@ import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.core.UserPreferences;
-import static org.sleuthkit.autopsy.core.UserPreferences.SelectedMode.REVIEW;
import org.sleuthkit.autopsy.coreutils.Logger;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.experimental.autoingest.AutoIngestDashboardOpenAction")
@@ -39,8 +38,7 @@ public final class AutoIngestDashboardOpenAction extends CallableSystemAction {
@Override
public boolean isEnabled() {
- UserPreferences.SelectedMode mode = UserPreferences.getMode();
- return (mode == REVIEW);
+ return (UserPreferences.getIsMultiUserModeEnabled());
}
@Override
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java
index 2f2f22fb0d..b621cb514f 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java
@@ -62,6 +62,7 @@ import org.openide.util.Lookup;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.casemodule.CaseActionException;
+import org.sleuthkit.autopsy.casemodule.CaseDetails;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
@@ -117,7 +118,6 @@ public final class AutoIngestManager extends Observable implements PropertyChang
private static final int NUM_INPUT_SCAN_SCHEDULING_THREADS = 1;
private static final String INPUT_SCAN_SCHEDULER_THREAD_NAME = "AIM-input-scan-scheduler-%d";
private static final String INPUT_SCAN_THREAD_NAME = "AIM-input-scan-%d";
- private static int DEFAULT_JOB_PRIORITY = 0;
private static final String AUTO_INGEST_THREAD_NAME = "AIM-job-processing-%d";
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
private static final String EVENT_CHANNEL_NAME = "Auto-Ingest-Manager-Events";
@@ -2115,7 +2115,8 @@ public final class AutoIngestManager extends Observable implements PropertyChang
Case.openAsCurrentCase(metadataFilePath.toString());
} else {
caseDirectoryPath = PathUtils.createCaseFolderPath(rootOutputDirectory, caseName);
- Case.createAsCurrentCase(caseDirectoryPath.toString(), caseName, "", "", CaseType.MULTI_USER_CASE);
+ CaseDetails caseDetails = new CaseDetails(caseName);
+ Case.createAsCurrentCase(CaseType.MULTI_USER_CASE, caseDirectoryPath.toString(), caseDetails);
/*
* Sleep a bit before releasing the lock to ensure
* that the new case folder is visible on the
@@ -2932,4 +2933,4 @@ public final class AutoIngestManager extends Observable implements PropertyChang
}
-}
+}
\ No newline at end of file
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form
new file mode 100755
index 0000000000..49e700ca21
--- /dev/null
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.form
@@ -0,0 +1,113 @@
+
+
+
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java
new file mode 100755
index 0000000000..66c6d28581
--- /dev/null
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java
@@ -0,0 +1,178 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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 com.github.lgooddatepicker.datepicker.DatePicker;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Window;
+import java.sql.Date;
+import java.text.SimpleDateFormat;
+import java.time.ZoneOffset;
+import org.openide.util.NbBundle;
+import org.openide.util.NbBundle.Messages;
+
+/**
+ * Display basic metrics for a cluster.
+ */
+final class AutoIngestMetricsDialog extends javax.swing.JDialog {
+
+ private final AutoIngestMonitor autoIngestMonitor;
+
+ /**
+ * Creates new form AutoIngestMetricsDialog
+ *
+ * @param parent The parent container.
+ * @param autoIngestMonitor The auto ingest monitor.
+ */
+ @Messages({
+ "AutoIngestMetricsDialog.title.text=Auto Ingest Cluster Metrics",
+ "AutoIngestMetricsDialog.initReportText=Select a date below and click the 'Get Metrics Since...' button to generate\na metrics report."
+ })
+ AutoIngestMetricsDialog(Container parent, AutoIngestMonitor autoIngestMonitor) {
+ super((Window) parent, NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.title.text"), ModalityType.MODELESS);
+ initComponents();
+ reportTextArea.setText(NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.initReportText"));
+ this.autoIngestMonitor = autoIngestMonitor;
+ setModal(true);
+ setSize(getPreferredSize());
+ setLocationRelativeTo(parent);
+ setVisible(true);
+ }
+
+ /**
+ * Update the metrics shown in the report text area.
+ */
+ private void updateMetrics() {
+ if(datePicker.getDate() == null) {
+ return;
+ }
+
+ AutoIngestMonitor.MetricsSnapshot metricsSnapshot = autoIngestMonitor.getMetricsSnapshot();
+ Object[] completedJobDates = metricsSnapshot.getCompletedJobDates().toArray();
+ int count = 0;
+ long pickedDate = datePicker.getDate().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000;
+ for(int i = completedJobDates.length - 1; i >= 0; i--) {
+ if((Long)completedJobDates[i] >= pickedDate) {
+ count++;
+ }
+ }
+
+ SimpleDateFormat dateFormatter = new SimpleDateFormat("MMM d, yyyy");
+ reportTextArea.setText(String.format(
+ "Since %s:\n" +
+ "\tNumber of Jobs Completed: %d\n",
+ dateFormatter.format(Date.valueOf(datePicker.getDate())),
+ count
+ ));
+ }
+
+ /**
+ * 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")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ closeButton = new javax.swing.JButton();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ reportTextArea = new javax.swing.JTextArea();
+ metricsButton = new javax.swing.JButton();
+ datePicker = new DatePicker();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setAlwaysOnTop(true);
+ setResizable(false);
+
+ org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.closeButton.text")); // NOI18N
+ closeButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ closeButtonActionPerformed(evt);
+ }
+ });
+
+ reportTextArea.setEditable(false);
+ reportTextArea.setColumns(20);
+ reportTextArea.setRows(5);
+ reportTextArea.setText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.reportTextArea.text")); // NOI18N
+ jScrollPane1.setViewportView(reportTextArea);
+
+ org.openide.awt.Mnemonics.setLocalizedText(metricsButton, org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.metricsButton.text")); // NOI18N
+ metricsButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ metricsButtonActionPerformed(evt);
+ }
+ });
+
+ datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jScrollPane1)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(metricsButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 33, Short.MAX_VALUE)
+ .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(closeButton)
+ .addComponent(metricsButton))
+ .addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
+ setVisible(false);
+ dispose();
+ }//GEN-LAST:event_closeButtonActionPerformed
+
+ private void metricsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_metricsButtonActionPerformed
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ updateMetrics();
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }//GEN-LAST:event_metricsButtonActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton closeButton;
+ private com.github.lgooddatepicker.datepicker.DatePicker datePicker;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JButton metricsButton;
+ private javax.swing.JTextArea reportTextArea;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java
index 9a262bb6d3..37c635b9f0 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java
@@ -23,10 +23,12 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Observable;
import java.util.Set;
+import java.util.TreeSet;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@@ -43,7 +45,7 @@ import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJob.ProcessingSta
* An auto ingest monitor responsible for monitoring and reporting the
* processing of auto ingest jobs.
*/
-public final class AutoIngestMonitor extends Observable implements PropertyChangeListener {
+final class AutoIngestMonitor extends Observable implements PropertyChangeListener {
private static final Logger LOGGER = Logger.getLogger(AutoIngestMonitor.class.getName());
private static final int NUM_COORD_SVC_QUERY_THREADS = 1;
@@ -265,17 +267,86 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
}
} catch (InterruptedException ex) {
LOGGER.log(Level.SEVERE, String.format("Unexpected interrupt while retrieving coordination service node data for '%s'", node), ex);
- } catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJob.AutoIngestJobException ex) {
+ } catch (AutoIngestJobNodeData.InvalidDataException ex) {
LOGGER.log(Level.SEVERE, String.format("Unable to use node data for '%s'", node), ex);
+ } catch (AutoIngestJob.AutoIngestJobException ex) {
+ LOGGER.log(Level.SEVERE, String.format("Failed to create a job for '%s'", node), ex);
}
}
+
return newJobsSnapshot;
+
} catch (CoordinationServiceException ex) {
LOGGER.log(Level.SEVERE, "Failed to get node list from coordination service", ex);
return new JobsSnapshot();
}
}
+ /**
+ * Gets a new metrics snapshot from the coordination service for an auto
+ * ingest cluster.
+ *
+ * @return The metrics snapshot.
+ */
+ private MetricsSnapshot queryCoordinationServiceForMetrics() {
+ try {
+ MetricsSnapshot newMetricsSnapshot = new MetricsSnapshot();
+ List nodeList = coordinationService.getNodeList(CoordinationService.CategoryNode.MANIFESTS);
+ for (String node : nodeList) {
+ try {
+ AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node));
+ if (nodeData.getVersion() < 1) {
+ /*
+ * Ignore version '0' nodes that have not been
+ * "upgraded" since they don't carry enough data.
+ */
+ continue;
+ }
+ AutoIngestJob job = new AutoIngestJob(nodeData);
+ ProcessingStatus processingStatus = nodeData.getProcessingStatus();
+ switch (processingStatus) {
+ case PENDING:
+ case PROCESSING:
+ case DELETED:
+ /*
+ * These are not jobs we care about for metrics, so
+ * we will ignore them.
+ */
+ break;
+ case COMPLETED:
+ newMetricsSnapshot.addCompletedJobDate(job.getCompletedDate());
+ break;
+ default:
+ LOGGER.log(Level.SEVERE, "Unknown AutoIngestJobData.ProcessingStatus");
+ break;
+ }
+ } catch (InterruptedException ex) {
+ LOGGER.log(Level.SEVERE, String.format("Unexpected interrupt while retrieving coordination service node data for '%s'", node), ex);
+ } catch (AutoIngestJobNodeData.InvalidDataException ex) {
+ LOGGER.log(Level.SEVERE, String.format("Unable to use node data for '%s'", node), ex);
+ } catch (AutoIngestJob.AutoIngestJobException ex) {
+ LOGGER.log(Level.SEVERE, String.format("Failed to create a job for '%s'", node), ex);
+ }
+ }
+
+ return newMetricsSnapshot;
+
+ } catch (CoordinationServiceException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to get node list from coordination service", ex);
+ return new MetricsSnapshot();
+ }
+ }
+
+ /**
+ * Gets a new metrics snapshot. The jobs snapshot will also be updated in
+ * effect.
+ *
+ * @return The metrics snapshot.
+ */
+ public MetricsSnapshot getMetricsSnapshot() {
+ return queryCoordinationServiceForMetrics();
+ }
+
/**
* Bumps the priority of all pending ingest jobs for a specified case.
*
@@ -522,6 +593,32 @@ public final class AutoIngestMonitor extends Observable implements PropertyChang
}
+ /**
+ * A snapshot of metrics for an auto ingest cluster.
+ */
+ public static final class MetricsSnapshot {
+
+ private final List completedJobDates = new ArrayList<>();
+
+ /**
+ * Gets a list of completed job dates, formatted in milliseconds.
+ *
+ * @return The completed job dates, formatted in milliseconds.
+ */
+ List getCompletedJobDates() {
+ return new ArrayList<>(completedJobDates);
+ }
+
+ /**
+ * Adds a new date to the list of completed job dates.
+ *
+ * @param date The date to be added.
+ */
+ void addCompletedJobDate(Date date) {
+ completedJobDates.add(date.getTime());
+ }
+ }
+
/**
* Exception type thrown when there is an error completing an auto ingest
* monitor operation.
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties
index edac418672..5f335b1ba4 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties
@@ -1,4 +1,3 @@
-CTL_OpenAction=Open Case...
AutoIngestDashboard.lbCompleted.text=Completed Jobs
AutoIngestDashboard.lbRunning.text=Running Jobs
AutoIngestDashboard.lbPending.text=Pending Jobs
@@ -47,14 +46,10 @@ 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.cannotOpenCase=Cannot Open Case
-ReviewModeCasePanel.casePathNotFound=Case path not found
-ReviewModeCasePanel.caseIsLocked=Single-user case is locked.
DisplayLogDialog.cannotOpenLog=Unable to open the selected case log file
DisplayLogDialog.cannotFindLog=Unable to find the selected case log file
DisplayLogDialog.unableToShowLogFile=Unable to show log file
DisplayLogDialog.okay=Okay
-ReviewModeCasePanel.bnShowLog.text=&Show Log
CopyFilesPanel.lbFrom.text=From Source
CopyFilesPanel.lbTo.text=Destination Case
CopyFilesPanel.bnCopy.text=&Copy
@@ -128,8 +123,6 @@ CopyFilesPanel.cbThrottleNetwork.toolTipText=Select this box if a low-band
CopyFilesPanel.bnShowCurrentLog.text=Show &Log
CopyFilesPanel.bnShowCurrentLog.text=Show &Log
CopyFilesPanel.lbCaseName.text=Case Name
-CaseStatusIconCellRenderer.tooltiptext.ok=Images processed successfully
-CaseStatusIconCellRenderer.tooltiptext.warning=An error occurred or processing was canceled for at least one image - please check the log
OptionsCategory_Name_Case_Import=Case Import
OptionsCategory_Keywords_Case_Import=Case Import Settings
CaseImportPanel.validationErrMsg.MUdisabled=Multi user settings must be enabled and saved
@@ -165,11 +158,6 @@ SingleUserCaseImporter.FailedToComplete=Failed to complete processing of
SingleUserCaseImporter.CompletedBatch=Completed batch processing of
SingleUserCaseImporter.AbortingBatch=Aborting batch processing of
SingleUserCaseImporter.SourceImageMissing=. Source image missing for
-ReviewModeCasePanel.CaseHeaderText=Case
-ReviewModeCasePanel.CreatedTimeHeaderText=Created Time
-ReviewModeCasePanel.StatusIconHeaderText=Status
-ReviewModeCasePanel.OutputFolderHeaderText=Output Folder
-ReviewModeCasePanel.LastAccessedTimeHeaderText=Last Accessed Time
CopyFilesPanel.bnOptions.text=&Options
AutoIngestDashboard.lbServicesStatus.text=Services Status:
AutoIngestDashboard.tbServicesStatusMessage.text=Connecting...
@@ -231,15 +219,6 @@ FileExporterSettingsPanel.BrowseReportTooltip_1=Browse for the Reports Folder
FileExporterSettingsPanel.NewRuleTooltip_1=Clear the rule editor to begin a new rule
FileExporterSettingsPanel.DeleteTooltip_1=Delete the selected rule
FileExporterSettingsPanel.SaveTooltip_1=Save the current rule
-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 cases accessed in the last 10:
AutoIngestDashboard.refreshButton.toolTipText=Refresh displayed tables
AutoIngestDashboard.refreshButton.text=&Refresh
AutoIngestDashboard.jButton1.text=jButton1
@@ -247,6 +226,11 @@ AutoIngestDashboard.prioritizeJobButton.toolTipText=Move the selected job to the
AutoIngestDashboard.prioritizeJobButton.text=Prioritize &Job
AutoIngestDashboard.prioritizeCaseButton.toolTipText=Move all images associated with a case to top of Pending queue.
AutoIngestDashboard.prioritizeCaseButton.text=Prioritize &Case
+AutoIngestMetricsDialog.reportTextArea.text=
+AutoIngestDashboard.clusterMetricsButton.text=Cluster Metrics
+AutoIngestMetricsDialog.metricsButton.text=Get Metrics Since...
+AutoIngestMetricsDialog.closeButton.text=Close
+AutoIngestMetricsDialog.datePicker.toolTipText=Choose a date
ArchiveFilePanel.pathLabel.text=Browse for an archive file:
ArchiveFilePanel.browseButton.text=Browse
ArchiveFilePanel.pathTextField.text=
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseImportPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseImportPanel.java
index a7cd13af72..2e4866b010 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseImportPanel.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseImportPanel.java
@@ -672,7 +672,6 @@ public class CaseImportPanel extends javax.swing.JPanel implements ImportDoneCal
*/
private void enableStartButton() {
if (UserPreferences.getIsMultiUserModeEnabled()
- && AutoIngestUserPreferences.getJoinAutoModeCluster()
&& (! RuntimeProperties.runningWithGUI())
&& !tbCaseSource.getText().isEmpty()
&& !tbCaseDestination.getText().isEmpty()
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseStatusIconCellRenderer.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseStatusIconCellRenderer.java
deleted file mode 100755
index 0010cc90ee..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseStatusIconCellRenderer.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2015 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.awt.Component;
-import javax.swing.ImageIcon;
-import javax.swing.JTable;
-import static javax.swing.SwingConstants.CENTER;
-import org.openide.util.ImageUtilities;
-
-/**
- * A JTable cell renderer that represents an auto ingest alert file exists flag
- * as a center-aligned icon, and grays out the cell if the table is disabled.
- */
-class CaseStatusIconCellRenderer extends GrayableCellRenderer {
-
- private static final long serialVersionUID = 1L;
- static final ImageIcon checkedIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/tick.png", false));
- static final ImageIcon warningIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/warning16.png", false));
-
- @Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
- setHorizontalAlignment(CENTER);
- if ((value instanceof Boolean)) {
- if (true == (Boolean) value) {
- setIcon(warningIcon);
- setToolTipText(org.openide.util.NbBundle.getMessage(CaseStatusIconCellRenderer.class, "CaseStatusIconCellRenderer.tooltiptext.warning"));
- } else {
- setIcon(checkedIcon);
- setToolTipText(org.openide.util.NbBundle.getMessage(CaseStatusIconCellRenderer.class, "CaseStatusIconCellRenderer.tooltiptext.ok"));
- }
- }
- grayCellIfTableNotEnabled(table, isSelected);
-
- return this;
- }
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PathUtils.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PathUtils.java
index 18ce9709d5..a7d5675883 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PathUtils.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/PathUtils.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.CaseMetadata;
+import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
final class PathUtils {
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SingleUserCaseImporter.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SingleUserCaseImporter.java
index e04399d321..3a5c45632f 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SingleUserCaseImporter.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/SingleUserCaseImporter.java
@@ -47,6 +47,7 @@ import org.sleuthkit.autopsy.casemodule.SingleUserCaseConverter;
import org.sleuthkit.autopsy.casemodule.SingleUserCaseConverter.ImportCaseData;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
+import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
public class SingleUserCaseImporter implements Runnable {
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/layer.xml b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/layer.xml
index 56ad444eb0..ced44d8569 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/layer.xml
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/layer.xml
@@ -2,20 +2,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -23,19 +9,12 @@
-
-
-
-
-
-
-
-
+
-
+
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form
index 20c8c7a981..68002e8055 100755
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form
@@ -1,10 +1,6 @@