19 package org.sleuthkit.autopsy.casemodule;
22 import java.text.DateFormat;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.logging.Level;
26 import javax.swing.JOptionPane;
27 import javax.swing.JPanel;
28 import javax.xml.parsers.*;
29 import javax.xml.transform.*;
30 import javax.xml.transform.dom.*;
31 import javax.xml.transform.stream.*;
32 import org.openide.util.Exceptions;
33 import org.openide.util.NbBundle;
37 import org.xml.sax.SAXException;
49 class XMLCaseManagement
implements CaseConfigFileInterface {
51 final static String XSDFILE =
"CaseSchema.xsd";
52 final static String TOP_ROOT_NAME =
"AutopsyCase";
53 final static String CASE_ROOT_NAME =
"Case";
55 final static String NAME =
"Name";
56 final static String NUMBER =
"Number";
57 final static String EXAMINER =
"Examiner";
58 final static String CREATED_DATE_NAME =
"CreatedDate";
59 final static String MODIFIED_DATE_NAME =
"ModifiedDate";
60 final static String SCHEMA_VERSION_NAME =
"SchemaVersion";
61 final static String AUTOPSY_CRVERSION_NAME =
"AutopsyCreatedVersion";
62 final static String AUTOPSY_MVERSION_NAME =
"AutopsySavedVersion";
64 final static String LOG_FOLDER_NAME =
"LogFolder";
65 final static String LOG_FOLDER_RELPATH =
"Log";
66 final static String TEMP_FOLDER_NAME =
"TempFolder";
67 final static String TEMP_FOLDER_RELPATH =
"Temp";
68 final static String EXPORT_FOLDER_NAME =
"ExportFolder";
69 final static String EXPORT_FOLDER_RELPATH =
"Export";
70 final static String CACHE_FOLDER_NAME =
"CacheFolder";
71 final static String CACHE_FOLDER_RELPATH =
"Cache";
73 final static String RELATIVE_NAME =
"Relative";
75 final static String RELATIVE_TRUE =
"true";
76 final static String RELATIVE_FALSE =
"false";
80 private DateFormat dateFormat =
new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss (z)");
81 private String caseDirPath;
82 private String caseName;
83 private String caseNumber;
84 private String examiner;
85 private String schemaVersion =
"1.0";
86 private String autopsySavedVersion;
88 private JPanel caller;
89 private String className = this.getClass().toString();
90 private static final Logger logger = Logger.getLogger(XMLCaseManagement.class.getName());
97 autopsySavedVersion = System.getProperty(
"netbeans.buildnumber");
105 private void setCaseDirPath(String givenPath) {
106 caseDirPath = givenPath;
115 public void setCaseName(String givenCaseName)
throws CaseActionException {
117 Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
118 nameElement.setTextContent(givenCaseName);
122 String newDate = dateFormat.format(
new Date());
123 Element rootEl = getRootElement();
124 rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
136 public void setCaseNumber(String givenCaseNumber)
throws CaseActionException {
138 Element nameElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0);
139 nameElement.setTextContent(String.valueOf(givenCaseNumber));
143 String newDate = dateFormat.format(
new Date());
144 Element rootEl = getRootElement();
145 rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
157 public void setCaseExaminer(String givenExaminer)
throws CaseActionException {
159 Element nameElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0);
160 nameElement.setTextContent(givenExaminer);
164 String newDate = dateFormat.format(
new Date());
165 Element rootEl = getRootElement();
166 rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
177 private void setName(String givenCaseName) {
178 caseName = givenCaseName;
186 private void setNumber(String givenCaseNumber) {
187 caseNumber = givenCaseNumber;
195 private void setExaminer(String givenExaminer) {
196 examiner = givenExaminer;
205 public String getCaseName() {
209 Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
210 String result = nameElement.getTextContent();
221 public String getCaseNumber() {
225 Element numberElement = (Element) getCaseElement().getElementsByTagName(NUMBER).item(0);
226 String result =
"-1";
227 if (numberElement != null) {
228 result = numberElement.getTextContent();
240 public String getCaseExaminer() {
244 Element examinerElement = (Element) getCaseElement().getElementsByTagName(EXAMINER).item(0);
246 if (examinerElement != null) {
247 result = examinerElement.getTextContent();
258 public String getCaseDirectory() {
272 private Element getRootElement() {
274 return doc.getDocumentElement();
285 protected String getCreatedDate() {
287 Element crDateElement = (Element) getRootElement().getElementsByTagName(CREATED_DATE_NAME).item(0);
288 return crDateElement.getTextContent();
299 protected String getModifiedDate() {
301 Element mDateElement = (Element) getRootElement().getElementsByTagName(MODIFIED_DATE_NAME).item(0);
302 return mDateElement.getTextContent();
313 protected String getCreatedVersion() {
315 Element crVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_CRVERSION_NAME).item(0);
316 return crVerElement.getTextContent();
328 protected String getSavedVersion() {
330 Element mVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0);
331 return mVerElement.getTextContent();
342 protected String getSchemaVersion() {
344 Element schemaVerElement = (Element) getRootElement().getElementsByTagName(SCHEMA_VERSION_NAME).item(0);
345 return schemaVerElement.getTextContent();
356 private Element getCaseElement() {
358 return (Element) doc.getElementsByTagName(CASE_ROOT_NAME).item(0);
369 protected String getLogDir() {
371 Element logElement = (Element) getCaseElement().getElementsByTagName(LOG_FOLDER_NAME).item(0);
372 if (logElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
373 return caseDirPath + File.separator + logElement.getTextContent();
375 return logElement.getTextContent();
387 protected String getTempDir() {
389 Element tempElement = (Element) getCaseElement().getElementsByTagName(TEMP_FOLDER_NAME).item(0);
390 if (tempElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
391 return caseDirPath + File.separator + tempElement.getTextContent();
393 return tempElement.getTextContent();
405 protected String getExportDir() {
407 Element exportElement = (Element) getCaseElement().getElementsByTagName(EXPORT_FOLDER_NAME).item(0);
408 if (exportElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
409 return caseDirPath + File.separator + exportElement.getTextContent();
411 return exportElement.getTextContent();
423 protected String getCacheDir() {
425 Element cacheElement = (Element) getCaseElement().getElementsByTagName(CACHE_FOLDER_NAME).item(0);
426 if (cacheElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)) {
427 return caseDirPath + File.separator + cacheElement.getTextContent();
429 return cacheElement.getTextContent();
446 protected void create(String dirPath, String caseName, String examiner, String caseNumber)
throws CaseActionException {
450 setCaseDirPath(dirPath);
452 setExaminer(examiner);
453 setNumber(caseNumber);
454 DocumentBuilder docBuilder;
455 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
459 docBuilder = docFactory.newDocumentBuilder();
460 }
catch (ParserConfigurationException ex) {
462 throw new CaseActionException(
463 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.create.exception.msg"), ex);
466 doc = docBuilder.newDocument();
467 Element rootElement = doc.createElement(TOP_ROOT_NAME);
468 doc.appendChild(rootElement);
470 Element crDateElement = doc.createElement(CREATED_DATE_NAME);
471 crDateElement.appendChild(doc.createTextNode(dateFormat.format(
new Date())));
472 rootElement.appendChild(crDateElement);
474 Element mDateElement = doc.createElement(MODIFIED_DATE_NAME);
475 mDateElement.appendChild(doc.createTextNode(dateFormat.format(
new Date())));
476 rootElement.appendChild(mDateElement);
478 Element autVerElement = doc.createElement(AUTOPSY_CRVERSION_NAME);
479 autVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
480 rootElement.appendChild(autVerElement);
482 Element autSavedVerElement = doc.createElement(AUTOPSY_MVERSION_NAME);
483 autSavedVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
484 rootElement.appendChild(autSavedVerElement);
486 Element schVerElement = doc.createElement(SCHEMA_VERSION_NAME);
487 schVerElement.appendChild(doc.createTextNode(schemaVersion));
488 rootElement.appendChild(schVerElement);
490 Element caseElement = doc.createElement(CASE_ROOT_NAME);
491 rootElement.appendChild(caseElement);
493 Element nameElement = doc.createElement(NAME);
494 nameElement.appendChild(doc.createTextNode(caseName));
495 caseElement.appendChild(nameElement);
497 Element numberElement = doc.createElement(NUMBER);
498 numberElement.appendChild(doc.createTextNode(String.valueOf(caseNumber)));
499 caseElement.appendChild(numberElement);
501 Element examinerElement = doc.createElement(EXAMINER);
502 examinerElement.appendChild(doc.createTextNode(examiner));
503 caseElement.appendChild(examinerElement);
505 Element exportElement = doc.createElement(EXPORT_FOLDER_NAME);
506 exportElement.appendChild(doc.createTextNode(EXPORT_FOLDER_RELPATH));
507 exportElement.setAttribute(RELATIVE_NAME,
"true");
508 caseElement.appendChild(exportElement);
510 Element logElement = doc.createElement(LOG_FOLDER_NAME);
511 logElement.appendChild(doc.createTextNode(LOG_FOLDER_RELPATH));
512 logElement.setAttribute(RELATIVE_NAME,
"true");
513 caseElement.appendChild(logElement);
515 Element tempElement = doc.createElement(TEMP_FOLDER_NAME);
516 tempElement.appendChild(doc.createTextNode(TEMP_FOLDER_RELPATH));
517 tempElement.setAttribute(RELATIVE_NAME,
"true");
518 caseElement.appendChild(tempElement);
520 Element cacheElement = doc.createElement(CACHE_FOLDER_NAME);
521 cacheElement.appendChild(doc.createTextNode(CACHE_FOLDER_RELPATH));
522 cacheElement.setAttribute(RELATIVE_NAME,
"true");
523 caseElement.appendChild(cacheElement);
534 public void writeFile() throws CaseActionException {
535 if (doc == null || caseName.equals(
"")) {
536 throw new CaseActionException(
537 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.writeFile.exception.noCase.msg"));
541 Source source =
new DOMSource(doc);
544 StringWriter sw =
new StringWriter();
545 Result result =
new StreamResult(sw);
549 TransformerFactory tfactory = TransformerFactory.newInstance();
552 xformer = tfactory.newTransformer();
553 }
catch (TransformerConfigurationException ex) {
554 logger.log(Level.SEVERE,
"Could not setup tranformer and write case file");
555 throw new CaseActionException(
556 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
560 xformer.setOutputProperty(OutputKeys.INDENT,
"yes");
561 xformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount",
"2");
564 xformer.transform(source, result);
565 }
catch (TransformerException ex) {
566 logger.log(Level.SEVERE,
"Could not run tranformer and write case file");
567 throw new CaseActionException(
568 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
572 String xmlString = sw.toString();
573 File file =
new File(caseDirPath + File.separator + caseName +
".aut");
577 BufferedWriter bw =
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(file)));
581 }
catch (IOException ex) {
582 logger.log(Level.SEVERE,
"Error writing to case file");
583 throw new CaseActionException(
584 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.writeFile.exception.errWriteToFile.msg"), ex);
595 public void open(String conFilePath)
throws CaseActionException {
597 File file =
new File(conFilePath);
600 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
601 DocumentBuilder db = null;
603 db = dbf.newDocumentBuilder();
604 doc = db.parse(file);
605 }
catch (ParserConfigurationException ex) {
606 throw new CaseActionException(
607 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.open.exception.errReadXMLFile.msg",
609 }
catch (SAXException ex) {
610 throw new CaseActionException(
611 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.open.exception.errReadXMLFile.msg",
613 }
catch (IOException ex) {
614 throw new CaseActionException(
615 NbBundle.getMessage(
this.getClass(),
"XMLCaseManagement.open.exception.errReadXMLFile.msg",
620 doc.getDocumentElement().normalize();
621 doc.getDocumentElement().normalize();
623 if (!XMLUtil.xmlIsValid(doc, XMLCaseManagement.class, XSDFILE)) {
624 logger.log(Level.WARNING,
"Could not validate against [" + XSDFILE +
"], results may not accurate");
627 Element rootEl = doc.getDocumentElement();
628 String rootName = rootEl.getNodeName();
631 if (!rootName.equals(TOP_ROOT_NAME)) {
634 JOptionPane.showMessageDialog(caller,
635 NbBundle.getMessage(
this.getClass(),
636 "XMLCaseManagement.open.msgDlg.notAutCase.msg",
637 file.getName(), className),
638 NbBundle.getMessage(
this.getClass(),
639 "XMLCaseManagement.open.msgDlg.notAutCase.title"),
640 JOptionPane.ERROR_MESSAGE);
643 String createdVersion = getCreatedVersion();
646 if (!createdVersion.equals(autopsySavedVersion)) {
648 getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0).setTextContent(autopsySavedVersion);
652 String schemaVer = getSchemaVersion();
654 if (!schemaVer.equals(schemaVersion)) {
660 setCaseDirPath(file.getParent());
661 String fullFileName = file.getName();
662 String fileName = fullFileName.substring(0, fullFileName.lastIndexOf(
"."));
675 public void close() throws CaseActionException {
685 private void clear() {