From 77fdbcf6a45d81bb0c4e5697f3483279de44e4bd Mon Sep 17 00:00:00 2001
From: Brian Carrier <carrier@sleuthkit.org>
Date: Sat, 19 Oct 2013 12:26:55 -0400
Subject: [PATCH] made line endings more consistent
---
.gitattributes | 13 +
.../autopsy/report/FileReportDataTypes.java | 276 +-
.../autopsy/report/FileReportModule.java | 120 +-
.../autopsy/report/FileReportText.java | 276 +-
.../report/ReportWizardFileOptionsPanel.java | 192 +-
ExifParser/nbproject/project.xml | 60 +-
HashDatabase/nbproject/project.xml | 180 +-
KeywordSearch/nbproject/project.xml | 830 +++---
.../keywordsearch/TikaLanguageIdentifier.java | 120 +-
RecentActivity/nbproject/project.xml | 104 +-
ScalpelCarver/nbproject/project.xml | 44 +-
SevenZip/nbproject/project.xml | 96 +-
Testing/nbproject/project.xml | 138 +-
Timeline/nbproject/project.xml | 226 +-
.../sleuthkit/autopsy/timeline/Timeline.java | 2354 ++++++++---------
.../netbeans/core/startup/Bundle.properties | 4 +-
.../core/windows/view/ui/Bundle.properties | 10 +-
thunderbirdparser/nbproject/project.xml | 62 +-
18 files changed, 2559 insertions(+), 2546 deletions(-)
create mode 100644 .gitattributes
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..ea6aa14ebc
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,13 @@
+*.java text diff=java
+
+*.txt text
+*.sh text
+*.mf text
+*.xml text
+*.form text
+*.properties text
+*.html text diff=html
+*.dox text
+Doxyfile text
+
+*.py text diff=python
diff --git a/Core/src/org/sleuthkit/autopsy/report/FileReportDataTypes.java b/Core/src/org/sleuthkit/autopsy/report/FileReportDataTypes.java
index 8cc0b63049..c46c59ca7d 100755
--- a/Core/src/org/sleuthkit/autopsy/report/FileReportDataTypes.java
+++ b/Core/src/org/sleuthkit/autopsy/report/FileReportDataTypes.java
@@ -1,138 +1,138 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2013 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.report;
-
-import org.sleuthkit.datamodel.AbstractFile;
-import org.sleuthkit.datamodel.TskCoreException;
-import org.sleuthkit.datamodel.TskData;
-
-/**
- * Represents Column Headers for FileList Reports.
- *
- * Encapsulates functionality for getting column values from Files.
- *
- * @author jwallace
- */
-public enum FileReportDataTypes {
-
- NAME("Name") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getName();
- }
- },
- FILE_EXT("File Extension") {
- @Override
- public String getValue(AbstractFile file) {
- String name = file.getName();
- int extIndex = name.lastIndexOf(".");
- return (extIndex == -1 ? "" : name.substring(extIndex));
- }
- },
- FILE_TYPE("File Type") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getMetaTypeAsString();
- }
- },
- DELETED("Is Deleted") {
- @Override
- public String getValue(AbstractFile file) {
- if (file.getMetaFlagsAsString().equals(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.toString())) {
- return "yes";
- }
- return "";
- }
- },
- A_TIME("Last Accessed") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getAtimeAsDate();
- }
- },
- CR_TIME("File Created") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getCrtimeAsDate();
- }
- },
- M_TIME("Last Modified") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getMtimeAsDate();
- }
- },
- SIZE("Size") {
- @Override
- public String getValue(AbstractFile file) {
- return String.valueOf(file.getSize());
- }
- },
- ADDRESS("Address") {
- @Override
- public String getValue(AbstractFile file) {
- return String.valueOf(file.getMetaAddr());
- }
- },
- HASH_VALUE("Hash Value") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getMd5Hash();
- }
- },
- KNOWN_STATUS("Known Status") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getKnown().getName();
- }
- },
- PERMISSIONS("Permissions") {
- @Override
- public String getValue(AbstractFile file) {
- return file.getModesAsString();
- }
- },
- FULL_PATH("Full Path") {
- @Override
- public String getValue(AbstractFile file) {
- try {
- return file.getUniquePath();
- } catch (TskCoreException ex) {
- return "";
- }
- }
- };
-
- private String name;
-
- FileReportDataTypes(String name) {
- this.name = name;
- }
-
- public String getName() {
- return this.name;
- }
-
- /**
- * Get the value of the column from the file.
- *
- * @return
- */
- public abstract String getValue(AbstractFile file);
-}
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.report;
+
+import org.sleuthkit.datamodel.AbstractFile;
+import org.sleuthkit.datamodel.TskCoreException;
+import org.sleuthkit.datamodel.TskData;
+
+/**
+ * Represents Column Headers for FileList Reports.
+ *
+ * Encapsulates functionality for getting column values from Files.
+ *
+ * @author jwallace
+ */
+public enum FileReportDataTypes {
+
+ NAME("Name") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getName();
+ }
+ },
+ FILE_EXT("File Extension") {
+ @Override
+ public String getValue(AbstractFile file) {
+ String name = file.getName();
+ int extIndex = name.lastIndexOf(".");
+ return (extIndex == -1 ? "" : name.substring(extIndex));
+ }
+ },
+ FILE_TYPE("File Type") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getMetaTypeAsString();
+ }
+ },
+ DELETED("Is Deleted") {
+ @Override
+ public String getValue(AbstractFile file) {
+ if (file.getMetaFlagsAsString().equals(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.toString())) {
+ return "yes";
+ }
+ return "";
+ }
+ },
+ A_TIME("Last Accessed") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getAtimeAsDate();
+ }
+ },
+ CR_TIME("File Created") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getCrtimeAsDate();
+ }
+ },
+ M_TIME("Last Modified") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getMtimeAsDate();
+ }
+ },
+ SIZE("Size") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return String.valueOf(file.getSize());
+ }
+ },
+ ADDRESS("Address") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return String.valueOf(file.getMetaAddr());
+ }
+ },
+ HASH_VALUE("Hash Value") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getMd5Hash();
+ }
+ },
+ KNOWN_STATUS("Known Status") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getKnown().getName();
+ }
+ },
+ PERMISSIONS("Permissions") {
+ @Override
+ public String getValue(AbstractFile file) {
+ return file.getModesAsString();
+ }
+ },
+ FULL_PATH("Full Path") {
+ @Override
+ public String getValue(AbstractFile file) {
+ try {
+ return file.getUniquePath();
+ } catch (TskCoreException ex) {
+ return "";
+ }
+ }
+ };
+
+ private String name;
+
+ FileReportDataTypes(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Get the value of the column from the file.
+ *
+ * @return
+ */
+ public abstract String getValue(AbstractFile file);
+}
diff --git a/Core/src/org/sleuthkit/autopsy/report/FileReportModule.java b/Core/src/org/sleuthkit/autopsy/report/FileReportModule.java
index 344643b2ae..50c74a55c0 100755
--- a/Core/src/org/sleuthkit/autopsy/report/FileReportModule.java
+++ b/Core/src/org/sleuthkit/autopsy/report/FileReportModule.java
@@ -1,60 +1,60 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2013 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.report;
-
-import java.util.List;
-import org.sleuthkit.datamodel.AbstractFile;
-
-/**
- * A Report Module that reports information on files in a case.
- *
- * @author jwallace
- */
-public interface FileReportModule extends ReportModule {
- /**
- * Initialize the report which will be stored at the given path.
- * @param path
- */
- public void startReport(String path);
-
- /**
- * End the report.
- * Will be called after the entire report has been written.
- */
- public void endReport();
-
- /**
- * Start the file list table.
- * @param headers The columns that should be included in the table.
- */
- public void startTable(List<FileReportDataTypes> headers);
-
- /**
- * Add the given AbstractFile as a row in the table.
- * Guaranteed to be called between startTable and endTable.
- * @param toAdd the AbstractFile to be added.
- * @param columns the columns that should be included
- */
- public void addRow(AbstractFile toAdd, List<FileReportDataTypes> columns);
-
- /**
- * Close the table.
- */
- public void endTable();
-}
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.report;
+
+import java.util.List;
+import org.sleuthkit.datamodel.AbstractFile;
+
+/**
+ * A Report Module that reports information on files in a case.
+ *
+ * @author jwallace
+ */
+public interface FileReportModule extends ReportModule {
+ /**
+ * Initialize the report which will be stored at the given path.
+ * @param path
+ */
+ public void startReport(String path);
+
+ /**
+ * End the report.
+ * Will be called after the entire report has been written.
+ */
+ public void endReport();
+
+ /**
+ * Start the file list table.
+ * @param headers The columns that should be included in the table.
+ */
+ public void startTable(List<FileReportDataTypes> headers);
+
+ /**
+ * Add the given AbstractFile as a row in the table.
+ * Guaranteed to be called between startTable and endTable.
+ * @param toAdd the AbstractFile to be added.
+ * @param columns the columns that should be included
+ */
+ public void addRow(AbstractFile toAdd, List<FileReportDataTypes> columns);
+
+ /**
+ * Close the table.
+ */
+ public void endTable();
+}
diff --git a/Core/src/org/sleuthkit/autopsy/report/FileReportText.java b/Core/src/org/sleuthkit/autopsy/report/FileReportText.java
index 05192e6910..45ef9d736c 100755
--- a/Core/src/org/sleuthkit/autopsy/report/FileReportText.java
+++ b/Core/src/org/sleuthkit/autopsy/report/FileReportText.java
@@ -1,138 +1,138 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2013 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.report;
-
-import java.io.BufferedWriter;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.sleuthkit.datamodel.AbstractFile;
-
-/**
- * A Tab-delimited text report of the files in the case.
- *
- * @author jwallace
- */
-public class FileReportText implements FileReportModule {
- private static final Logger logger = Logger.getLogger(FileReportText.class.getName());
- private String reportPath;
- private Writer out;
- private static final String FILE_NAME = "file-report.txt";
-
- private static FileReportText instance;
-
- // Get the default implementation of this report
- public static synchronized FileReportText getDefault() {
- if (instance == null) {
- instance = new FileReportText();
- }
- return instance;
- }
-
- @Override
- public void startReport(String path) {
- this.reportPath = path + FILE_NAME;
- try {
- out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.reportPath)));
- } catch (IOException ex) {
- logger.log(Level.WARNING, "Failed to create report text file", ex);
- }
- }
-
- @Override
- public void endReport() {
- if (out != null) {
- try {
- out.close();
- } catch (IOException ex) {
- logger.log(Level.WARNING, "Could not close output writer when ending report.", ex);
- }
- }
- }
-
- private String getTabDelimitedList(List<String> list) {
- StringBuilder output = new StringBuilder();
- Iterator<String> it = list.iterator();
- while(it.hasNext()) {
- output.append(it.next()).append((it.hasNext() ? "\t" : System.lineSeparator()));
- }
- return output.toString();
- }
-
- @Override
- public void startTable(List<FileReportDataTypes> headers) {
- List<String> titles = new ArrayList<>();
- for(FileReportDataTypes col : headers) {
- titles.add(col.getName());
- }
- try {
- out.write(getTabDelimitedList(titles));
- } catch (IOException ex) {
- logger.log(Level.WARNING, "Error when writing headers to report file: {0}", ex);
- }
- }
-
- @Override
- public void addRow(AbstractFile toAdd, List<FileReportDataTypes> columns) {
- List<String> cells = new ArrayList<>();
- for(FileReportDataTypes type : columns) {
- cells.add(type.getValue(toAdd));
- }
- try {
- out.write(getTabDelimitedList(cells));
- } catch (IOException ex) {
- logger.log(Level.WARNING, "Error when writing row to report file: {0}", ex);
- }
- }
-
- @Override
- public void endTable() {
- try {
- out.write(System.lineSeparator());
- } catch (IOException ex) {
- logger.log(Level.WARNING, "Error when closing table: {0}", ex);
- }
- }
-
- @Override
- public String getName() {
- return "Files - Text";
- }
-
- @Override
- public String getDescription() {
- return "A tab delimited text file containing information about files in the case.";
- }
-
- @Override
- public String getExtension() {
- return ".txt";
- }
-
- @Override
- public String getFilePath() {
- return FILE_NAME;
- }
-}
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.report;
+
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.sleuthkit.datamodel.AbstractFile;
+
+/**
+ * A Tab-delimited text report of the files in the case.
+ *
+ * @author jwallace
+ */
+public class FileReportText implements FileReportModule {
+ private static final Logger logger = Logger.getLogger(FileReportText.class.getName());
+ private String reportPath;
+ private Writer out;
+ private static final String FILE_NAME = "file-report.txt";
+
+ private static FileReportText instance;
+
+ // Get the default implementation of this report
+ public static synchronized FileReportText getDefault() {
+ if (instance == null) {
+ instance = new FileReportText();
+ }
+ return instance;
+ }
+
+ @Override
+ public void startReport(String path) {
+ this.reportPath = path + FILE_NAME;
+ try {
+ out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.reportPath)));
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Failed to create report text file", ex);
+ }
+ }
+
+ @Override
+ public void endReport() {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Could not close output writer when ending report.", ex);
+ }
+ }
+ }
+
+ private String getTabDelimitedList(List<String> list) {
+ StringBuilder output = new StringBuilder();
+ Iterator<String> it = list.iterator();
+ while(it.hasNext()) {
+ output.append(it.next()).append((it.hasNext() ? "\t" : System.lineSeparator()));
+ }
+ return output.toString();
+ }
+
+ @Override
+ public void startTable(List<FileReportDataTypes> headers) {
+ List<String> titles = new ArrayList<>();
+ for(FileReportDataTypes col : headers) {
+ titles.add(col.getName());
+ }
+ try {
+ out.write(getTabDelimitedList(titles));
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Error when writing headers to report file: {0}", ex);
+ }
+ }
+
+ @Override
+ public void addRow(AbstractFile toAdd, List<FileReportDataTypes> columns) {
+ List<String> cells = new ArrayList<>();
+ for(FileReportDataTypes type : columns) {
+ cells.add(type.getValue(toAdd));
+ }
+ try {
+ out.write(getTabDelimitedList(cells));
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Error when writing row to report file: {0}", ex);
+ }
+ }
+
+ @Override
+ public void endTable() {
+ try {
+ out.write(System.lineSeparator());
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Error when closing table: {0}", ex);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "Files - Text";
+ }
+
+ @Override
+ public String getDescription() {
+ return "A tab delimited text file containing information about files in the case.";
+ }
+
+ @Override
+ public String getExtension() {
+ return ".txt";
+ }
+
+ @Override
+ public String getFilePath() {
+ return FILE_NAME;
+ }
+}
diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportWizardFileOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/report/ReportWizardFileOptionsPanel.java
index 2e09b0d5bd..f6fcb9afe1 100755
--- a/Core/src/org/sleuthkit/autopsy/report/ReportWizardFileOptionsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/report/ReportWizardFileOptionsPanel.java
@@ -1,96 +1,96 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2013 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.report;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import javax.swing.JButton;
-import javax.swing.event.ChangeListener;
-import org.openide.WizardDescriptor;
-import org.openide.util.HelpCtx;
-
-/**
- * Wizard panel that allows configuration of File Report options.
- *
- * @author jwallace
- */
-public class ReportWizardFileOptionsPanel implements WizardDescriptor.FinishablePanel<WizardDescriptor>{
- private WizardDescriptor wiz;
- private ReportWizardFileOptionsVisualPanel component;
- private JButton finishButton;
-
- ReportWizardFileOptionsPanel() {
- finishButton = new JButton("Finish");
- finishButton.setEnabled(false);
-
- finishButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- wiz.doFinishClick();
- };
- });
- }
-
- public void setFinish(boolean enable) {
- finishButton.setEnabled(enable);
- }
-
- @Override
- public boolean isFinishPanel() {
- return true;
- }
-
- @Override
- public ReportWizardFileOptionsVisualPanel getComponent() {
- if (component == null) {
- component = new ReportWizardFileOptionsVisualPanel(this);
- }
- return component;
- }
-
- @Override
- public HelpCtx getHelp() {
- return HelpCtx.DEFAULT_HELP;
- }
-
- @Override
- public void readSettings(WizardDescriptor data) {
- this.wiz = data;
- wiz.setOptions(new Object[] {WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, finishButton, WizardDescriptor.CANCEL_OPTION});
- }
-
- @Override
- public void storeSettings(WizardDescriptor data) {
- data.putProperty("fileReportOptions", getComponent().getFileReportOptions());
- }
-
- @Override
- public boolean isValid() {
- return true;
- }
-
- @Override
- public void addChangeListener(ChangeListener cl) {
- }
-
- @Override
- public void removeChangeListener(ChangeListener cl) {
- }
-
-}
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.report;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JButton;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+
+/**
+ * Wizard panel that allows configuration of File Report options.
+ *
+ * @author jwallace
+ */
+public class ReportWizardFileOptionsPanel implements WizardDescriptor.FinishablePanel<WizardDescriptor>{
+ private WizardDescriptor wiz;
+ private ReportWizardFileOptionsVisualPanel component;
+ private JButton finishButton;
+
+ ReportWizardFileOptionsPanel() {
+ finishButton = new JButton("Finish");
+ finishButton.setEnabled(false);
+
+ finishButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ wiz.doFinishClick();
+ };
+ });
+ }
+
+ public void setFinish(boolean enable) {
+ finishButton.setEnabled(enable);
+ }
+
+ @Override
+ public boolean isFinishPanel() {
+ return true;
+ }
+
+ @Override
+ public ReportWizardFileOptionsVisualPanel getComponent() {
+ if (component == null) {
+ component = new ReportWizardFileOptionsVisualPanel(this);
+ }
+ return component;
+ }
+
+ @Override
+ public HelpCtx getHelp() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public void readSettings(WizardDescriptor data) {
+ this.wiz = data;
+ wiz.setOptions(new Object[] {WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, finishButton, WizardDescriptor.CANCEL_OPTION});
+ }
+
+ @Override
+ public void storeSettings(WizardDescriptor data) {
+ data.putProperty("fileReportOptions", getComponent().getFileReportOptions());
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public void addChangeListener(ChangeListener cl) {
+ }
+
+ @Override
+ public void removeChangeListener(ChangeListener cl) {
+ }
+
+}
diff --git a/ExifParser/nbproject/project.xml b/ExifParser/nbproject/project.xml
index b5d8819e79..da91e0b898 100644
--- a/ExifParser/nbproject/project.xml
+++ b/ExifParser/nbproject/project.xml
@@ -1,30 +1,30 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.exifparser</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages/>
- <class-path-extension>
- <runtime-relative-path>ext/xmpcore.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/xmpcore.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/metadata-extractor-2.6.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/metadata-extractor-2.6.2.jar</binary-origin>
- </class-path-extension>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.exifparser</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ <class-path-extension>
+ <runtime-relative-path>ext/xmpcore.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/xmpcore.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/metadata-extractor-2.6.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/metadata-extractor-2.6.2.jar</binary-origin>
+ </class-path-extension>
+ </data>
+ </configuration>
+</project>
diff --git a/HashDatabase/nbproject/project.xml b/HashDatabase/nbproject/project.xml
index 3a743f01d0..b650bf0ecc 100644
--- a/HashDatabase/nbproject/project.xml
+++ b/HashDatabase/nbproject/project.xml
@@ -1,90 +1,90 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.hashdatabase</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.netbeans.api.progress</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.24.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.netbeans.modules.options.api</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.26.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.awt</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.31.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.dialogs</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.20.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.nodes</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.28.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>8.15.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util.lookup</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>8.15.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.windows</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>6.40.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages>
- <package>org.sleuthkit.autopsy.hashdatabase</package>
- </public-packages>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.hashdatabase</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.netbeans.api.progress</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.24.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.netbeans.modules.options.api</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.26.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.awt</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.31.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.dialogs</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.20.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.nodes</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.28.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.15.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util.lookup</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.15.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.windows</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.40.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages>
+ <package>org.sleuthkit.autopsy.hashdatabase</package>
+ </public-packages>
+ </data>
+ </configuration>
+</project>
diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml
index 215c6068ba..455c7745da 100644
--- a/KeywordSearch/nbproject/project.xml
+++ b/KeywordSearch/nbproject/project.xml
@@ -1,415 +1,415 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.netbeans.api.progress</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.24.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.netbeans.modules.javahelp</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>2.22.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.netbeans.modules.options.api</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.26.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.netbeans.modules.settings</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.31.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.awt</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.31.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.modules</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.23.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.nodes</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.21.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>8.15.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util.lookup</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>8.8.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.windows</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>6.40.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages>
- <package>org.apache.commons.lang</package>
- <package>org.apache.commons.lang.builder</package>
- <package>org.apache.commons.lang.enums</package>
- <package>org.apache.commons.lang.exception</package>
- <package>org.apache.commons.lang.math</package>
- <package>org.apache.commons.lang.mutable</package>
- <package>org.apache.commons.lang.text</package>
- <package>org.apache.commons.lang.time</package>
- <package>org.apache.commons.logging</package>
- <package>org.apache.commons.logging.impl</package>
- <package>org.apache.tika</package>
- <package>org.apache.tika.config</package>
- <package>org.apache.tika.detect</package>
- <package>org.apache.tika.exception</package>
- <package>org.apache.tika.extractor</package>
- <package>org.apache.tika.fork</package>
- <package>org.apache.tika.io</package>
- <package>org.apache.tika.language</package>
- <package>org.apache.tika.metadata</package>
- <package>org.apache.tika.mime</package>
- <package>org.apache.tika.parser</package>
- <package>org.apache.tika.parser.asm</package>
- <package>org.apache.tika.parser.audio</package>
- <package>org.apache.tika.parser.chm</package>
- <package>org.apache.tika.parser.chm.accessor</package>
- <package>org.apache.tika.parser.chm.assertion</package>
- <package>org.apache.tika.parser.chm.core</package>
- <package>org.apache.tika.parser.chm.exception</package>
- <package>org.apache.tika.parser.chm.lzx</package>
- <package>org.apache.tika.parser.crypto</package>
- <package>org.apache.tika.parser.dwg</package>
- <package>org.apache.tika.parser.epub</package>
- <package>org.apache.tika.parser.executable</package>
- <package>org.apache.tika.parser.external</package>
- <package>org.apache.tika.parser.feed</package>
- <package>org.apache.tika.parser.font</package>
- <package>org.apache.tika.parser.hdf</package>
- <package>org.apache.tika.parser.html</package>
- <package>org.apache.tika.parser.image</package>
- <package>org.apache.tika.parser.image.xmp</package>
- <package>org.apache.tika.parser.internal</package>
- <package>org.apache.tika.parser.iptc</package>
- <package>org.apache.tika.parser.iwork</package>
- <package>org.apache.tika.parser.jpeg</package>
- <package>org.apache.tika.parser.mail</package>
- <package>org.apache.tika.parser.mbox</package>
- <package>org.apache.tika.parser.microsoft</package>
- <package>org.apache.tika.parser.microsoft.ooxml</package>
- <package>org.apache.tika.parser.mp3</package>
- <package>org.apache.tika.parser.mp4</package>
- <package>org.apache.tika.parser.netcdf</package>
- <package>org.apache.tika.parser.odf</package>
- <package>org.apache.tika.parser.opendocument</package>
- <package>org.apache.tika.parser.pdf</package>
- <package>org.apache.tika.parser.pkg</package>
- <package>org.apache.tika.parser.prt</package>
- <package>org.apache.tika.parser.rtf</package>
- <package>org.apache.tika.parser.txt</package>
- <package>org.apache.tika.parser.video</package>
- <package>org.apache.tika.parser.xml</package>
- <package>org.apache.tika.sax</package>
- <package>org.apache.tika.sax.xpath</package>
- <package>org.apache.tika.utils</package>
- <package>org.sleuthkit.autopsy.keywordsearch</package>
- </public-packages>
- <class-path-extension>
- <runtime-relative-path>ext/metadata-extractor-2.4.0-beta-1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/metadata-extractor-2.4.0-beta-1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-io-2.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-io-2.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-lang-2.4.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-lang-2.4.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/log4j-1.2.17.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/log4j-1.2.17.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/jcl-over-slf4j-1.6.4.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/jcl-over-slf4j-1.6.4.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/asm-all-3.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/asm-all-3.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/qdox-1.12.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/qdox-1.12.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/org.apache.felix.scr.generator-1.1.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/org.apache.felix.scr.generator-1.1.2.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/bcmail-jdk15-1.45.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/bcmail-jdk15-1.45.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/vorbis-java-core-0.1-tests.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/vorbis-java-core-0.1-tests.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/tika-parsers-1.2-javadoc.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/tika-parsers-1.2-javadoc.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/log4j-over-slf4j-1.6.4.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/log4j-over-slf4j-1.6.4.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/vorbis-java-tika-0.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/vorbis-java-tika-0.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/isoparser-1.0-RC-1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/isoparser-1.0-RC-1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/httpcore-4.1.4.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/httpcore-4.1.4.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/tika-parsers-1.2-sources.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/tika-parsers-1.2-sources.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/aspectjrt-1.6.11.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/aspectjrt-1.6.11.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-compress-1.4.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-compress-1.4.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/poi-3.8.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/poi-3.8.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/tika-parsers-1.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/tika-parsers-1.2.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/apache-mime4j-core-0.7.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/apache-mime4j-core-0.7.2.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/rome-0.9.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/rome-0.9.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/httpclient-4.1.3.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/httpclient-4.1.3.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/icu4j-3.8.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/icu4j-3.8.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/juniversalchardet-1.0.3.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/juniversalchardet-1.0.3.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/pdfbox-1.7.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/pdfbox-1.7.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/jericho-html-3.3-sources.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/jericho-html-3.3-sources.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/jdom-1.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/jdom-1.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-logging-1.1.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-logging-1.1.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/tagsoup-1.2.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/tagsoup-1.2.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/fontbox-1.7.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/fontbox-1.7.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/poi-ooxml-3.8.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/poi-ooxml-3.8.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/boilerpipe-1.1.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/boilerpipe-1.1.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/org.osgi.compendium-4.0.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/org.osgi.compendium-4.0.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/slf4j-api-1.7.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/slf4j-api-1.7.2.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-lang-2.4-javadoc.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-lang-2.4-javadoc.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/jempbox-1.7.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/jempbox-1.7.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/jericho-html-3.3-javadoc.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/jericho-html-3.3-javadoc.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/wstx-asl-3.2.7.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/wstx-asl-3.2.7.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/netcdf-4.2-min.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/netcdf-4.2-min.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/solr-solrj-4.0.0-javadoc.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/solr-solrj-4.0.0-javadoc.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/xmlbeans-2.3.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/xmlbeans-2.3.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/httpmime-4.1.3.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/httpmime-4.1.3.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/org.osgi.core-4.0.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/org.osgi.core-4.0.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/org.apache.felix.scr.annotations-1.6.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/org.apache.felix.scr.annotations-1.6.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-logging-api-1.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-logging-api-1.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/xz-1.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/xz-1.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-codec-1.7.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-codec-1.7.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/tika-core-1.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/tika-core-1.2.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/zookeeper-3.3.6.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/zookeeper-3.3.6.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/dom4j-1.6.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/dom4j-1.6.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/poi-scratchpad-3.8.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/poi-scratchpad-3.8.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/poi-ooxml-schemas-3.8.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/poi-ooxml-schemas-3.8.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/bcprov-jdk15-1.45.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/bcprov-jdk15-1.45.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/jericho-html-3.3.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/jericho-html-3.3.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/solr-solrj-4.0.0.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/solr-solrj-4.0.0.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/commons-lang-2.4-sources.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/commons-lang-2.4-sources.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/solr-solrj-4.0.0-sources.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/solr-solrj-4.0.0-sources.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/apache-mime4j-dom-0.7.2.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/apache-mime4j-dom-0.7.2.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/geronimo-stax-api_1.0_spec-1.0.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/geronimo-stax-api_1.0_spec-1.0.1.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/asm-3.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/asm-3.1.jar</binary-origin>
- </class-path-extension>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.netbeans.api.progress</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.24.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.netbeans.modules.javahelp</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>2.22.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.netbeans.modules.options.api</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.26.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.netbeans.modules.settings</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.31.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.awt</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.31.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.modules</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.23.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.nodes</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.21.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.15.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util.lookup</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.8.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.windows</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.40.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages>
+ <package>org.apache.commons.lang</package>
+ <package>org.apache.commons.lang.builder</package>
+ <package>org.apache.commons.lang.enums</package>
+ <package>org.apache.commons.lang.exception</package>
+ <package>org.apache.commons.lang.math</package>
+ <package>org.apache.commons.lang.mutable</package>
+ <package>org.apache.commons.lang.text</package>
+ <package>org.apache.commons.lang.time</package>
+ <package>org.apache.commons.logging</package>
+ <package>org.apache.commons.logging.impl</package>
+ <package>org.apache.tika</package>
+ <package>org.apache.tika.config</package>
+ <package>org.apache.tika.detect</package>
+ <package>org.apache.tika.exception</package>
+ <package>org.apache.tika.extractor</package>
+ <package>org.apache.tika.fork</package>
+ <package>org.apache.tika.io</package>
+ <package>org.apache.tika.language</package>
+ <package>org.apache.tika.metadata</package>
+ <package>org.apache.tika.mime</package>
+ <package>org.apache.tika.parser</package>
+ <package>org.apache.tika.parser.asm</package>
+ <package>org.apache.tika.parser.audio</package>
+ <package>org.apache.tika.parser.chm</package>
+ <package>org.apache.tika.parser.chm.accessor</package>
+ <package>org.apache.tika.parser.chm.assertion</package>
+ <package>org.apache.tika.parser.chm.core</package>
+ <package>org.apache.tika.parser.chm.exception</package>
+ <package>org.apache.tika.parser.chm.lzx</package>
+ <package>org.apache.tika.parser.crypto</package>
+ <package>org.apache.tika.parser.dwg</package>
+ <package>org.apache.tika.parser.epub</package>
+ <package>org.apache.tika.parser.executable</package>
+ <package>org.apache.tika.parser.external</package>
+ <package>org.apache.tika.parser.feed</package>
+ <package>org.apache.tika.parser.font</package>
+ <package>org.apache.tika.parser.hdf</package>
+ <package>org.apache.tika.parser.html</package>
+ <package>org.apache.tika.parser.image</package>
+ <package>org.apache.tika.parser.image.xmp</package>
+ <package>org.apache.tika.parser.internal</package>
+ <package>org.apache.tika.parser.iptc</package>
+ <package>org.apache.tika.parser.iwork</package>
+ <package>org.apache.tika.parser.jpeg</package>
+ <package>org.apache.tika.parser.mail</package>
+ <package>org.apache.tika.parser.mbox</package>
+ <package>org.apache.tika.parser.microsoft</package>
+ <package>org.apache.tika.parser.microsoft.ooxml</package>
+ <package>org.apache.tika.parser.mp3</package>
+ <package>org.apache.tika.parser.mp4</package>
+ <package>org.apache.tika.parser.netcdf</package>
+ <package>org.apache.tika.parser.odf</package>
+ <package>org.apache.tika.parser.opendocument</package>
+ <package>org.apache.tika.parser.pdf</package>
+ <package>org.apache.tika.parser.pkg</package>
+ <package>org.apache.tika.parser.prt</package>
+ <package>org.apache.tika.parser.rtf</package>
+ <package>org.apache.tika.parser.txt</package>
+ <package>org.apache.tika.parser.video</package>
+ <package>org.apache.tika.parser.xml</package>
+ <package>org.apache.tika.sax</package>
+ <package>org.apache.tika.sax.xpath</package>
+ <package>org.apache.tika.utils</package>
+ <package>org.sleuthkit.autopsy.keywordsearch</package>
+ </public-packages>
+ <class-path-extension>
+ <runtime-relative-path>ext/metadata-extractor-2.4.0-beta-1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/metadata-extractor-2.4.0-beta-1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-io-2.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-io-2.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-lang-2.4.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-lang-2.4.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/log4j-1.2.17.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/log4j-1.2.17.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/jcl-over-slf4j-1.6.4.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/jcl-over-slf4j-1.6.4.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/asm-all-3.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/asm-all-3.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/qdox-1.12.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/qdox-1.12.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/org.apache.felix.scr.generator-1.1.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/org.apache.felix.scr.generator-1.1.2.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/bcmail-jdk15-1.45.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/bcmail-jdk15-1.45.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/vorbis-java-core-0.1-tests.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/vorbis-java-core-0.1-tests.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/tika-parsers-1.2-javadoc.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/tika-parsers-1.2-javadoc.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/log4j-over-slf4j-1.6.4.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/log4j-over-slf4j-1.6.4.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/vorbis-java-tika-0.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/vorbis-java-tika-0.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/isoparser-1.0-RC-1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/isoparser-1.0-RC-1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/httpcore-4.1.4.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/httpcore-4.1.4.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/tika-parsers-1.2-sources.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/tika-parsers-1.2-sources.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/aspectjrt-1.6.11.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/aspectjrt-1.6.11.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-compress-1.4.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-compress-1.4.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/poi-3.8.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/poi-3.8.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/tika-parsers-1.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/tika-parsers-1.2.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/apache-mime4j-core-0.7.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/apache-mime4j-core-0.7.2.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/rome-0.9.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/rome-0.9.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/httpclient-4.1.3.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/httpclient-4.1.3.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/icu4j-3.8.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/icu4j-3.8.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/juniversalchardet-1.0.3.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/juniversalchardet-1.0.3.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/pdfbox-1.7.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/pdfbox-1.7.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/jericho-html-3.3-sources.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/jericho-html-3.3-sources.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/jdom-1.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/jdom-1.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-logging-1.1.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-logging-1.1.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/tagsoup-1.2.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/tagsoup-1.2.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/fontbox-1.7.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/fontbox-1.7.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/poi-ooxml-3.8.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/poi-ooxml-3.8.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/boilerpipe-1.1.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/boilerpipe-1.1.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/org.osgi.compendium-4.0.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/org.osgi.compendium-4.0.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/slf4j-api-1.7.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/slf4j-api-1.7.2.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-lang-2.4-javadoc.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-lang-2.4-javadoc.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/jempbox-1.7.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/jempbox-1.7.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/jericho-html-3.3-javadoc.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/jericho-html-3.3-javadoc.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/wstx-asl-3.2.7.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/wstx-asl-3.2.7.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/netcdf-4.2-min.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/netcdf-4.2-min.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/solr-solrj-4.0.0-javadoc.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/solr-solrj-4.0.0-javadoc.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/xmlbeans-2.3.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/xmlbeans-2.3.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/httpmime-4.1.3.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/httpmime-4.1.3.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/org.osgi.core-4.0.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/org.osgi.core-4.0.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/org.apache.felix.scr.annotations-1.6.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/org.apache.felix.scr.annotations-1.6.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-logging-api-1.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-logging-api-1.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/xz-1.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/xz-1.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-codec-1.7.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-codec-1.7.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/tika-core-1.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/tika-core-1.2.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/zookeeper-3.3.6.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/zookeeper-3.3.6.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/dom4j-1.6.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/dom4j-1.6.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/poi-scratchpad-3.8.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/poi-scratchpad-3.8.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/poi-ooxml-schemas-3.8.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/poi-ooxml-schemas-3.8.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/bcprov-jdk15-1.45.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/bcprov-jdk15-1.45.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/jericho-html-3.3.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/jericho-html-3.3.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/solr-solrj-4.0.0.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/solr-solrj-4.0.0.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/commons-lang-2.4-sources.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/commons-lang-2.4-sources.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/solr-solrj-4.0.0-sources.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/solr-solrj-4.0.0-sources.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/apache-mime4j-dom-0.7.2.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/apache-mime4j-dom-0.7.2.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/geronimo-stax-api_1.0_spec-1.0.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/geronimo-stax-api_1.0_spec-1.0.1.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/asm-3.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/asm-3.1.jar</binary-origin>
+ </class-path-extension>
+ </data>
+ </configuration>
+</project>
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaLanguageIdentifier.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaLanguageIdentifier.java
index 607daeb9a8..7d42399f89 100755
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaLanguageIdentifier.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaLanguageIdentifier.java
@@ -1,61 +1,61 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2013 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.keywordsearch;
-
-import java.util.logging.Level;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.datamodel.AbstractFile;
-import org.sleuthkit.datamodel.BlackboardArtifact;
-import org.sleuthkit.datamodel.BlackboardAttribute;
-import org.sleuthkit.datamodel.TskCoreException;
-
-/**
- * TextLanguageIdentifier implementation based on a wrapped Tike
- * LanguageIdentifier
- */
-public class TikaLanguageIdentifier implements TextLanguageIdentifier {
-
- private static final Logger logger = Logger.getLogger(TikaLanguageIdentifier.class.getName());
- private static final int MIN_STRING_LENGTH = 1000;
-
- @Override
- public void addLanguageToBlackBoard(String extracted, AbstractFile sourceFile) {
- if (extracted.length() > MIN_STRING_LENGTH) {
- org.apache.tika.language.LanguageIdentifier li = new org.apache.tika.language.LanguageIdentifier(extracted);
-
- //logger.log(Level.INFO, sourceFile.getName() + " detected language: " + li.getLanguage()
- // + " with " + ((li.isReasonablyCertain()) ? "HIGH" : "LOW") + " confidence");
-
- BlackboardArtifact genInfo;
- try {
- genInfo = sourceFile.getGenInfoArtifact();
-
- BlackboardAttribute textLang = new BlackboardAttribute(
- BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT_LANGUAGE.getTypeID(),
- KeywordSearchIngestModule.MODULE_NAME, li.getLanguage());
-
- genInfo.addAttribute(textLang);
-
- } catch (TskCoreException ex) {
- logger.log(Level.WARNING, "failed to add TSK_TEXT_LANGUAGE attribute to TSK_GEN_INFO artifact for file: " + sourceFile.getName(), ex);
- }
-
- }
- }
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.keywordsearch;
+
+import java.util.logging.Level;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.datamodel.AbstractFile;
+import org.sleuthkit.datamodel.BlackboardArtifact;
+import org.sleuthkit.datamodel.BlackboardAttribute;
+import org.sleuthkit.datamodel.TskCoreException;
+
+/**
+ * TextLanguageIdentifier implementation based on a wrapped Tike
+ * LanguageIdentifier
+ */
+public class TikaLanguageIdentifier implements TextLanguageIdentifier {
+
+ private static final Logger logger = Logger.getLogger(TikaLanguageIdentifier.class.getName());
+ private static final int MIN_STRING_LENGTH = 1000;
+
+ @Override
+ public void addLanguageToBlackBoard(String extracted, AbstractFile sourceFile) {
+ if (extracted.length() > MIN_STRING_LENGTH) {
+ org.apache.tika.language.LanguageIdentifier li = new org.apache.tika.language.LanguageIdentifier(extracted);
+
+ //logger.log(Level.INFO, sourceFile.getName() + " detected language: " + li.getLanguage()
+ // + " with " + ((li.isReasonablyCertain()) ? "HIGH" : "LOW") + " confidence");
+
+ BlackboardArtifact genInfo;
+ try {
+ genInfo = sourceFile.getGenInfoArtifact();
+
+ BlackboardAttribute textLang = new BlackboardAttribute(
+ BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT_LANGUAGE.getTypeID(),
+ KeywordSearchIngestModule.MODULE_NAME, li.getLanguage());
+
+ genInfo.addAttribute(textLang);
+
+ } catch (TskCoreException ex) {
+ logger.log(Level.WARNING, "failed to add TSK_TEXT_LANGUAGE attribute to TSK_GEN_INFO artifact for file: " + sourceFile.getName(), ex);
+ }
+
+ }
+ }
}
\ No newline at end of file
diff --git a/RecentActivity/nbproject/project.xml b/RecentActivity/nbproject/project.xml
index 8da413bbc9..78526a084c 100644
--- a/RecentActivity/nbproject/project.xml
+++ b/RecentActivity/nbproject/project.xml
@@ -1,52 +1,52 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.recentactivity</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.openide.awt</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.46.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.modules</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.23.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.nodes</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.21.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages>
- <package>org.sleuthkit.autopsy.recentactivity</package>
- </public-packages>
- <class-path-extension>
- <runtime-relative-path>ext/gson-2.1.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/gson-2.1.jar</binary-origin>
- </class-path-extension>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.recentactivity</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.openide.awt</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.46.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.modules</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.23.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.nodes</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.21.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages>
+ <package>org.sleuthkit.autopsy.recentactivity</package>
+ </public-packages>
+ <class-path-extension>
+ <runtime-relative-path>ext/gson-2.1.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/gson-2.1.jar</binary-origin>
+ </class-path-extension>
+ </data>
+ </configuration>
+</project>
diff --git a/ScalpelCarver/nbproject/project.xml b/ScalpelCarver/nbproject/project.xml
index d0f610f870..09a3bb2f87 100644
--- a/ScalpelCarver/nbproject/project.xml
+++ b/ScalpelCarver/nbproject/project.xml
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.scalpel</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages/>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.scalpel</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ </data>
+ </configuration>
+</project>
diff --git a/SevenZip/nbproject/project.xml b/SevenZip/nbproject/project.xml
index 2a2f30e675..ef6d94d674 100644
--- a/SevenZip/nbproject/project.xml
+++ b/SevenZip/nbproject/project.xml
@@ -1,48 +1,48 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.sevenzip</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.netbeans.api.progress</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.32.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>3</release-version>
- <specification-version>1.1</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages/>
- <class-path-extension>
- <runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
- </class-path-extension>
- <class-path-extension>
- <runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
- <binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
- </class-path-extension>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.sevenzip</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.netbeans.api.progress</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.32.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>3</release-version>
+ <specification-version>1.1</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ <class-path-extension>
+ <runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
+ <binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
+ </class-path-extension>
+ </data>
+ </configuration>
+</project>
diff --git a/Testing/nbproject/project.xml b/Testing/nbproject/project.xml
index e9621dd78b..f685034d4a 100644
--- a/Testing/nbproject/project.xml
+++ b/Testing/nbproject/project.xml
@@ -1,69 +1,69 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.testing</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>5</release-version>
- <specification-version>3.2</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <test-dependencies>
- <test-type>
- <name>qa-functional</name>
- <test-dependency>
- <code-name-base>org.netbeans.libs.junit4</code-name-base>
- <compile-dependency/>
- </test-dependency>
- <test-dependency>
- <code-name-base>org.netbeans.modules.jellytools.java</code-name-base>
- <compile-dependency/>
- </test-dependency>
- <test-dependency>
- <code-name-base>org.netbeans.modules.jellytools.platform</code-name-base>
- <compile-dependency/>
- </test-dependency>
- <test-dependency>
- <code-name-base>org.netbeans.modules.jemmy</code-name-base>
- <compile-dependency/>
- </test-dependency>
- <test-dependency>
- <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
- <recursive/>
- <compile-dependency/>
- </test-dependency>
- </test-type>
- <test-type>
- <name>unit</name>
- <test-dependency>
- <code-name-base>org.netbeans.libs.junit4</code-name-base>
- <compile-dependency/>
- </test-dependency>
- <test-dependency>
- <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
- <recursive/>
- <compile-dependency/>
- </test-dependency>
- </test-type>
- </test-dependencies>
- <public-packages/>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.testing</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>5</release-version>
+ <specification-version>3.2</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <test-dependencies>
+ <test-type>
+ <name>qa-functional</name>
+ <test-dependency>
+ <code-name-base>org.netbeans.libs.junit4</code-name-base>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+ <code-name-base>org.netbeans.modules.jellytools.java</code-name-base>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+ <code-name-base>org.netbeans.modules.jellytools.platform</code-name-base>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+ <code-name-base>org.netbeans.modules.jemmy</code-name-base>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+ <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
+ <recursive/>
+ <compile-dependency/>
+ </test-dependency>
+ </test-type>
+ <test-type>
+ <name>unit</name>
+ <test-dependency>
+ <code-name-base>org.netbeans.libs.junit4</code-name-base>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+ <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
+ <recursive/>
+ <compile-dependency/>
+ </test-dependency>
+ </test-type>
+ </test-dependencies>
+ <public-packages/>
+ </data>
+ </configuration>
+</project>
diff --git a/Timeline/nbproject/project.xml b/Timeline/nbproject/project.xml
index f21e7f63ba..352e0fd55f 100644
--- a/Timeline/nbproject/project.xml
+++ b/Timeline/nbproject/project.xml
@@ -1,113 +1,113 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.timeline</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.netbeans.api.progress</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.32.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.netbeans.modules.settings</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>1</release-version>
- <specification-version>1.35.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.actions</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>6.26.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.awt</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.46.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.dialogs</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.25.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.modules</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.32.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.nodes</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.28.1</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>8.25.2</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util.lookup</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>8.15.2</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.windows</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>6.55.2</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>3</release-version>
- <specification-version>1.1</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages/>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.timeline</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.netbeans.api.progress</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.32.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.netbeans.modules.settings</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.35.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.actions</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.26.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.awt</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.46.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.dialogs</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.25.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.modules</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.32.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.nodes</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.28.1</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.25.2</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util.lookup</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.15.2</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.windows</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.55.2</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.corelibs</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>3</release-version>
+ <specification-version>1.1</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ </data>
+ </configuration>
+</project>
diff --git a/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java b/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java
index 9f027c53ce..3468ab6fef 100644
--- a/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java
+++ b/Timeline/src/org/sleuthkit/autopsy/timeline/Timeline.java
@@ -1,1177 +1,1177 @@
-/*
- * Autopsy Forensic Browser
- *
- * Copyright 2013 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.timeline;
-
-import java.awt.Component;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.EventQueue;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.BufferedWriter;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.text.DateFormat;
-import java.text.DateFormatSymbols;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Scanner;
-import java.util.Stack;
-import java.util.logging.Level;
-import javafx.application.Platform;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import javafx.embed.swing.JFXPanel;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.geometry.Pos;
-import javafx.scene.Group;
-import javafx.scene.Scene;
-import javafx.scene.chart.BarChart;
-import javafx.scene.chart.CategoryAxis;
-import javafx.scene.chart.NumberAxis;
-import javafx.scene.control.Button;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.Label;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.input.MouseButton;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.SwingUtilities;
-import org.netbeans.api.progress.ProgressHandle;
-import org.netbeans.api.progress.ProgressHandleFactory;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.awt.ActionReferences;
-import org.openide.awt.ActionRegistration;
-import org.openide.modules.InstalledFileLocator;
-import org.openide.modules.ModuleInstall;
-import org.openide.nodes.Children;
-import org.openide.nodes.Node;
-import org.openide.util.HelpCtx;
-import org.openide.util.NbBundle;
-import org.openide.util.actions.CallableSystemAction;
-import org.openide.util.actions.Presenter;
-import org.openide.util.lookup.Lookups;
-import org.openide.windows.WindowManager;
-import org.sleuthkit.autopsy.casemodule.Case;
-import org.sleuthkit.autopsy.core.Installer;
-import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
-import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.coreutils.PlatformUtil;
-import org.sleuthkit.autopsy.datamodel.FilterNodeLeaf;
-import org.sleuthkit.autopsy.datamodel.DirectoryNode;
-import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
-import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
-import org.sleuthkit.autopsy.datamodel.FileNode;
-import org.sleuthkit.autopsy.ingest.IngestManager;
-import org.sleuthkit.autopsy.coreutils.ExecUtil;
-import org.sleuthkit.datamodel.AbstractFile;
-import org.sleuthkit.datamodel.SleuthkitCase;
-import org.sleuthkit.datamodel.TskCoreException;
-
-@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
-@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy = false)
-@ActionReferences(value = {
- @ActionReference(path = "Menu/Tools", position = 100)})
-@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
-/**
- * The Timeline Action entry point. Collects data and pushes data to javafx
- * widgets
- *
- */
-public class Timeline extends CallableSystemAction implements Presenter.Toolbar, PropertyChangeListener {
-
- private static final Logger logger = Logger.getLogger(Timeline.class.getName());
- private final java.io.File macRoot = InstalledFileLocator.getDefault().locate("mactime", Timeline.class.getPackage().getName(), false);
- private TimelineFrame mainFrame; //frame for holding all the elements
- private Group fxGroupCharts; //Orders the charts
- private Scene fxSceneCharts; //Displays the charts
- private HBox fxHBoxCharts; //Holds the navigation buttons in horiztonal fashion.
- private VBox fxVBox; //Holds the JavaFX Elements in vertical fashion.
- private JFXPanel fxPanelCharts; //FX panel to hold the group
- private BarChart<String, Number> fxChartEvents; //Yearly/Monthly events - Bar chart
- private ScrollPane fxScrollEvents; //Scroll Panes for dealing with oversized an oversized chart
- private static final int FRAME_HEIGHT = 700; //Sizing constants
- private static final int FRAME_WIDTH = 1200;
- private Button fxZoomOutButton; //Navigation buttons
- private ComboBox<String> fxDropdownSelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events.
- private final Stack<BarChart<String, Number>> fxStackPrevCharts = new Stack<BarChart<String, Number>>(); //Stack for storing drill-up information.
- private BarChart<String, Number> fxChartTopLevel; //the topmost chart, used for resetting to default view.
- private DataResultPanel dataResultPanel;
- private DataContentPanel dataContentPanel;
- private ProgressHandle progress;
- private java.io.File moduleDir;
- private String mactimeFileName;
- private List<YearEpoch> data;
- private boolean listeningToAddImage = false;
- private long lastObjectId = -1;
- private TimelineProgressDialog progressDialog;
- private EventHandler<MouseEvent> fxMouseEnteredListener;
- private EventHandler<MouseEvent> fxMouseExitedListener;
- private SleuthkitCase skCase;
- private boolean fxInited = false;
-
- public Timeline() {
- super();
-
- fxInited = Installer.isJavaFxInited();
-
- }
-
- //Swing components and JavafX components don't play super well together
- //Swing components need to be initialized first, in the swing specific thread
- //Next, the javafx components may be initialized.
- private void customize() {
-
- //listeners
- fxMouseEnteredListener = new EventHandler<MouseEvent>() {
- @Override
- public void handle(MouseEvent e) {
- fxPanelCharts.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- }
- };
- fxMouseExitedListener = new EventHandler<MouseEvent>() {
- @Override
- public void handle(MouseEvent e) {
- fxPanelCharts.setCursor(null);
- }
- };
-
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- //Making the main frame *
-
- mainFrame = new TimelineFrame();
- mainFrame.setFrameName(Case.getCurrentCase().getName() + " - Autopsy Timeline (Beta)");
-
- //use the same icon on jframe as main application
- mainFrame.setIconImage(WindowManager.getDefault().getMainWindow().getIconImage());
- mainFrame.setFrameSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); //(Width, Height)
-
-
- dataContentPanel = DataContentPanel.createInstance();
- //dataContentPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
- //dataContentPanel.setPreferredSize(new Dimension(FRAME_WIDTH, (int) (FRAME_HEIGHT * 0.4)));
-
- dataResultPanel = DataResultPanel.createInstance("Timeline Results", "", Node.EMPTY, 0, dataContentPanel);
- dataResultPanel.setContentViewer(dataContentPanel);
- //dataResultPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
- //dataResultPanel.setPreferredSize(new Dimension((int)(FRAME_WIDTH * 0.5), (int) (FRAME_HEIGHT * 0.5)));
- logger.log(Level.INFO, "Successfully created viewers");
-
- mainFrame.setBottomLeftPanel(dataResultPanel);
- mainFrame.setBottomRightPanel(dataContentPanel);
-
- runJavaFxThread();
- }
- });
-
-
- }
-
- private void runJavaFxThread() {
- //JavaFX thread
- //JavaFX components MUST be run in the JavaFX thread, otherwise massive amounts of exceptions will be thrown and caught. Liable to freeze up and crash.
- //Components can be declared whenever, but initialization and manipulation must take place here.
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
- try {
- // start the progress bar
- progress = ProgressHandleFactory.createHandle("Creating timeline . . .");
- progress.start();
-
- fxChartEvents = null; //important to reset old data
- fxPanelCharts = new JFXPanel();
- fxGroupCharts = new Group();
- fxSceneCharts = new Scene(fxGroupCharts, FRAME_WIDTH, FRAME_HEIGHT * 0.6); //Width, Height
- fxVBox = new VBox(5);
- fxVBox.setAlignment(Pos.BOTTOM_CENTER);
- fxHBoxCharts = new HBox(10);
- fxHBoxCharts.setAlignment(Pos.BOTTOM_CENTER);
-
- //Initializing default values for the scroll pane
- fxScrollEvents = new ScrollPane();
- fxScrollEvents.setPrefSize(FRAME_WIDTH, FRAME_HEIGHT * 0.6); //Width, Height
- fxScrollEvents.setContent(null); //Needs some content, otherwise it crashes
-
- // set up moduleDir
- moduleDir = new java.io.File(Case.getCurrentCase().getModulesOutputDirAbsPath() + java.io.File.separator + "timeline");
- if (!moduleDir.exists()) {
- moduleDir.mkdir();
- }
-
- int currentProgress = 0;
- java.io.File mactimeFile = new java.io.File(moduleDir, mactimeFileName);
- if (!mactimeFile.exists()) {
- progressDialog.setProgressTotal(3); //total 3 units
- logger.log(Level.INFO, "Creating body file");
- progressDialog.updateProgressBar("Generating Bodyfile");
- String bodyFilePath = makeBodyFile();
- progressDialog.updateProgressBar(++currentProgress);
- logger.log(Level.INFO, "Creating mactime file: " + mactimeFile.getAbsolutePath());
- progressDialog.updateProgressBar("Generating Mactime");
- makeMacTime(bodyFilePath);
- progressDialog.updateProgressBar(++currentProgress);
- data = null;
- } else {
- progressDialog.setProgressTotal(1); //total 1 units
- logger.log(Level.INFO, "Mactime file already exists; parsing that: " + mactimeFile.getAbsolutePath());
- }
-
-
- progressDialog.updateProgressBar("Parsing Mactime");
- if (data == null) {
- logger.log(Level.INFO, "Parsing mactime file: " + mactimeFile.getAbsolutePath());
- data = parseMacTime(mactimeFile); //The sum total of the mactime parsing. YearEpochs contain everything you need to make a timeline.
- }
- progressDialog.updateProgressBar(++currentProgress);
-
- //Making a dropdown box to select years.
- List<String> lsi = new ArrayList<String>(); //List is in the format of {Year : Number of Events}, used for selecting from the dropdown.
- for (YearEpoch ye : data) {
- lsi.add(ye.year + " : " + ye.getNumFiles());
- }
- ObservableList<String> listSelect = FXCollections.observableArrayList(lsi);
- fxDropdownSelectYears = new ComboBox<String>(listSelect);
-
- //Buttons for navigating up and down the timeline
- fxZoomOutButton = new Button("Zoom Out");
- fxZoomOutButton.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent e) {
- BarChart<String, Number> bc;
- if (fxStackPrevCharts.size() == 0) {
- bc = fxChartTopLevel;
- } else {
- bc = fxStackPrevCharts.pop();
- }
- fxChartEvents = bc;
- fxScrollEvents.setContent(fxChartEvents);
- }
- });
-
- fxDropdownSelectYears.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
- @Override
- public void changed(ObservableValue<? extends String> ov, String t, String t1) {
- if (fxDropdownSelectYears.getValue() != null) {
- mainFrame.setTopComponentCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- try {
- fxChartEvents = createMonthsWithDrill(findYear(data, Integer.valueOf(fxDropdownSelectYears.getValue().split(" ")[0])));
- fxScrollEvents.setContent(fxChartEvents);
- } finally {
- mainFrame.setTopComponentCursor(null);
- }
- }
- }
- });
-
- //Adding things to the V and H boxes.
- //hBox_Charts stores the pseudo menu bar at the top of the timeline. |Zoom Out|View Year: [Select Year]|►|
- fxHBoxCharts.getChildren().addAll(fxZoomOutButton, new Label("Go To:"), fxDropdownSelectYears);
- fxVBox.getChildren().addAll(fxHBoxCharts, fxScrollEvents); //FxBox_V holds things in a visual stack.
- fxGroupCharts.getChildren().add(fxVBox); //Adding the FxBox to the group. Groups make things easier to manipulate without having to update a hundred things every change.
- fxPanelCharts.setScene(fxSceneCharts);
-
-
- fxPanelCharts.setAlignmentX(Component.LEFT_ALIGNMENT);
-
- fxChartTopLevel = createYearChartWithDrill(data);
- fxChartEvents = fxChartTopLevel;
- fxScrollEvents.setContent(fxChartEvents);
-
- EventQueue.invokeLater(new Runnable() {
- @Override
- public void run() {
- mainFrame.setTopPanel(fxPanelCharts);
- dataResultPanel.open();
- //mainFrame.pack();
- mainFrame.setVisible(true);
- }
- });
- } finally {
- // stop the progress bar
- progress.finish();
-
- // close the progressDialog
- progressDialog.doClose(0);
- }
- }
- });
- }
-
- /**
- * Creates a BarChart with datapoints for all the years from the parsed
- * mactime file.
- *
- * @param allYears The list of years that have barData from the mactime file
- * @return BarChart scaled to the year level
- */
- private BarChart<String, Number> createYearChartWithDrill(final List<YearEpoch> allYears) {
- final CategoryAxis xAxis = new CategoryAxis(); //Axes are very specific types. Categorys are strings.
- final NumberAxis yAxis = new NumberAxis();
- final Label l = new Label("");
- l.setStyle("-fx-font: 24 arial;");
- l.setTextFill(Color.AZURE);
- xAxis.setLabel("Years");
- yAxis.setLabel("Number of Events");
- //Charts are made up of individual pieces of Chart.Data. In this case, a piece of barData is a single bar on the graph.
- //Data is packaged into a series, which can be assigned custom colors or styling
- //After the series are created, 1 or more series are packaged into a single chart.
- ObservableList<BarChart.Series<String, Number>> bcData = FXCollections.observableArrayList();
- BarChart.Series<String, Number> se = new BarChart.Series<String, Number>();
- if (allYears != null) {
- for (final YearEpoch ye : allYears) {
- se.getData().add(new BarChart.Data<String, Number>(String.valueOf(ye.year), ye.getNumFiles()));
- }
- }
- bcData.add(se);
-
-
- //Note:
- // BarChart.Data wraps the Java Nodes class. BUT, until a BarChart.Data gets added to an actual series, it's node is null, and you can perform no operations on it.
- // When the Data is added to a series(or a chart? I am unclear on where), a node is automaticaly generated for it, after which you can perform any of the operations it offers.
- // In addtion, you are free to set the node to whatever you want. It wraps the most generic Node class.
- // But it is for this reason that the chart generating functions have two forloops. I do not believe they can be condensed into a single loop due to the nodes being null until
- // an undetermined point in time.
- BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
- for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) { //.get(0) refers to the BarChart.Series class to work on. There is only one series in this graph, so get(0) is safe.
- barData.getNode().setScaleX(.5);
-
- final javafx.scene.Node barNode = barData.getNode();
- //hover listener
- barNode.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, fxMouseEnteredListener);
- barNode.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, fxMouseExitedListener);
-
- //click listener
- barNode.addEventHandler(MouseEvent.MOUSE_CLICKED,
- new EventHandler<MouseEvent>() {
- @Override
- public void handle(MouseEvent e) {
- if (e.getButton().equals(MouseButton.PRIMARY)) {
- if (e.getClickCount() == 1) {
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
- BarChart<String, Number> b =
- createMonthsWithDrill(findYear(allYears, Integer.valueOf(barData.getXValue())));
- fxChartEvents = b;
- fxScrollEvents.setContent(fxChartEvents);
- }
- });
-
- }
- }
- }
- });
- }
-
- bc.autosize(); //Get an auto height
- bc.setPrefWidth(FRAME_WIDTH); //but override the width
- bc.setLegendVisible(false); //The legend adds too much extra chart space, it's not necessary.
- return bc;
- }
-
- /*
- * Displays a chart with events from one year only, separated into 1-month chunks.
- * Always 12 per year, empty months are represented by no bar.
- */
- private BarChart<String, Number> createMonthsWithDrill(final YearEpoch ye) {
-
- final CategoryAxis xAxis = new CategoryAxis();
- final NumberAxis yAxis = new NumberAxis();
- xAxis.setLabel("Month (" + ye.year + ")");
- yAxis.setLabel("Number of Events");
- ObservableList<BarChart.Series<String, Number>> bcData = FXCollections.observableArrayList();
-
- BarChart.Series<String, Number> se = new BarChart.Series<String, Number>();
- for (int monthNum = 0; monthNum < 12; ++monthNum) {
- String monthName = new DateFormatSymbols().getMonths()[monthNum];
- MonthEpoch month = ye.getMonth(monthNum);
- int numEvents = month == null ? 0 : month.getNumFiles();
- se.getData().add(new BarChart.Data<String, Number>(monthName, numEvents)); //Adding new barData at {X-pos, Y-Pos}
- }
- bcData.add(se);
- final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
-
- for (int i = 0; i < 12; i++) {
- for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) {
- //Note:
- // All the charts of this package have a problem where when the chart gets below a certain pixel ratio, the barData stops drawing. The axes and the labels remain,
- // But the actual chart barData is invisible, unclickable, and unrendered. To partially compensate for that, barData.getNode() can be manually scaled up to increase visibility.
- // Sometimes I've had it jacked up to as much as x2400 just to see a sliver of information.
- // But that doesn't work all the time. Adding it to a scrollpane and letting the user scroll up and down to view the chart is the other workaround. Both of these fixes suck.
- final javafx.scene.Node barNode = barData.getNode();
- barNode.setScaleX(.5);
-
- //hover listener
- barNode.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, fxMouseEnteredListener);
- barNode.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, fxMouseExitedListener);
-
- //clicks
- barNode.addEventHandler(MouseEvent.MOUSE_PRESSED,
- new EventHandler<MouseEvent>() {
- @Override
- public void handle(MouseEvent e) {
- if (e.getButton().equals(MouseButton.PRIMARY)) {
- if (e.getClickCount() == 1) {
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
- fxChartEvents = createEventsByMonth(findMonth(ye.months, monthStringToInt(barData.getXValue())), ye);
- fxScrollEvents.setContent(fxChartEvents);
- }
- });
- }
- }
- }
- });
- }
- }
-
- bc.autosize();
- bc.setPrefWidth(FRAME_WIDTH);
- bc.setLegendVisible(false);
- fxStackPrevCharts.push(bc);
- return bc;
- }
-
-
- /*
- * Displays a chart with events from one month only.
- * Up to 31 days per month, as low as 28 as determined by the specific MonthEpoch
- */
- private BarChart<String, Number> createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
- final CategoryAxis xAxis = new CategoryAxis();
- final NumberAxis yAxis = new NumberAxis();
- xAxis.setLabel("Day of Month");
- yAxis.setLabel("Number of Events");
- ObservableList<BarChart.Data<String, Number>> bcData = makeObservableListByMonthAllDays(me, ye.getYear());
- BarChart.Series<String, Number> series = new BarChart.Series<String, Number>(bcData);
- series.setName(me.getMonthName() + " " + ye.getYear());
-
-
- ObservableList<BarChart.Series<String, Number>> ol =
- FXCollections.<BarChart.Series<String, Number>>observableArrayList(series);
-
- final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, ol);
- for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) {
- //data.getNode().setScaleX(2);
-
- final javafx.scene.Node barNode = barData.getNode();
-
- //hover listener
- barNode.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, fxMouseEnteredListener);
- barNode.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, fxMouseExitedListener);
-
- barNode.addEventHandler(MouseEvent.MOUSE_PRESSED,
- new EventHandler<MouseEvent>() {
- MonthEpoch myme = me;
-
- @Override
- public void handle(MouseEvent e) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- //reset the view and free the current nodes before loading new ones
- final FileRootNode d = new FileRootNode("Empty Root", new ArrayList<Long>());
- dataResultPanel.setNode(d);
- dataResultPanel.setPath("Loading...");
- }
- });
- final int day = (Integer.valueOf((barData.getXValue()).split("-")[1]));
- final DayEpoch de = myme.getDay(day);
- final List<Long> afs;
- if (de != null) {
- afs = de.getEvents();
- } else {
- logger.log(Level.SEVERE, "There were no events for the clicked-on day: " + day);
- return;
- }
-
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- final FileRootNode d = new FileRootNode("Root", afs);
- dataResultPanel.setNode(d);
- //set result viewer title path with the current date
- String dateString = ye.getYear() + "-" + (1 + me.getMonthInt()) + "-" + +de.dayNum;
- dataResultPanel.setPath(dateString);
- }
- });
-
-
- }
- });
- }
- bc.autosize();
- bc.setPrefWidth(FRAME_WIDTH);
- return bc;
- }
-
- private static ObservableList<BarChart.Data<String, Number>> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
- ObservableList<BarChart.Data<String, Number>> bcData = FXCollections.observableArrayList();
- int totalDays = me.getTotalNumDays(year);
- for (int i = 1; i <= totalDays; ++i) {
- DayEpoch day = me.getDay(i);
- int numFiles = day == null ? 0 : day.getNumFiles();
- BarChart.Data<String, Number> d = new BarChart.Data<String, Number>(me.month + 1 + "-" + i, numFiles);
- d.setExtraValue(me);
- bcData.add(d);
- }
- return bcData;
- }
-
- /*
- * Section for Utility functions
- */
- /**
- *
- * @param mon The month to convert. Must be minimum 4 characters long
- * "February" and "Febr" are acceptable.
- * @return The integer value of the month. February = 1, July = 6
- */
- private static int monthStringToInt(String mon) {
- try {
- Date date = new SimpleDateFormat("MMMM", Locale.ENGLISH).parse(mon);
- Calendar cal = Calendar.getInstance();
- cal.setTime(date);
- return cal.get(Calendar.MONTH);
- } catch (ParseException ex) {
- logger.log(Level.WARNING, "Unable to convert string " + mon + " to integer", ex);
- return -1;
- }
- }
-
- /**
- * Used for finding the proper month in a list of available months
- *
- * @param lst The list of months to search through. It is assumed that the
- * desired match is in this list.
- * @param match The month, in integer format, to retrieve.
- * @return The month epoch as specified by match.
- */
- private static MonthEpoch findMonth(List<MonthEpoch> lst, int match) {
- for (MonthEpoch e : lst) {
- if (e.month == match) {
- return e;
- }
- }
- return null;
- }
-
- /**
- * Used for finding the proper year in a list of available years
- *
- * @param lst The list of years to search through. It is assumed that the
- * desired match is in this list.
- * @param match The year to retrieve.
- * @return The year epoch as specified by match.
- */
- private static YearEpoch findYear(List<YearEpoch> lst, int match) {
- for (YearEpoch e : lst) {
- if (e.year == match) {
- return e;
- }
- }
- return null;
- }
-
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- String prop = evt.getPropertyName();
- if (prop.equals(Case.CASE_ADD_DATA_SOURCE)) {
- if (mainFrame != null && !mainFrame.isVisible()) {
- // change the lastObjectId to trigger a reparse of mactime barData
- ++lastObjectId;
- return;
- }
-
- int answer = JOptionPane.showConfirmDialog(mainFrame, "Timeline is out of date. Would you like to regenerate it?", "Select an option", JOptionPane.YES_NO_OPTION);
- if (answer != JOptionPane.YES_OPTION) {
- return;
- }
-
- clearMactimeData();
-
- // call performAction as if the user selected 'Make Timeline' from the menu
- performAction();
- } else if (prop.equals(Case.CASE_CURRENT_CASE)) {
- if (mainFrame != null && mainFrame.isVisible()) {
- mainFrame.dispose();
- mainFrame = null;
- }
-
- data = null;
- }
- }
-
- private void clearMactimeData() {
- // get rid of the old barData
- data = null;
-
- // get rid of the mactime file
- java.io.File mactimeFile = new java.io.File(moduleDir, mactimeFileName);
- mactimeFile.delete();
-
- // close the jframe
- if (mainFrame != null) {
- mainFrame.setVisible(false);
- mainFrame.dispose();
- mainFrame = null;
- }
-
- // remove ourself as change listener on Case
- Case.removePropertyChangeListener(this);
- listeningToAddImage = false;
-
- }
-
- /*
- * The backbone of the timeline functionality, years are split into months, months into days, and days contain the events of that given day.
- * All of those are Epochs.
- */
- abstract class Epoch {
-
- abstract public int getNumFiles();
- }
-
- private class YearEpoch extends Epoch {
-
- private int year;
- private List<MonthEpoch> months = new ArrayList<>();
-
- YearEpoch(int year) {
- this.year = year;
- }
-
- public int getYear() {
- return year;
- }
-
- @Override
- public int getNumFiles() {
- int size = 0;
- for (MonthEpoch me : months) {
- size += me.getNumFiles();
- }
- return size;
- }
-
- public MonthEpoch getMonth(int monthNum) {
- MonthEpoch month = null;
- for (MonthEpoch me : months) {
- if (me.getMonthInt() == monthNum) {
- month = me;
- break;
- }
- }
- return month;
- }
-
- public void add(long fileId, int month, int day) {
- // see if this month is in the list
- MonthEpoch monthEpoch = null;
- for (MonthEpoch me : months) {
- if (me.getMonthInt() == month) {
- monthEpoch = me;
- break;
- }
- }
-
- if (monthEpoch == null) {
- monthEpoch = new MonthEpoch(month);
- months.add(monthEpoch);
- }
-
- // add the file the the MonthEpoch object
- monthEpoch.add(fileId, day);
- }
- }
-
- private class MonthEpoch extends Epoch {
-
- private int month; //Zero-indexed: June = 5, August = 7, etc
- private List<DayEpoch> days = new ArrayList<>(); //List of DayEpochs in this month, max 31
-
- MonthEpoch(int month) {
- this.month = month;
- }
-
- public int getMonthInt() {
- return month;
- }
-
- public int getTotalNumDays(int year) {
- Calendar cal = Calendar.getInstance();
- cal.set(year, month, 1);
- return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
- }
-
- @Override
- public int getNumFiles() {
- int numFiles = 0;
- for (DayEpoch de : days) {
- numFiles += de.getNumFiles();
- }
- return numFiles;
- }
-
- public DayEpoch getDay(int dayNum) {
- DayEpoch de = null;
- for (DayEpoch d : days) {
- if (d.dayNum == dayNum) {
- de = d;
- break;
- }
- }
- return de;
- }
-
- public void add(long fileId, int day) {
- DayEpoch dayEpoch = null;
- for (DayEpoch de : days) {
- if (de.getDayInt() == day) {
- dayEpoch = de;
- break;
- }
- }
-
- if (dayEpoch == null) {
- dayEpoch = new DayEpoch(day);
- days.add(dayEpoch);
- }
-
- dayEpoch.add(fileId);
- }
-
- /**
- * Returns the month's name in String format, e.g., September, July,
- */
- String getMonthName() {
- return new DateFormatSymbols().getMonths()[month];
- }
-
- /**
- * @return the list of days in this month
- */
- List<DayEpoch> getDays() {
- return this.days;
- }
- }
-
- private class DayEpoch extends Epoch {
-
- private final List<Long> fileIds = new ArrayList<>();
- int dayNum = 0; //Day of the month this Epoch represents, 1 indexed: 28=28.
-
- DayEpoch(int dayOfMonth) {
- this.dayNum = dayOfMonth;
- }
-
- public int getDayInt() {
- return dayNum;
- }
-
- @Override
- public int getNumFiles() {
- return fileIds.size();
- }
-
- public void add(long fileId) {
- fileIds.add(fileId);
- }
-
- List<Long> getEvents() {
- return this.fileIds;
- }
- }
-
- // The node factories used to make lists of files to send to the result viewer
- // using the lazy loading (rather than background) loading option to facilitate
- // loading a huge number of nodes for the given day
- private class FileNodeChildFactory extends Children.Keys<Long> {
-
- private List<Long> fileIds;
-
- FileNodeChildFactory(List<Long> fileIds) {
- super(true);
- this.fileIds = fileIds;
- }
-
- @Override
- protected void addNotify() {
- super.addNotify();
- setKeys(fileIds);
- }
-
- @Override
- protected void removeNotify() {
- super.removeNotify();
- setKeys(new ArrayList<Long>());
- }
-
- @Override
- protected Node[] createNodes(Long t) {
- return new Node[]{createNodeForKey(t)};
- }
-
- // @Override
- // protected boolean createKeys(List<Long> list) {
- // list.addAll(fileIds);
- // return true;
- // }
- //@Override
- protected Node createNodeForKey(Long fileId) {
- AbstractFile af = null;
- try {
- af = skCase.getAbstractFileById(fileId);
- } catch (TskCoreException ex) {
- logger.log(Level.SEVERE, "Error getting file by id and creating a node in Timeline: " + fileId, ex);
- //no node will be shown for this object
- return null;
- }
-
- Node wrapped;
- if (af.isDir()) {
- wrapped = new DirectoryNode(af, false);
- } else {
- wrapped = new FileNode(af, false);
- }
- return new FilterNodeLeaf(wrapped);
- }
- }
-
- private class FileRootNode extends DisplayableItemNode {
-
- FileRootNode(String NAME, List<Long> fileIds) {
- //super(Children.create(new FileNodeChildFactory(fileIds), true));
- super(new FileNodeChildFactory(fileIds), Lookups.singleton(fileIds));
- super.setName(NAME);
- super.setDisplayName(NAME);
- }
-
- @Override
- public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
- return DisplayableItemNode.TYPE.CONTENT;
- }
-
- @Override
- public <T> T accept(DisplayableItemNodeVisitor<T> v) {
- return null;
- }
- }
-
- private List<YearEpoch> parseMacTime(java.io.File f) {
- List<YearEpoch> years = new ArrayList<>();
- Scanner scan;
- try {
- scan = new Scanner(new FileInputStream(f));
- } catch (FileNotFoundException ex) {
- logger.log(Level.SEVERE, "Error: could not find mactime file.", ex);
- return years;
- }
- scan.useDelimiter(",");
- scan.nextLine(); // skip the header line
-
- int prevYear = -1;
- YearEpoch ye = null;
- while (scan.hasNextLine()) {
- String[] s = scan.nextLine().split(","); //1999-02-08T11:08:08Z, 78706, m..b, rrwxrwxrwx, 0, 0, 8355, /img...
- String[] datetime = s[0].split("T"); //{1999-02-08, 11:08:08Z}
- String[] date = datetime[0].split("-"); // {1999, 02, 08}
- int year = Integer.valueOf(date[0]);
- int month = Integer.valueOf(date[1]) - 1; //Months are zero indexed: 1 = February, 6 = July, 11 = December
- int day = Integer.valueOf(date[2]); //Days are 1 indexed
- long ObjId = Long.valueOf(s[4]);
-
- // when the year changes, create and add a new YearEpoch object to the list
- if (year != prevYear) {
- ye = new YearEpoch(year);
- years.add(ye);
- prevYear = year;
- }
-
- if (ye != null) {
- ye.add(ObjId, month, day);
- }
- }
-
- scan.close();
-
- return years;
- }
-
- /**
- * Crate a body file and return its path or null if error
- *
- * @return absolute path string or null if error
- */
- private String makeBodyFile() {
- // Setup timestamp
- DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
- Date date = new Date();
- String datenotime = dateFormat.format(date);
-
- final Case currentCase = Case.getCurrentCase();
-
- // Get report path
- String bodyFilePath = moduleDir.getAbsolutePath()
- + java.io.File.separator + currentCase.getName() + "-" + datenotime + ".txt";
-
- // Run query to get all files
- final String filesAndDirs = "name != '.' "
- + "AND name != '..'";
- List<Long> fileIds = null;
- try {
- fileIds = skCase.findAllFileIdsWhere(filesAndDirs);
- } catch (TskCoreException ex) {
- logger.log(Level.SEVERE, "Error querying image files to make a body file: " + bodyFilePath, ex);
- return null;
- }
-
- // Loop files and write info to report
- FileWriter fileWriter = null;
- try {
- fileWriter = new FileWriter(bodyFilePath, true);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "Error creating output stream to write body file to: " + bodyFilePath, ex);
- return null;
- }
-
- BufferedWriter out = null;
- try {
- out = new BufferedWriter(fileWriter);
- for (long fileId : fileIds) {
- AbstractFile file = skCase.getAbstractFileById(fileId);
- // try {
- // MD5|name|inode|mode_as_string|ObjId|GID|size|atime|mtime|ctime|crtime
- if (file.getMd5Hash() != null) {
- out.write(file.getMd5Hash());
- }
- out.write("|");
- String path = null;
- try {
- path = file.getUniquePath();
- } catch (TskCoreException e) {
- logger.log(Level.SEVERE, "Failed to get the unique path of: " + file + " and writing body file.", e);
- return null;
- }
-
- out.write(path);
-
- out.write("|");
- out.write(Long.toString(file.getMetaAddr()));
- out.write("|");
- String modeString = file.getModesAsString();
- if (modeString != null) {
- out.write(modeString);
- }
- out.write("|");
- out.write(Long.toString(file.getId()));
- out.write("|");
- out.write(Long.toString(file.getGid()));
- out.write("|");
- out.write(Long.toString(file.getSize()));
- out.write("|");
- out.write(Long.toString(file.getAtime()));
- out.write("|");
- out.write(Long.toString(file.getMtime()));
- out.write("|");
- out.write(Long.toString(file.getCtime()));
- out.write("|");
- out.write(Long.toString(file.getCrtime()));
- out.write("\n");
- }
- } catch (TskCoreException ex) {
- logger.log(Level.SEVERE, "Error querying file by id", ex);
- return null;
-
- } catch (IOException ex) {
- logger.log(Level.WARNING, "Error while trying to write data to the body file.", ex);
- return null;
- } finally {
- if (out != null) {
- try {
- out.flush();
- out.close();
- } catch (IOException ex1) {
- logger.log(Level.WARNING, "Could not flush and/or close body file.", ex1);
- }
- }
- }
-
-
- return bodyFilePath;
- }
-
- private String makeMacTime(String pathToBodyFile) {
- String cmdpath = "";
- String macpath = "";
- String[] mactimeArgs;
- final String machome = macRoot.getAbsolutePath();
- pathToBodyFile = PlatformUtil.getOSFilePath(pathToBodyFile);
- if (PlatformUtil.isWindowsOS()) {
- macpath = machome + java.io.File.separator + "mactime.exe";
- cmdpath = PlatformUtil.getOSFilePath(macpath);
- mactimeArgs = new String[]{"-b", pathToBodyFile, "-d", "-y"};
- } else {
- cmdpath = "perl";
- macpath = machome + java.io.File.separator + "mactime.pl";
- mactimeArgs = new String[]{macpath, "-b", pathToBodyFile, "-d", "-y"};
- }
-
- String macfile = moduleDir.getAbsolutePath() + java.io.File.separator + mactimeFileName;
-
-
- String output = "";
- ExecUtil execUtil = new ExecUtil();
- Writer writer = null;
- try {
- //JavaSystemCaller.Exec.execute("\"" + command + "\"");
- writer = new FileWriter(macfile);
- execUtil.execute(writer, cmdpath, mactimeArgs);
- } catch (InterruptedException ie) {
- logger.log(Level.WARNING, "Mactime process was interrupted by user", ie);
- return null;
- } catch (IOException ioe) {
- logger.log(Level.SEVERE, "Could not create mactime file, encountered error ", ioe);
- return null;
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "Could not clsoe writer after creating mactime file, encountered error ", ex);
- }
- }
- }
-
- return macfile;
- }
-
- @Override
- public boolean isEnabled() {
- return Case.isCaseOpen() && this.fxInited;
- }
-
- @Override
- public void performAction() {
- initTimeline();
- }
-
- private void initTimeline() {
- if (!Case.existsCurrentCase()) {
- return;
- }
-
- final Case currentCase = Case.getCurrentCase();
- skCase = currentCase.getSleuthkitCase();
-
- try {
- if (currentCase.getRootObjectsCount() == 0) {
- logger.log(Level.INFO, "Error creating timeline, there are no data sources. ");
- } else {
-
- if (IngestManager.getDefault().isIngestRunning()) {
- int answer = JOptionPane.showConfirmDialog(new JFrame(),
- "You are trying to generate a timeline before "
- + "ingest has been completed. The timeline may be "
- + "incomplete. Do you want to continue?", "Timeline",
- JOptionPane.YES_NO_OPTION);
- if (answer != JOptionPane.YES_OPTION) {
- return;
- }
- }
-
- logger.log(Level.INFO, "Beginning generation of timeline");
-
- // if the timeline window is already open, bring to front and do nothing
- if (mainFrame != null && mainFrame.isVisible()) {
- mainFrame.toFront();
- return;
- }
-
- // listen for case changes (specifically images being added).
- if (Case.isCaseOpen() && !listeningToAddImage) {
- Case.addPropertyChangeListener(this);
- listeningToAddImage = true;
- }
-
- // create the modal progressDialog
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- progressDialog = new TimelineProgressDialog(WindowManager.getDefault().getMainWindow(), true);
- progressDialog.setVisible(true);
- }
- });
-
- // initialize mactimeFileName
- mactimeFileName = currentCase.getName() + "-MACTIME.txt";
-
- // see if barData has been added to the database since the last
- // time timeline ran
- long objId = skCase.getLastObjectId();
- if (objId != lastObjectId && lastObjectId != -1) {
- clearMactimeData();
- }
- lastObjectId = objId;
-
- customize();
- }
- } catch (TskCoreException ex) {
- logger.log(Level.SEVERE, "Error when generating timeline, ", ex);
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Unexpected error when generating timeline, ", ex);
- }
- }
-
- @Override
- public String getName() {
- return "Make Timeline (Beta)";
- }
-
- @Override
- public HelpCtx getHelpCtx() {
- return HelpCtx.DEFAULT_HELP;
- }
-
- @Override
- public boolean asynchronous() {
- return false;
- }
-}
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.timeline;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.BufferedWriter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Scanner;
+import java.util.Stack;
+import java.util.logging.Level;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.embed.swing.JFXPanel;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.chart.BarChart;
+import javafx.scene.chart.CategoryAxis;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.modules.InstalledFileLocator;
+import org.openide.modules.ModuleInstall;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+import org.openide.util.lookup.Lookups;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.core.Installer;
+import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
+import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+import org.sleuthkit.autopsy.datamodel.FilterNodeLeaf;
+import org.sleuthkit.autopsy.datamodel.DirectoryNode;
+import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
+import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
+import org.sleuthkit.autopsy.datamodel.FileNode;
+import org.sleuthkit.autopsy.ingest.IngestManager;
+import org.sleuthkit.autopsy.coreutils.ExecUtil;
+import org.sleuthkit.datamodel.AbstractFile;
+import org.sleuthkit.datamodel.SleuthkitCase;
+import org.sleuthkit.datamodel.TskCoreException;
+
+@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.timeline.Timeline")
+@ActionRegistration(displayName = "#CTL_MakeTimeline", lazy = false)
+@ActionReferences(value = {
+ @ActionReference(path = "Menu/Tools", position = 100)})
+@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
+/**
+ * The Timeline Action entry point. Collects data and pushes data to javafx
+ * widgets
+ *
+ */
+public class Timeline extends CallableSystemAction implements Presenter.Toolbar, PropertyChangeListener {
+
+ private static final Logger logger = Logger.getLogger(Timeline.class.getName());
+ private final java.io.File macRoot = InstalledFileLocator.getDefault().locate("mactime", Timeline.class.getPackage().getName(), false);
+ private TimelineFrame mainFrame; //frame for holding all the elements
+ private Group fxGroupCharts; //Orders the charts
+ private Scene fxSceneCharts; //Displays the charts
+ private HBox fxHBoxCharts; //Holds the navigation buttons in horiztonal fashion.
+ private VBox fxVBox; //Holds the JavaFX Elements in vertical fashion.
+ private JFXPanel fxPanelCharts; //FX panel to hold the group
+ private BarChart<String, Number> fxChartEvents; //Yearly/Monthly events - Bar chart
+ private ScrollPane fxScrollEvents; //Scroll Panes for dealing with oversized an oversized chart
+ private static final int FRAME_HEIGHT = 700; //Sizing constants
+ private static final int FRAME_WIDTH = 1200;
+ private Button fxZoomOutButton; //Navigation buttons
+ private ComboBox<String> fxDropdownSelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events.
+ private final Stack<BarChart<String, Number>> fxStackPrevCharts = new Stack<BarChart<String, Number>>(); //Stack for storing drill-up information.
+ private BarChart<String, Number> fxChartTopLevel; //the topmost chart, used for resetting to default view.
+ private DataResultPanel dataResultPanel;
+ private DataContentPanel dataContentPanel;
+ private ProgressHandle progress;
+ private java.io.File moduleDir;
+ private String mactimeFileName;
+ private List<YearEpoch> data;
+ private boolean listeningToAddImage = false;
+ private long lastObjectId = -1;
+ private TimelineProgressDialog progressDialog;
+ private EventHandler<MouseEvent> fxMouseEnteredListener;
+ private EventHandler<MouseEvent> fxMouseExitedListener;
+ private SleuthkitCase skCase;
+ private boolean fxInited = false;
+
+ public Timeline() {
+ super();
+
+ fxInited = Installer.isJavaFxInited();
+
+ }
+
+ //Swing components and JavafX components don't play super well together
+ //Swing components need to be initialized first, in the swing specific thread
+ //Next, the javafx components may be initialized.
+ private void customize() {
+
+ //listeners
+ fxMouseEnteredListener = new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent e) {
+ fxPanelCharts.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ }
+ };
+ fxMouseExitedListener = new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent e) {
+ fxPanelCharts.setCursor(null);
+ }
+ };
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ //Making the main frame *
+
+ mainFrame = new TimelineFrame();
+ mainFrame.setFrameName(Case.getCurrentCase().getName() + " - Autopsy Timeline (Beta)");
+
+ //use the same icon on jframe as main application
+ mainFrame.setIconImage(WindowManager.getDefault().getMainWindow().getIconImage());
+ mainFrame.setFrameSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); //(Width, Height)
+
+
+ dataContentPanel = DataContentPanel.createInstance();
+ //dataContentPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
+ //dataContentPanel.setPreferredSize(new Dimension(FRAME_WIDTH, (int) (FRAME_HEIGHT * 0.4)));
+
+ dataResultPanel = DataResultPanel.createInstance("Timeline Results", "", Node.EMPTY, 0, dataContentPanel);
+ dataResultPanel.setContentViewer(dataContentPanel);
+ //dataResultPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+ //dataResultPanel.setPreferredSize(new Dimension((int)(FRAME_WIDTH * 0.5), (int) (FRAME_HEIGHT * 0.5)));
+ logger.log(Level.INFO, "Successfully created viewers");
+
+ mainFrame.setBottomLeftPanel(dataResultPanel);
+ mainFrame.setBottomRightPanel(dataContentPanel);
+
+ runJavaFxThread();
+ }
+ });
+
+
+ }
+
+ private void runJavaFxThread() {
+ //JavaFX thread
+ //JavaFX components MUST be run in the JavaFX thread, otherwise massive amounts of exceptions will be thrown and caught. Liable to freeze up and crash.
+ //Components can be declared whenever, but initialization and manipulation must take place here.
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // start the progress bar
+ progress = ProgressHandleFactory.createHandle("Creating timeline . . .");
+ progress.start();
+
+ fxChartEvents = null; //important to reset old data
+ fxPanelCharts = new JFXPanel();
+ fxGroupCharts = new Group();
+ fxSceneCharts = new Scene(fxGroupCharts, FRAME_WIDTH, FRAME_HEIGHT * 0.6); //Width, Height
+ fxVBox = new VBox(5);
+ fxVBox.setAlignment(Pos.BOTTOM_CENTER);
+ fxHBoxCharts = new HBox(10);
+ fxHBoxCharts.setAlignment(Pos.BOTTOM_CENTER);
+
+ //Initializing default values for the scroll pane
+ fxScrollEvents = new ScrollPane();
+ fxScrollEvents.setPrefSize(FRAME_WIDTH, FRAME_HEIGHT * 0.6); //Width, Height
+ fxScrollEvents.setContent(null); //Needs some content, otherwise it crashes
+
+ // set up moduleDir
+ moduleDir = new java.io.File(Case.getCurrentCase().getModulesOutputDirAbsPath() + java.io.File.separator + "timeline");
+ if (!moduleDir.exists()) {
+ moduleDir.mkdir();
+ }
+
+ int currentProgress = 0;
+ java.io.File mactimeFile = new java.io.File(moduleDir, mactimeFileName);
+ if (!mactimeFile.exists()) {
+ progressDialog.setProgressTotal(3); //total 3 units
+ logger.log(Level.INFO, "Creating body file");
+ progressDialog.updateProgressBar("Generating Bodyfile");
+ String bodyFilePath = makeBodyFile();
+ progressDialog.updateProgressBar(++currentProgress);
+ logger.log(Level.INFO, "Creating mactime file: " + mactimeFile.getAbsolutePath());
+ progressDialog.updateProgressBar("Generating Mactime");
+ makeMacTime(bodyFilePath);
+ progressDialog.updateProgressBar(++currentProgress);
+ data = null;
+ } else {
+ progressDialog.setProgressTotal(1); //total 1 units
+ logger.log(Level.INFO, "Mactime file already exists; parsing that: " + mactimeFile.getAbsolutePath());
+ }
+
+
+ progressDialog.updateProgressBar("Parsing Mactime");
+ if (data == null) {
+ logger.log(Level.INFO, "Parsing mactime file: " + mactimeFile.getAbsolutePath());
+ data = parseMacTime(mactimeFile); //The sum total of the mactime parsing. YearEpochs contain everything you need to make a timeline.
+ }
+ progressDialog.updateProgressBar(++currentProgress);
+
+ //Making a dropdown box to select years.
+ List<String> lsi = new ArrayList<String>(); //List is in the format of {Year : Number of Events}, used for selecting from the dropdown.
+ for (YearEpoch ye : data) {
+ lsi.add(ye.year + " : " + ye.getNumFiles());
+ }
+ ObservableList<String> listSelect = FXCollections.observableArrayList(lsi);
+ fxDropdownSelectYears = new ComboBox<String>(listSelect);
+
+ //Buttons for navigating up and down the timeline
+ fxZoomOutButton = new Button("Zoom Out");
+ fxZoomOutButton.setOnAction(new EventHandler<ActionEvent>() {
+ @Override
+ public void handle(ActionEvent e) {
+ BarChart<String, Number> bc;
+ if (fxStackPrevCharts.size() == 0) {
+ bc = fxChartTopLevel;
+ } else {
+ bc = fxStackPrevCharts.pop();
+ }
+ fxChartEvents = bc;
+ fxScrollEvents.setContent(fxChartEvents);
+ }
+ });
+
+ fxDropdownSelectYears.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
+ @Override
+ public void changed(ObservableValue<? extends String> ov, String t, String t1) {
+ if (fxDropdownSelectYears.getValue() != null) {
+ mainFrame.setTopComponentCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ try {
+ fxChartEvents = createMonthsWithDrill(findYear(data, Integer.valueOf(fxDropdownSelectYears.getValue().split(" ")[0])));
+ fxScrollEvents.setContent(fxChartEvents);
+ } finally {
+ mainFrame.setTopComponentCursor(null);
+ }
+ }
+ }
+ });
+
+ //Adding things to the V and H boxes.
+ //hBox_Charts stores the pseudo menu bar at the top of the timeline. |Zoom Out|View Year: [Select Year]|►|
+ fxHBoxCharts.getChildren().addAll(fxZoomOutButton, new Label("Go To:"), fxDropdownSelectYears);
+ fxVBox.getChildren().addAll(fxHBoxCharts, fxScrollEvents); //FxBox_V holds things in a visual stack.
+ fxGroupCharts.getChildren().add(fxVBox); //Adding the FxBox to the group. Groups make things easier to manipulate without having to update a hundred things every change.
+ fxPanelCharts.setScene(fxSceneCharts);
+
+
+ fxPanelCharts.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+ fxChartTopLevel = createYearChartWithDrill(data);
+ fxChartEvents = fxChartTopLevel;
+ fxScrollEvents.setContent(fxChartEvents);
+
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ mainFrame.setTopPanel(fxPanelCharts);
+ dataResultPanel.open();
+ //mainFrame.pack();
+ mainFrame.setVisible(true);
+ }
+ });
+ } finally {
+ // stop the progress bar
+ progress.finish();
+
+ // close the progressDialog
+ progressDialog.doClose(0);
+ }
+ }
+ });
+ }
+
+ /**
+ * Creates a BarChart with datapoints for all the years from the parsed
+ * mactime file.
+ *
+ * @param allYears The list of years that have barData from the mactime file
+ * @return BarChart scaled to the year level
+ */
+ private BarChart<String, Number> createYearChartWithDrill(final List<YearEpoch> allYears) {
+ final CategoryAxis xAxis = new CategoryAxis(); //Axes are very specific types. Categorys are strings.
+ final NumberAxis yAxis = new NumberAxis();
+ final Label l = new Label("");
+ l.setStyle("-fx-font: 24 arial;");
+ l.setTextFill(Color.AZURE);
+ xAxis.setLabel("Years");
+ yAxis.setLabel("Number of Events");
+ //Charts are made up of individual pieces of Chart.Data. In this case, a piece of barData is a single bar on the graph.
+ //Data is packaged into a series, which can be assigned custom colors or styling
+ //After the series are created, 1 or more series are packaged into a single chart.
+ ObservableList<BarChart.Series<String, Number>> bcData = FXCollections.observableArrayList();
+ BarChart.Series<String, Number> se = new BarChart.Series<String, Number>();
+ if (allYears != null) {
+ for (final YearEpoch ye : allYears) {
+ se.getData().add(new BarChart.Data<String, Number>(String.valueOf(ye.year), ye.getNumFiles()));
+ }
+ }
+ bcData.add(se);
+
+
+ //Note:
+ // BarChart.Data wraps the Java Nodes class. BUT, until a BarChart.Data gets added to an actual series, it's node is null, and you can perform no operations on it.
+ // When the Data is added to a series(or a chart? I am unclear on where), a node is automaticaly generated for it, after which you can perform any of the operations it offers.
+ // In addtion, you are free to set the node to whatever you want. It wraps the most generic Node class.
+ // But it is for this reason that the chart generating functions have two forloops. I do not believe they can be condensed into a single loop due to the nodes being null until
+ // an undetermined point in time.
+ BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
+ for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) { //.get(0) refers to the BarChart.Series class to work on. There is only one series in this graph, so get(0) is safe.
+ barData.getNode().setScaleX(.5);
+
+ final javafx.scene.Node barNode = barData.getNode();
+ //hover listener
+ barNode.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, fxMouseEnteredListener);
+ barNode.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, fxMouseExitedListener);
+
+ //click listener
+ barNode.addEventHandler(MouseEvent.MOUSE_CLICKED,
+ new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent e) {
+ if (e.getButton().equals(MouseButton.PRIMARY)) {
+ if (e.getClickCount() == 1) {
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ BarChart<String, Number> b =
+ createMonthsWithDrill(findYear(allYears, Integer.valueOf(barData.getXValue())));
+ fxChartEvents = b;
+ fxScrollEvents.setContent(fxChartEvents);
+ }
+ });
+
+ }
+ }
+ }
+ });
+ }
+
+ bc.autosize(); //Get an auto height
+ bc.setPrefWidth(FRAME_WIDTH); //but override the width
+ bc.setLegendVisible(false); //The legend adds too much extra chart space, it's not necessary.
+ return bc;
+ }
+
+ /*
+ * Displays a chart with events from one year only, separated into 1-month chunks.
+ * Always 12 per year, empty months are represented by no bar.
+ */
+ private BarChart<String, Number> createMonthsWithDrill(final YearEpoch ye) {
+
+ final CategoryAxis xAxis = new CategoryAxis();
+ final NumberAxis yAxis = new NumberAxis();
+ xAxis.setLabel("Month (" + ye.year + ")");
+ yAxis.setLabel("Number of Events");
+ ObservableList<BarChart.Series<String, Number>> bcData = FXCollections.observableArrayList();
+
+ BarChart.Series<String, Number> se = new BarChart.Series<String, Number>();
+ for (int monthNum = 0; monthNum < 12; ++monthNum) {
+ String monthName = new DateFormatSymbols().getMonths()[monthNum];
+ MonthEpoch month = ye.getMonth(monthNum);
+ int numEvents = month == null ? 0 : month.getNumFiles();
+ se.getData().add(new BarChart.Data<String, Number>(monthName, numEvents)); //Adding new barData at {X-pos, Y-Pos}
+ }
+ bcData.add(se);
+ final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, bcData);
+
+ for (int i = 0; i < 12; i++) {
+ for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) {
+ //Note:
+ // All the charts of this package have a problem where when the chart gets below a certain pixel ratio, the barData stops drawing. The axes and the labels remain,
+ // But the actual chart barData is invisible, unclickable, and unrendered. To partially compensate for that, barData.getNode() can be manually scaled up to increase visibility.
+ // Sometimes I've had it jacked up to as much as x2400 just to see a sliver of information.
+ // But that doesn't work all the time. Adding it to a scrollpane and letting the user scroll up and down to view the chart is the other workaround. Both of these fixes suck.
+ final javafx.scene.Node barNode = barData.getNode();
+ barNode.setScaleX(.5);
+
+ //hover listener
+ barNode.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, fxMouseEnteredListener);
+ barNode.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, fxMouseExitedListener);
+
+ //clicks
+ barNode.addEventHandler(MouseEvent.MOUSE_PRESSED,
+ new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent e) {
+ if (e.getButton().equals(MouseButton.PRIMARY)) {
+ if (e.getClickCount() == 1) {
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ fxChartEvents = createEventsByMonth(findMonth(ye.months, monthStringToInt(barData.getXValue())), ye);
+ fxScrollEvents.setContent(fxChartEvents);
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+ }
+
+ bc.autosize();
+ bc.setPrefWidth(FRAME_WIDTH);
+ bc.setLegendVisible(false);
+ fxStackPrevCharts.push(bc);
+ return bc;
+ }
+
+
+ /*
+ * Displays a chart with events from one month only.
+ * Up to 31 days per month, as low as 28 as determined by the specific MonthEpoch
+ */
+ private BarChart<String, Number> createEventsByMonth(final MonthEpoch me, final YearEpoch ye) {
+ final CategoryAxis xAxis = new CategoryAxis();
+ final NumberAxis yAxis = new NumberAxis();
+ xAxis.setLabel("Day of Month");
+ yAxis.setLabel("Number of Events");
+ ObservableList<BarChart.Data<String, Number>> bcData = makeObservableListByMonthAllDays(me, ye.getYear());
+ BarChart.Series<String, Number> series = new BarChart.Series<String, Number>(bcData);
+ series.setName(me.getMonthName() + " " + ye.getYear());
+
+
+ ObservableList<BarChart.Series<String, Number>> ol =
+ FXCollections.<BarChart.Series<String, Number>>observableArrayList(series);
+
+ final BarChart<String, Number> bc = new BarChart<String, Number>(xAxis, yAxis, ol);
+ for (final BarChart.Data<String, Number> barData : bc.getData().get(0).getData()) {
+ //data.getNode().setScaleX(2);
+
+ final javafx.scene.Node barNode = barData.getNode();
+
+ //hover listener
+ barNode.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, fxMouseEnteredListener);
+ barNode.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, fxMouseExitedListener);
+
+ barNode.addEventHandler(MouseEvent.MOUSE_PRESSED,
+ new EventHandler<MouseEvent>() {
+ MonthEpoch myme = me;
+
+ @Override
+ public void handle(MouseEvent e) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ //reset the view and free the current nodes before loading new ones
+ final FileRootNode d = new FileRootNode("Empty Root", new ArrayList<Long>());
+ dataResultPanel.setNode(d);
+ dataResultPanel.setPath("Loading...");
+ }
+ });
+ final int day = (Integer.valueOf((barData.getXValue()).split("-")[1]));
+ final DayEpoch de = myme.getDay(day);
+ final List<Long> afs;
+ if (de != null) {
+ afs = de.getEvents();
+ } else {
+ logger.log(Level.SEVERE, "There were no events for the clicked-on day: " + day);
+ return;
+ }
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ final FileRootNode d = new FileRootNode("Root", afs);
+ dataResultPanel.setNode(d);
+ //set result viewer title path with the current date
+ String dateString = ye.getYear() + "-" + (1 + me.getMonthInt()) + "-" + +de.dayNum;
+ dataResultPanel.setPath(dateString);
+ }
+ });
+
+
+ }
+ });
+ }
+ bc.autosize();
+ bc.setPrefWidth(FRAME_WIDTH);
+ return bc;
+ }
+
+ private static ObservableList<BarChart.Data<String, Number>> makeObservableListByMonthAllDays(final MonthEpoch me, int year) {
+ ObservableList<BarChart.Data<String, Number>> bcData = FXCollections.observableArrayList();
+ int totalDays = me.getTotalNumDays(year);
+ for (int i = 1; i <= totalDays; ++i) {
+ DayEpoch day = me.getDay(i);
+ int numFiles = day == null ? 0 : day.getNumFiles();
+ BarChart.Data<String, Number> d = new BarChart.Data<String, Number>(me.month + 1 + "-" + i, numFiles);
+ d.setExtraValue(me);
+ bcData.add(d);
+ }
+ return bcData;
+ }
+
+ /*
+ * Section for Utility functions
+ */
+ /**
+ *
+ * @param mon The month to convert. Must be minimum 4 characters long
+ * "February" and "Febr" are acceptable.
+ * @return The integer value of the month. February = 1, July = 6
+ */
+ private static int monthStringToInt(String mon) {
+ try {
+ Date date = new SimpleDateFormat("MMMM", Locale.ENGLISH).parse(mon);
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ return cal.get(Calendar.MONTH);
+ } catch (ParseException ex) {
+ logger.log(Level.WARNING, "Unable to convert string " + mon + " to integer", ex);
+ return -1;
+ }
+ }
+
+ /**
+ * Used for finding the proper month in a list of available months
+ *
+ * @param lst The list of months to search through. It is assumed that the
+ * desired match is in this list.
+ * @param match The month, in integer format, to retrieve.
+ * @return The month epoch as specified by match.
+ */
+ private static MonthEpoch findMonth(List<MonthEpoch> lst, int match) {
+ for (MonthEpoch e : lst) {
+ if (e.month == match) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Used for finding the proper year in a list of available years
+ *
+ * @param lst The list of years to search through. It is assumed that the
+ * desired match is in this list.
+ * @param match The year to retrieve.
+ * @return The year epoch as specified by match.
+ */
+ private static YearEpoch findYear(List<YearEpoch> lst, int match) {
+ for (YearEpoch e : lst) {
+ if (e.year == match) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ String prop = evt.getPropertyName();
+ if (prop.equals(Case.CASE_ADD_DATA_SOURCE)) {
+ if (mainFrame != null && !mainFrame.isVisible()) {
+ // change the lastObjectId to trigger a reparse of mactime barData
+ ++lastObjectId;
+ return;
+ }
+
+ int answer = JOptionPane.showConfirmDialog(mainFrame, "Timeline is out of date. Would you like to regenerate it?", "Select an option", JOptionPane.YES_NO_OPTION);
+ if (answer != JOptionPane.YES_OPTION) {
+ return;
+ }
+
+ clearMactimeData();
+
+ // call performAction as if the user selected 'Make Timeline' from the menu
+ performAction();
+ } else if (prop.equals(Case.CASE_CURRENT_CASE)) {
+ if (mainFrame != null && mainFrame.isVisible()) {
+ mainFrame.dispose();
+ mainFrame = null;
+ }
+
+ data = null;
+ }
+ }
+
+ private void clearMactimeData() {
+ // get rid of the old barData
+ data = null;
+
+ // get rid of the mactime file
+ java.io.File mactimeFile = new java.io.File(moduleDir, mactimeFileName);
+ mactimeFile.delete();
+
+ // close the jframe
+ if (mainFrame != null) {
+ mainFrame.setVisible(false);
+ mainFrame.dispose();
+ mainFrame = null;
+ }
+
+ // remove ourself as change listener on Case
+ Case.removePropertyChangeListener(this);
+ listeningToAddImage = false;
+
+ }
+
+ /*
+ * The backbone of the timeline functionality, years are split into months, months into days, and days contain the events of that given day.
+ * All of those are Epochs.
+ */
+ abstract class Epoch {
+
+ abstract public int getNumFiles();
+ }
+
+ private class YearEpoch extends Epoch {
+
+ private int year;
+ private List<MonthEpoch> months = new ArrayList<>();
+
+ YearEpoch(int year) {
+ this.year = year;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ @Override
+ public int getNumFiles() {
+ int size = 0;
+ for (MonthEpoch me : months) {
+ size += me.getNumFiles();
+ }
+ return size;
+ }
+
+ public MonthEpoch getMonth(int monthNum) {
+ MonthEpoch month = null;
+ for (MonthEpoch me : months) {
+ if (me.getMonthInt() == monthNum) {
+ month = me;
+ break;
+ }
+ }
+ return month;
+ }
+
+ public void add(long fileId, int month, int day) {
+ // see if this month is in the list
+ MonthEpoch monthEpoch = null;
+ for (MonthEpoch me : months) {
+ if (me.getMonthInt() == month) {
+ monthEpoch = me;
+ break;
+ }
+ }
+
+ if (monthEpoch == null) {
+ monthEpoch = new MonthEpoch(month);
+ months.add(monthEpoch);
+ }
+
+ // add the file the the MonthEpoch object
+ monthEpoch.add(fileId, day);
+ }
+ }
+
+ private class MonthEpoch extends Epoch {
+
+ private int month; //Zero-indexed: June = 5, August = 7, etc
+ private List<DayEpoch> days = new ArrayList<>(); //List of DayEpochs in this month, max 31
+
+ MonthEpoch(int month) {
+ this.month = month;
+ }
+
+ public int getMonthInt() {
+ return month;
+ }
+
+ public int getTotalNumDays(int year) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(year, month, 1);
+ return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+ }
+
+ @Override
+ public int getNumFiles() {
+ int numFiles = 0;
+ for (DayEpoch de : days) {
+ numFiles += de.getNumFiles();
+ }
+ return numFiles;
+ }
+
+ public DayEpoch getDay(int dayNum) {
+ DayEpoch de = null;
+ for (DayEpoch d : days) {
+ if (d.dayNum == dayNum) {
+ de = d;
+ break;
+ }
+ }
+ return de;
+ }
+
+ public void add(long fileId, int day) {
+ DayEpoch dayEpoch = null;
+ for (DayEpoch de : days) {
+ if (de.getDayInt() == day) {
+ dayEpoch = de;
+ break;
+ }
+ }
+
+ if (dayEpoch == null) {
+ dayEpoch = new DayEpoch(day);
+ days.add(dayEpoch);
+ }
+
+ dayEpoch.add(fileId);
+ }
+
+ /**
+ * Returns the month's name in String format, e.g., September, July,
+ */
+ String getMonthName() {
+ return new DateFormatSymbols().getMonths()[month];
+ }
+
+ /**
+ * @return the list of days in this month
+ */
+ List<DayEpoch> getDays() {
+ return this.days;
+ }
+ }
+
+ private class DayEpoch extends Epoch {
+
+ private final List<Long> fileIds = new ArrayList<>();
+ int dayNum = 0; //Day of the month this Epoch represents, 1 indexed: 28=28.
+
+ DayEpoch(int dayOfMonth) {
+ this.dayNum = dayOfMonth;
+ }
+
+ public int getDayInt() {
+ return dayNum;
+ }
+
+ @Override
+ public int getNumFiles() {
+ return fileIds.size();
+ }
+
+ public void add(long fileId) {
+ fileIds.add(fileId);
+ }
+
+ List<Long> getEvents() {
+ return this.fileIds;
+ }
+ }
+
+ // The node factories used to make lists of files to send to the result viewer
+ // using the lazy loading (rather than background) loading option to facilitate
+ // loading a huge number of nodes for the given day
+ private class FileNodeChildFactory extends Children.Keys<Long> {
+
+ private List<Long> fileIds;
+
+ FileNodeChildFactory(List<Long> fileIds) {
+ super(true);
+ this.fileIds = fileIds;
+ }
+
+ @Override
+ protected void addNotify() {
+ super.addNotify();
+ setKeys(fileIds);
+ }
+
+ @Override
+ protected void removeNotify() {
+ super.removeNotify();
+ setKeys(new ArrayList<Long>());
+ }
+
+ @Override
+ protected Node[] createNodes(Long t) {
+ return new Node[]{createNodeForKey(t)};
+ }
+
+ // @Override
+ // protected boolean createKeys(List<Long> list) {
+ // list.addAll(fileIds);
+ // return true;
+ // }
+ //@Override
+ protected Node createNodeForKey(Long fileId) {
+ AbstractFile af = null;
+ try {
+ af = skCase.getAbstractFileById(fileId);
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Error getting file by id and creating a node in Timeline: " + fileId, ex);
+ //no node will be shown for this object
+ return null;
+ }
+
+ Node wrapped;
+ if (af.isDir()) {
+ wrapped = new DirectoryNode(af, false);
+ } else {
+ wrapped = new FileNode(af, false);
+ }
+ return new FilterNodeLeaf(wrapped);
+ }
+ }
+
+ private class FileRootNode extends DisplayableItemNode {
+
+ FileRootNode(String NAME, List<Long> fileIds) {
+ //super(Children.create(new FileNodeChildFactory(fileIds), true));
+ super(new FileNodeChildFactory(fileIds), Lookups.singleton(fileIds));
+ super.setName(NAME);
+ super.setDisplayName(NAME);
+ }
+
+ @Override
+ public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
+ return DisplayableItemNode.TYPE.CONTENT;
+ }
+
+ @Override
+ public <T> T accept(DisplayableItemNodeVisitor<T> v) {
+ return null;
+ }
+ }
+
+ private List<YearEpoch> parseMacTime(java.io.File f) {
+ List<YearEpoch> years = new ArrayList<>();
+ Scanner scan;
+ try {
+ scan = new Scanner(new FileInputStream(f));
+ } catch (FileNotFoundException ex) {
+ logger.log(Level.SEVERE, "Error: could not find mactime file.", ex);
+ return years;
+ }
+ scan.useDelimiter(",");
+ scan.nextLine(); // skip the header line
+
+ int prevYear = -1;
+ YearEpoch ye = null;
+ while (scan.hasNextLine()) {
+ String[] s = scan.nextLine().split(","); //1999-02-08T11:08:08Z, 78706, m..b, rrwxrwxrwx, 0, 0, 8355, /img...
+ String[] datetime = s[0].split("T"); //{1999-02-08, 11:08:08Z}
+ String[] date = datetime[0].split("-"); // {1999, 02, 08}
+ int year = Integer.valueOf(date[0]);
+ int month = Integer.valueOf(date[1]) - 1; //Months are zero indexed: 1 = February, 6 = July, 11 = December
+ int day = Integer.valueOf(date[2]); //Days are 1 indexed
+ long ObjId = Long.valueOf(s[4]);
+
+ // when the year changes, create and add a new YearEpoch object to the list
+ if (year != prevYear) {
+ ye = new YearEpoch(year);
+ years.add(ye);
+ prevYear = year;
+ }
+
+ if (ye != null) {
+ ye.add(ObjId, month, day);
+ }
+ }
+
+ scan.close();
+
+ return years;
+ }
+
+ /**
+ * Crate a body file and return its path or null if error
+ *
+ * @return absolute path string or null if error
+ */
+ private String makeBodyFile() {
+ // Setup timestamp
+ DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
+ Date date = new Date();
+ String datenotime = dateFormat.format(date);
+
+ final Case currentCase = Case.getCurrentCase();
+
+ // Get report path
+ String bodyFilePath = moduleDir.getAbsolutePath()
+ + java.io.File.separator + currentCase.getName() + "-" + datenotime + ".txt";
+
+ // Run query to get all files
+ final String filesAndDirs = "name != '.' "
+ + "AND name != '..'";
+ List<Long> fileIds = null;
+ try {
+ fileIds = skCase.findAllFileIdsWhere(filesAndDirs);
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Error querying image files to make a body file: " + bodyFilePath, ex);
+ return null;
+ }
+
+ // Loop files and write info to report
+ FileWriter fileWriter = null;
+ try {
+ fileWriter = new FileWriter(bodyFilePath, true);
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "Error creating output stream to write body file to: " + bodyFilePath, ex);
+ return null;
+ }
+
+ BufferedWriter out = null;
+ try {
+ out = new BufferedWriter(fileWriter);
+ for (long fileId : fileIds) {
+ AbstractFile file = skCase.getAbstractFileById(fileId);
+ // try {
+ // MD5|name|inode|mode_as_string|ObjId|GID|size|atime|mtime|ctime|crtime
+ if (file.getMd5Hash() != null) {
+ out.write(file.getMd5Hash());
+ }
+ out.write("|");
+ String path = null;
+ try {
+ path = file.getUniquePath();
+ } catch (TskCoreException e) {
+ logger.log(Level.SEVERE, "Failed to get the unique path of: " + file + " and writing body file.", e);
+ return null;
+ }
+
+ out.write(path);
+
+ out.write("|");
+ out.write(Long.toString(file.getMetaAddr()));
+ out.write("|");
+ String modeString = file.getModesAsString();
+ if (modeString != null) {
+ out.write(modeString);
+ }
+ out.write("|");
+ out.write(Long.toString(file.getId()));
+ out.write("|");
+ out.write(Long.toString(file.getGid()));
+ out.write("|");
+ out.write(Long.toString(file.getSize()));
+ out.write("|");
+ out.write(Long.toString(file.getAtime()));
+ out.write("|");
+ out.write(Long.toString(file.getMtime()));
+ out.write("|");
+ out.write(Long.toString(file.getCtime()));
+ out.write("|");
+ out.write(Long.toString(file.getCrtime()));
+ out.write("\n");
+ }
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Error querying file by id", ex);
+ return null;
+
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Error while trying to write data to the body file.", ex);
+ return null;
+ } finally {
+ if (out != null) {
+ try {
+ out.flush();
+ out.close();
+ } catch (IOException ex1) {
+ logger.log(Level.WARNING, "Could not flush and/or close body file.", ex1);
+ }
+ }
+ }
+
+
+ return bodyFilePath;
+ }
+
+ private String makeMacTime(String pathToBodyFile) {
+ String cmdpath = "";
+ String macpath = "";
+ String[] mactimeArgs;
+ final String machome = macRoot.getAbsolutePath();
+ pathToBodyFile = PlatformUtil.getOSFilePath(pathToBodyFile);
+ if (PlatformUtil.isWindowsOS()) {
+ macpath = machome + java.io.File.separator + "mactime.exe";
+ cmdpath = PlatformUtil.getOSFilePath(macpath);
+ mactimeArgs = new String[]{"-b", pathToBodyFile, "-d", "-y"};
+ } else {
+ cmdpath = "perl";
+ macpath = machome + java.io.File.separator + "mactime.pl";
+ mactimeArgs = new String[]{macpath, "-b", pathToBodyFile, "-d", "-y"};
+ }
+
+ String macfile = moduleDir.getAbsolutePath() + java.io.File.separator + mactimeFileName;
+
+
+ String output = "";
+ ExecUtil execUtil = new ExecUtil();
+ Writer writer = null;
+ try {
+ //JavaSystemCaller.Exec.execute("\"" + command + "\"");
+ writer = new FileWriter(macfile);
+ execUtil.execute(writer, cmdpath, mactimeArgs);
+ } catch (InterruptedException ie) {
+ logger.log(Level.WARNING, "Mactime process was interrupted by user", ie);
+ return null;
+ } catch (IOException ioe) {
+ logger.log(Level.SEVERE, "Could not create mactime file, encountered error ", ioe);
+ return null;
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "Could not clsoe writer after creating mactime file, encountered error ", ex);
+ }
+ }
+ }
+
+ return macfile;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return Case.isCaseOpen() && this.fxInited;
+ }
+
+ @Override
+ public void performAction() {
+ initTimeline();
+ }
+
+ private void initTimeline() {
+ if (!Case.existsCurrentCase()) {
+ return;
+ }
+
+ final Case currentCase = Case.getCurrentCase();
+ skCase = currentCase.getSleuthkitCase();
+
+ try {
+ if (currentCase.getRootObjectsCount() == 0) {
+ logger.log(Level.INFO, "Error creating timeline, there are no data sources. ");
+ } else {
+
+ if (IngestManager.getDefault().isIngestRunning()) {
+ int answer = JOptionPane.showConfirmDialog(new JFrame(),
+ "You are trying to generate a timeline before "
+ + "ingest has been completed. The timeline may be "
+ + "incomplete. Do you want to continue?", "Timeline",
+ JOptionPane.YES_NO_OPTION);
+ if (answer != JOptionPane.YES_OPTION) {
+ return;
+ }
+ }
+
+ logger.log(Level.INFO, "Beginning generation of timeline");
+
+ // if the timeline window is already open, bring to front and do nothing
+ if (mainFrame != null && mainFrame.isVisible()) {
+ mainFrame.toFront();
+ return;
+ }
+
+ // listen for case changes (specifically images being added).
+ if (Case.isCaseOpen() && !listeningToAddImage) {
+ Case.addPropertyChangeListener(this);
+ listeningToAddImage = true;
+ }
+
+ // create the modal progressDialog
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ progressDialog = new TimelineProgressDialog(WindowManager.getDefault().getMainWindow(), true);
+ progressDialog.setVisible(true);
+ }
+ });
+
+ // initialize mactimeFileName
+ mactimeFileName = currentCase.getName() + "-MACTIME.txt";
+
+ // see if barData has been added to the database since the last
+ // time timeline ran
+ long objId = skCase.getLastObjectId();
+ if (objId != lastObjectId && lastObjectId != -1) {
+ clearMactimeData();
+ }
+ lastObjectId = objId;
+
+ customize();
+ }
+ } catch (TskCoreException ex) {
+ logger.log(Level.SEVERE, "Error when generating timeline, ", ex);
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, "Unexpected error when generating timeline, ", ex);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "Make Timeline (Beta)";
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ @Override
+ public boolean asynchronous() {
+ return false;
+ }
+}
diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
index 4744f62146..ea31e2447b 100644
--- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
+++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
@@ -1,5 +1,5 @@
#Updated by build script
-#Wed, 25 Sep 2013 13:55:37 -0400
+#Fri, 18 Oct 2013 23:25:14 -0400
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=288
SPLASH_WIDTH=538
@@ -8,4 +8,4 @@ SplashRunningTextBounds=5,266,530,17
SplashRunningTextColor=0x0
SplashRunningTextFontSize=18
-currentVersion=Autopsy 3.0.7
+currentVersion=Autopsy 3.0.8
diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
index 0dbd5e9a00..5b961ec43f 100644
--- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
+++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
@@ -1,5 +1,5 @@
-#Updated by build script
-#Wed, 25 Sep 2013 13:55:37 -0400
-
-CTL_MainWindow_Title=Autopsy 3.0.7
-CTL_MainWindow_Title_No_Project=Autopsy 3.0.7
+#Updated by build script
+#Fri, 18 Oct 2013 23:25:14 -0400
+
+CTL_MainWindow_Title=Autopsy 3.0.8
+CTL_MainWindow_Title_No_Project=Autopsy 3.0.8
diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml
index aec76cd632..52a74cd1a7 100644
--- a/thunderbirdparser/nbproject/project.xml
+++ b/thunderbirdparser/nbproject/project.xml
@@ -1,31 +1,31 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
- <type>org.netbeans.modules.apisupport.project</type>
- <configuration>
- <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
- <code-name-base>org.sleuthkit.autopsy.thunderbirdparser</code-name-base>
- <suite-component/>
- <module-dependencies>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>9</release-version>
- <specification-version>7.0</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <release-version>5</release-version>
- <specification-version>3.2</specification-version>
- </run-dependency>
- </dependency>
- </module-dependencies>
- <public-packages/>
- </data>
- </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.sleuthkit.autopsy.thunderbirdparser</code-name-base>
+ <suite-component/>
+ <module-dependencies>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.core</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>9</release-version>
+ <specification-version>7.0</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>5</release-version>
+ <specification-version>3.2</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <public-packages/>
+ </data>
+ </configuration>
+</project>
--
GitLab