diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 3e7cacb99a..2163af52e4 100755 --- a/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -115,3 +115,12 @@ AddImageVisualPanel4.crDbLabel.text=Finish or Add More Images AddImageVisualPanel4.addImgButton.text=Add Another Image AddImageVisualPanel3.titleLabel.text=Add image to ingest AddImageVisualPanel3.subtitleLabel.text=Image has been commited. You can configure and run ingest modules on the new image. +CasePropertiesForm.caseNumberLabel.text=Case Number: +CasePropertiesForm.examinerLabel.text=Examiner: +CasePropertiesForm.caseNumberTextField.text= +CasePropertiesForm.examinerTextField.text= +NewCaseVisualPanel2.caseNumberTextField.text= +NewCaseVisualPanel2.examinerLabel.text=Examiner: +NewCaseVisualPanel2.caseNumberLabel.text=Case Number: +NewCaseVisualPanel2.examinerTextField.text= +NewCaseVisualPanel2.optionalLabel.text=Optional: Set Case Number and Examiner diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Case.java b/Case/src/org/sleuthkit/autopsy/casemodule/Case.java index a38bc738c6..9d1548d483 100755 --- a/Case/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -62,6 +62,20 @@ public class Case { * The empty string ("") is used for no open case. */ public static final String CASE_NAME = "caseName"; + /** + * Property name that indicates the number of the current case has changed. + * Fired with the case number is changed. + * The value is an int: the number of the case. + * -1 is used for no case number set. + */ + public static final String CASE_NUMBER = "caseNumber"; + /** + * Property name that indicates the examiner of the current case has changed. + * Fired with the case examiner is changed. + * The value is a String: the name of the examiner. + * The empty string ("") is used for no examiner set. + */ + public static final String CASE_EXAMINER = "caseExaminer"; /** * Property name that indicates a new image has been added to the current * case. The new value is the newly-added instance of Image, and the old @@ -94,6 +108,8 @@ public class Case { private String name; + private int number; + private String examiner; private String configFilePath; private XMLCaseManagement xmlcm; private SleuthkitCase db; @@ -106,8 +122,10 @@ public class Case { /** * Constructor for the Case class */ - private Case(String name, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db) { + private Case(String name, int number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db) { this.name = name; + this.number = number; + this.examiner = examiner; this.configFilePath = configFilePath; this.xmlcm = xmlcm; this.db = db; @@ -165,20 +183,22 @@ public class Case { * * @param caseDir the base directory where the configuration file is saved * @param caseName the name of case + * @param caseNumber the case number + * @param examiner the examiner for this case */ - static void create(String caseDir, String caseName) throws Exception { + static void create(String caseDir, String caseName, int caseNumber, String examiner) throws Exception { Log.get(Case.class).log(Level.INFO, "Creating new case.\ncaseDir: {0}\ncaseName: {1}", new Object[] {caseDir, caseName}); String configFilePath = caseDir + File.separator + caseName + ".aut"; XMLCaseManagement xmlcm = new XMLCaseManagement(); - xmlcm.create(caseDir, caseName); // create a new XML config file + xmlcm.create(caseDir, caseName, examiner, caseNumber); // create a new XML config file xmlcm.writeFile(); String dbPath = caseDir + File.separator + "autopsy.db"; SleuthkitCase db = SleuthkitCase.newCase(dbPath); - Case newCase = new Case(caseName, configFilePath, xmlcm, db); + Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db); changeCase(newCase); } @@ -199,6 +219,8 @@ public class Case { xmlcm.writeFile(); // write any changes to the config file String caseName = xmlcm.getCaseName(); + int caseNumber = xmlcm.getCaseNumber(); + String examiner = xmlcm.getCaseExaminer(); // if the caseName is "", case / config file can't be opened if (caseName.equals("")) { throw new Exception("Case name is blank."); @@ -208,7 +230,7 @@ public class Case { String dbPath = caseDir + File.separator + "autopsy.db"; SleuthkitCase db = SleuthkitCase.openCase(dbPath); - Case openedCase = new Case(caseName, configFilePath, xmlcm, db); + Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db); changeCase(openedCase); @@ -307,6 +329,40 @@ public class Case { throw new Exception("Error while trying to update the case name.", e); } } + + /** + * Updates the case examiner + * + * @param oldExaminer the old examiner + * @param newExaminer the new examiner + */ + void updateExaminer(String oldExaminer, String newExaminer) throws Exception { + try { + xmlcm.setCaseExaminer(newExaminer); // set the examiner + examiner = newExaminer; + + pcs.firePropertyChange(CASE_EXAMINER, oldExaminer, newExaminer); + } catch (Exception e) { + throw new Exception("Error while trying to update the examiner.", e); + } + } + + /** + * Updates the case number + * + * @param oldCaseNumber the old case number + * @param newCaseNumber the new case number + */ + void updateCaseNumber(int oldCaseNumber, int newCaseNumber) throws Exception { + try { + xmlcm.setCaseNumber(newCaseNumber); // set the case number + number = newCaseNumber; + + pcs.firePropertyChange(CASE_NUMBER, oldCaseNumber, newCaseNumber); + } catch (Exception e) { + throw new Exception("Error while trying to update the case number.", e); + } + } // Not dealing with removing images for now. // /** @@ -400,6 +456,22 @@ public class Case { public String getName() { return name; } + + /** + * Gets the case number + * @return number + */ + public int getNumber() { + return number; + } + + /** + * Gets the Examiner name + * @return examiner + */ + public String getExaminer() { + return examiner; + } /** * Gets the case directory path diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java b/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java index 3e94393e0d..e0f5dc6707 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java @@ -35,6 +35,10 @@ interface CaseConfigFileInterface { // all the get and set methods public String getCaseName() throws Exception; // get the case name public void setCaseName(String caseName) throws Exception; // set the case name + public int getCaseNumber() throws Exception; // get the case number + public void setCaseNumber(int caseNumber) throws Exception; // set the case number + public String getCaseExaminer() throws Exception; // get the examiner + public void setCaseExaminer(String examiner) throws Exception; // set the examiner // public void getXXX(); // methods to get the case attributes // public void setXXX(); // methods to set the case attributes diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form index a37c13a2ba..ddbcd7e243 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form +++ b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form @@ -34,37 +34,51 @@ + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + @@ -85,13 +99,23 @@ + + + + + + + + + + - + @@ -105,7 +129,7 @@ - + @@ -250,5 +274,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java index 44c5dbc8b0..156afa4c83 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java @@ -78,6 +78,9 @@ class CasePropertiesForm extends javax.swing.JPanel{ CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map imgPaths) { initComponents(); caseNameTextField.setText(currentCase.getName()); + if(currentCase.getNumber() != -1) + caseNumberTextField.setText(String.valueOf(currentCase.getNumber())); + examinerTextField.setText(currentCase.getExaminer()); crDateTextField.setText(crDate); caseDirTextArea.setText(caseDir); @@ -178,6 +181,10 @@ class CasePropertiesForm extends javax.swing.JPanel{ jScrollPane2 = new javax.swing.JScrollPane(); caseDirTextArea = new javax.swing.JTextArea(); deleteCaseButton = new javax.swing.JButton(); + caseNumberLabel = new javax.swing.JLabel(); + examinerLabel = new javax.swing.JLabel(); + caseNumberTextField = new javax.swing.JTextField(); + examinerTextField = new javax.swing.JTextField(); jTextArea1.setColumns(20); jTextArea1.setRows(5); @@ -249,36 +256,56 @@ class CasePropertiesForm extends javax.swing.JPanel{ } }); + caseNumberLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNumberLabel.text")); // NOI18N + + examinerLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.examinerLabel.text")); // NOI18N + + caseNumberTextField.setEditable(false); + caseNumberTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNumberTextField.text")); // NOI18N + + examinerTextField.setEditable(false); + examinerTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.examinerTextField.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(casePropLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE) + .addComponent(genInfoLabel) + .addComponent(imgInfoLabel) + .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(casePropLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE) - .addComponent(genInfoLabel) + .addGap(181, 181, 181) + .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(caseNameLabel) + .addComponent(caseNumberLabel)) + .addGap(25, 25, 25) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(caseNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE) + .addComponent(caseNumberTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE))) + .addGroup(layout.createSequentialGroup() + .addComponent(examinerLabel) + .addGap(45, 45, 45) + .addComponent(examinerTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(caseDirLabel) - .addComponent(crDateLabel) - .addComponent(caseNameLabel)) + .addComponent(crDateLabel)) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE) - .addComponent(caseNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE) - .addComponent(crDateTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(updateCaseNameButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(deleteCaseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addComponent(imgInfoLabel) - .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE))) - .addGroup(layout.createSequentialGroup() - .addGap(191, 191, 191) - .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(crDateTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(updateCaseNameButton) + .addComponent(deleteCaseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( @@ -294,6 +321,14 @@ class CasePropertiesForm extends javax.swing.JPanel{ .addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(updateCaseNameButton)) .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)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(crDateLabel) .addComponent(crDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -310,7 +345,7 @@ class CasePropertiesForm extends javax.swing.JPanel{ .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(OKButton) - .addContainerGap(17, Short.MAX_VALUE)) + .addContainerGap()) ); }// //GEN-END:initComponents @@ -382,10 +417,14 @@ class CasePropertiesForm extends javax.swing.JPanel{ private javax.swing.JTextArea caseDirTextArea; private javax.swing.JLabel caseNameLabel; private javax.swing.JTextField caseNameTextField; + private javax.swing.JLabel caseNumberLabel; + private javax.swing.JTextField caseNumberTextField; private javax.swing.JLabel casePropLabel; private javax.swing.JLabel crDateLabel; private javax.swing.JTextField crDateTextField; private javax.swing.JButton deleteCaseButton; + private javax.swing.JLabel examinerLabel; + private javax.swing.JTextField examinerTextField; private javax.swing.JLabel genInfoLabel; private javax.swing.JTable imagesTable; private javax.swing.JScrollPane imagesTableScrollPane; diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form new file mode 100644 index 0000000000..dccd11860d --- /dev/null +++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.form @@ -0,0 +1,98 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java new file mode 100644 index 0000000000..515e1481c2 --- /dev/null +++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel2.java @@ -0,0 +1,138 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 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. + */ + +/* + * NewCaseVisualPanel2.java + * + * Created on Mar 7, 2012, 11:01:48 AM + */ +package org.sleuthkit.autopsy.casemodule; + +/** + * + * @author dfickling + */ +public class NewCaseVisualPanel2 extends javax.swing.JPanel { + + /** Creates new form NewCaseVisualPanel2 */ + public NewCaseVisualPanel2() { + initComponents(); + } + + /** + * Returns the name of the this panel. This name will be shown on the left + * panel of the "New Case" wizard panel. + * + * @return name the name of this panel + */ + @Override + public String getName() { + return "Additional Information"; + } + + /** 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() { + + 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.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.caseNumberTextField.text")); // NOI18N + + examinerTextField.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.examinerTextField.text")); // NOI18N + + caseNumberLabel.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.caseNumberLabel.text")); // NOI18N + + examinerLabel.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel2.class, "NewCaseVisualPanel2.examinerLabel.text")); // NOI18N + + optionalLabel.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N + 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)) + ); + }// //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 + + String getCaseNumber() { + return caseNumberTextField.getText(); + } + + String getExaminer() { + return examinerTextField.getText(); + } + + boolean validInputs() { + if(caseNumberTextField.getText().equals("")) + return true; + try { + Integer.valueOf(caseNumberTextField.getText()); + return true; + } catch (NumberFormatException ex) { + return false; + } + } + + + +} diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java index 84a35fc166..82cb933265 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.casemodule; import java.awt.Component; import java.awt.Dialog; +import java.io.File; import java.text.MessageFormat; import java.util.logging.Level; import java.util.logging.Logger; @@ -90,6 +91,9 @@ public final class NewCaseWizardAction extends CallableSystemAction { // if Cancel button is pressed if (isCancelled) { + String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); + if(createdDirectory != null) + Case.deleteCaseDirectory(new File(createdDirectory)); // if there's case opened, close the case if (Case.existsCurrentCase()) { // close the previous case if there's any @@ -107,7 +111,8 @@ public final class NewCaseWizardAction extends CallableSystemAction { private WizardDescriptor.Panel[] getPanels() { if (panels == null) { panels = new WizardDescriptor.Panel[]{ - new NewCaseWizardPanel1() + new NewCaseWizardPanel1(), + new NewCaseWizardPanel2() }; String[] steps = new String[panels.length]; for (int i = 0; i < panels.length; i++) { diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java index 814a5e3940..aac75c1113 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java @@ -50,7 +50,9 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel 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.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.openide.WizardDescriptor; +import org.openide.WizardValidationException; +import org.openide.util.HelpCtx; + +/** + * The "New Case" wizard panel with a component on it. This class represents + * data of wizard step. It defers creation and initialization of UI component + * of wizard panel into getComponent() method. + * + * @author jantonius + */ +class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel { + + /** + * The visual component that displays this panel. If you need to access the + * component from this class, just use getComponent(). + */ + private NewCaseVisualPanel2 component; + private Boolean isFinish = true; + private String caseName; + private String caseDir; + private String createdDirectory; + + /** + * Get the visual component for the panel. In this template, the component + * is kept separate. This can be more efficient: if the wizard is created + * but never displayed, or not all panels are displayed, it is better to + * create only those which really need to be visible. + * + * @return component the UI component of this wizard panel + */ + @Override + public NewCaseVisualPanel2 getComponent() { + if (component == null) { + component = new NewCaseVisualPanel2(); + } + return component; + } + + /** + * Help for this panel. When the panel is active, this is used as the help + * for the wizard dialog. + * + * @return HelpCtx.DEFAULT_HELP the help for this panel + */ + @Override + public HelpCtx getHelp() { + // Show no Help button for this panel: + return HelpCtx.DEFAULT_HELP; + // If you have context help: + // return new HelpCtx(SampleWizardPanel1.class); + } + + /** + * Tests whether the panel is finished. If the panel is valid, the "Finish" + * button will be enabled. + * + * @return boolean true if all the fields are correctly filled, false otherwise + */ + @Override + public boolean isValid() { + // If it is always OK to press Next or Finish, then: + return isFinish; + // If it depends on some condition (form filled out...), then: + // return someCondition(); + // and when this condition changes (last form field filled in...) then: + // fireChangeEvent(); + // and uncomment the complicated stuff below. + } + private final Set listeners = new HashSet(1); // or can use ChangeSupport in NB 6.0 + + /** + * Adds a listener to changes of the panel's validity. + * + * @param l the change listener to add + */ + @Override + public final void addChangeListener(ChangeListener l) { + synchronized (listeners) { + listeners.add(l); + } + } + + /** + * Removes a listener to changes of the panel's validity. + * + * @param l the change listener to move + */ + @Override + public final void removeChangeListener(ChangeListener l) { + synchronized (listeners) { + listeners.remove(l); + } + } + + /** + * This method is auto-generated. It seems that this method is used to listen + * to any change in this wizard panel. + */ + protected final void fireChangeEvent() { + Iterator it; + synchronized (listeners) { + it = new HashSet(listeners).iterator(); + } + ChangeEvent ev = new ChangeEvent(this); + while (it.hasNext()) { + it.next().stateChanged(ev); + } + } + + // You can use a settings object to keep track of state. Normally the + // settings object will be the WizardDescriptor, so you can use + // WizardDescriptor.getProperty & putProperty to store information entered + // by the user. + /** + * Provides the wizard panel with the current data--either the default data + * or already-modified settings, if the user used the previous and/or next + * buttons. This method can be called multiple times on one instance of + * WizardDescriptor.Panel. + * + * @param settings the setting to be read from + */ + @Override + public void readSettings(WizardDescriptor settings) { + caseName = (String) settings.getProperty("caseName"); + caseDir = (String) settings.getProperty("caseParentDir"); + createdDirectory = (String) settings.getProperty("createdDirectory"); + } + + /** + * Provides the wizard panel with the opportunity to update the settings + * with its current customized state. Rather than updating its settings + * with every change in the GUI, it should collect them, and then only save + * them when requested to by this method. This method can be called multiple + * times on one instance of WizardDescriptor.Panel. + * + * @param settings the setting to be stored to + */ + @Override + public void storeSettings(WizardDescriptor settings) { + } + + @Override + public void validate() throws WizardValidationException { + if (!getComponent().validInputs()) { + throw new WizardValidationException(this.getComponent(), "Please enter a valid case number", null); + } + + NewCaseVisualPanel2 currentComponent = getComponent(); + int caseNumber = -1; + if(!currentComponent.getCaseNumber().equals("")) { + caseNumber = Integer.valueOf(currentComponent.getCaseNumber()); + } + String examiner = currentComponent.getExaminer(); + try { + Case.create(createdDirectory, caseName, caseNumber, examiner); + } catch(Exception ex) { + throw new WizardValidationException(this.getComponent(), "Error creating case", null); + } + } +} diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java b/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java index 2f1dbbdde8..10dc3c2d10 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java @@ -99,8 +99,7 @@ class OpenRecentCasePanel extends javax.swing.JPanel { CueBannerPanel.closeOpenRecentCasesWindow(); } catch(Exception ex){ - // no need to show the error message to the user. - //TODO: But maybe put the error message in the log in the future. + Logger.getLogger(OpenRecentCasePanel.class.getName()).log(Level.WARNING, "Error: couldn't open case.", ex); } // Open the recent cases diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java b/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java index 3b8e85a215..f4e66b6537 100644 --- a/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java +++ b/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java @@ -51,6 +51,8 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ // general metadata about the case file final static String NAME = "Name"; + final static String NUMBER = "Number"; + final static String EXAMINER = "Examiner"; final static String CREATED_DATE_NAME = "CreatedDate"; final static String MODIFIED_DATE_NAME = "ModifiedDate"; final static String SCHEMA_VERSION_NAME = "SchemaVersion"; @@ -92,6 +94,8 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)"); private String caseDirPath; // case directory path private String caseName; // case name + private int caseNumber; // case number + private String examiner; // examiner name private String schemaVersion = "1.0"; private String autopsySavedVersion; @@ -139,6 +143,54 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ } } + /** + * Sets the case number on the XML configuration file + * + * @param givenCaseNumber the new case number to be set + */ + @Override + public void setCaseNumber(int givenCaseNumber) throws Exception { + // change this to change the xml file if needed + Element nameElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0); + nameElement.setTextContent(String.valueOf(givenCaseNumber)); + doc.normalize(); + + // edit the modified data + String newDate = dateFormat.format(new Date()); + Element rootEl = getRootElement(); + rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate); + + try { + writeFile(); + } catch (Exception ex) { + throw new Exception("Cannot update the case name in the XML config file.", ex); + } + } + + /** + * Sets the examiner on the XML configuration file + * + * @param givenExaminer the new examiner to be set + */ + @Override + public void setCaseExaminer(String givenExaminer) throws Exception { + // change this to change the xml file if needed + Element nameElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0); + nameElement.setTextContent(givenExaminer); + doc.normalize(); + + // edit the modified data + String newDate = dateFormat.format(new Date()); + Element rootEl = getRootElement(); + rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate); + + try { + writeFile(); + } catch (Exception ex) { + throw new Exception("Cannot update the case name in the XML config file.", ex); + } + } + /** * Sets the case name internally (on local variable in this class) * @@ -148,6 +200,24 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ caseName = givenCaseName; // change this to change the xml file if needed } + /** + * Sets the case number internally (on local variable in this class) + * + * @param givenCaseNumber the new case number + */ + private void setNumber(int givenCaseNumber){ + caseNumber = givenCaseNumber; // change this to change the xml file if needed + } + + /** + * Sets the examiner name internally (on local variable in this class) + * + * @param givenExaminer the new examiner + */ + private void setExaminer(String givenExaminer){ + examiner = givenExaminer; // change this to change the xml file if needed + } + /** * Gets the case Name from the document handler * @@ -164,6 +234,44 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ return result; } } + + /** + * Gets the case Number from the document handler + * + * @return caseNumber the case number from the document handler + */ + @Override + public int getCaseNumber(){ + if(doc == null){ + return 0; + } + else{ + Element numberElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0); + String result = "-1"; + if(numberElement != null) + result = numberElement.getTextContent(); + return Integer.valueOf(result); + } + } + + /** + * Gets the examiner from the document handler + * + * @return examiner the examiner from the document handler + */ + @Override + public String getCaseExaminer(){ + if(doc == null){ + return ""; + } + else{ + Element examinerElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0); + String result = ""; + if(examinerElement != null) + result = examinerElement.getTextContent(); + return result; + } + } /** * Gets the case directory path that's stored in this class @@ -540,12 +648,14 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ * @param parentPath the name of the parent of the case directory. * @param caseName the name of the config file to be located in the case directory */ - protected void create(String dirPath, String caseName) throws Exception { + protected void create(String dirPath, String caseName, String examiner, int caseNumber) throws Exception { clear(); // clear the previous data // set the case Name and Directory and the parent directory setCaseDirPath(dirPath); setName(caseName); + setExaminer(examiner); + setNumber(caseNumber); DocumentBuilder docBuilder; DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); @@ -587,6 +697,14 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ Element nameElement = doc.createElement(NAME); // ... nameElement.appendChild(doc.createTextNode(caseName)); caseElement.appendChild(nameElement); + + Element numberElement = doc.createElement(NUMBER); // ... + numberElement.appendChild(doc.createTextNode(String.valueOf(caseNumber))); + caseElement.appendChild(numberElement); + + Element examinerElement = doc.createElement(EXAMINER); // ... + examinerElement.appendChild(doc.createTextNode(examiner)); + caseElement.appendChild(examinerElement); Element exportElement = doc.createElement(EXPORT_FOLDER_NAME); // ... exportElement.appendChild(doc.createTextNode(EXPORT_FOLDER_RELPATH)); @@ -745,6 +863,8 @@ public class XMLCaseManagement implements CaseConfigFileInterface{ doc = null; caseDirPath = ""; caseName = ""; + caseNumber = -1; + examiner = ""; } /**