diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 0fa567cf00..25e17dd3eb 100755 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -237,6 +237,15 @@ + + + unit + + org.netbeans.libs.junit4 + + + + net.sf.sevenzipjbinding net.sf.sevenzipjbinding.impl @@ -366,7 +375,7 @@ 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..25b43a423a 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -8,7 +8,6 @@ CTL_OpenAction=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,14 +203,11 @@ 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= @@ -226,4 +217,4 @@ 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.openAutoIngestCaseLabel.text=Open Auto Ingest Case \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties index fd00f725e5..e212a125e9 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties @@ -7,7 +7,6 @@ CTL_OpenAction=\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,14 +181,15 @@ 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 diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index afcf23ed57..983c9420b2 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -90,6 +90,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; @@ -128,7 +129,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()); @@ -249,19 +249,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 @@ -346,7 +355,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; }; /** @@ -477,19 +493,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); } /** @@ -1167,6 +1210,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. * @@ -1484,24 +1554,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 } @@ -1523,8 +1606,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); } /** @@ -1645,7 +1728,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, @@ -1654,7 +1737,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) { /* @@ -1664,7 +1747,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(); @@ -1992,7 +2075,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(); } @@ -2063,7 +2146,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(); } } @@ -2174,7 +2257,7 @@ public class Case { Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage()))); } } finally { - shutDownTaskExecutor(executor); + ThreadUtils.shutDownTaskExecutor(executor); progressIndicator.finish(); } } @@ -2231,41 +2314,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/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/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/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/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/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/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/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java index 2a27be8297..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; 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/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/test/unit/src/org/sleuthkit/autopsy/ingest/IntestFileFiltersTest.java b/Core/test/unit/src/org/sleuthkit/autopsy/ingest/IntestFileFiltersTest.java new file mode 100755 index 0000000000..b952462de8 --- /dev/null +++ b/Core/test/unit/src/org/sleuthkit/autopsy/ingest/IntestFileFiltersTest.java @@ -0,0 +1,51 @@ +/* + * 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 org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class IntestFileFiltersTest { + + public IntestFileFiltersTest() { + } + + @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/Core/test/unit/src/org/sleuthkit/autopsy/testutils/UnitTestDspCallback.java b/Core/test/unit/src/org/sleuthkit/autopsy/testutils/UnitTestDspCallback.java new file mode 100755 index 0000000000..c6adb1f24c --- /dev/null +++ b/Core/test/unit/src/org/sleuthkit/autopsy/testutils/UnitTestDspCallback.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 UnitTestDspCallback 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. + */ + UnitTestDspCallback(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/unit/src/org/sleuthkit/autopsy/testutils/UnitTestDspProgressMonitor.java b/Core/test/unit/src/org/sleuthkit/autopsy/testutils/UnitTestDspProgressMonitor.java new file mode 100755 index 0000000000..1f856e6500 --- /dev/null +++ b/Core/test/unit/src/org/sleuthkit/autopsy/testutils/UnitTestDspProgressMonitor.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 UnitTestDspProgressMonitor 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) { + } + +}