Merge remote-tracking branch 'upstream/cvt-graph-view' into visualization-refinement

This commit is contained in:
millmanorama 2018-01-22 11:37:45 +01:00
commit 12392eb20d
51 changed files with 2985 additions and 1520 deletions

View File

@ -18,6 +18,8 @@
</copy>
</target>
<property name="VERSION" value="4.6.0"/>
<target name="get-thirdparty-dependencies" description="get third-party dependencies">
<!--Copy openCV dependencies to release-->
<copy todir="${modules.dir}" >
@ -52,8 +54,8 @@
<target name="getTSKJars" depends="findTSK">
<property environment="env"/>
<copy file="${env.TSK_HOME}/bindings/java/dist/Tsk_DataModel_PostgreSQL.jar"
tofile="${ext.dir}/Tsk_DataModel_PostgreSQL.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/dist/sleuthkit-postgresql-${VERSION}.jar"
tofile="${ext.dir}/sleuthkit-postgresql-${VERSION}.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.8.11.jar"
tofile="${ext.dir}/sqlite-jdbc-3.8.11.jar"/>
<copy file="${env.TSK_HOME}/bindings/java/lib/postgresql-9.4.1211.jre7.jar"

View File

@ -22,8 +22,8 @@
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.8.1"/>
<dependency conf="core->default" org="org.apache.tika" name="tika-core" rev="1.14"/>
<dependency conf="core->default" org="org.apache.tika" name="tika-parsers" rev="1.14"/>
<dependency conf="core->default" org="org.apache.tika" name="tika-core" rev="1.17"/>
<dependency conf="core->default" org="org.apache.tika" name="tika-parsers" rev="1.17"/>
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>

View File

@ -1,6 +1,6 @@
file.reference.activemq-all-5.11.1.jar=release/modules/ext/activemq-all-5.11.1.jar
file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar
file.reference.commons-compress-1.12.jar=release/modules/ext/commons-compress-1.12.jar
file.reference.commons-compress-1.14.jar=release/modules/ext/commons-compress-1.14.jar
file.reference.commons-dbcp2-2.1.1.jar=release\\modules\\ext\\commons-dbcp2-2.1.1.jar
file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar
file.reference.jdom-2.0.5-contrib.jar=release/modules/ext/jdom-2.0.5-contrib.jar
@ -9,7 +9,7 @@ file.reference.jgraphx-v3.8.0.jar=release/modules/ext/jgraphx-v3.8.0.jar
file.reference.jsoup-1.10.3.jar=release/modules/ext/jsoup-1.10.3.jar
file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
file.reference.metadata-extractor-2.9.1.jar=release/modules/ext/metadata-extractor-2.9.1.jar
file.reference.metadata-extractor-2.10.1.jar=release/modules/ext/metadata-extractor-2.10.1.jar
file.reference.postgresql-9.4.1211.jre7.jar=release/modules/ext/postgresql-9.4.1211.jre7.jar
file.reference.opencv-248.jar=release/modules/ext/opencv-248.jar
file.reference.Rejistry-1.0-SNAPSHOT.jar=release/modules/ext/Rejistry-1.0-SNAPSHOT.jar
@ -17,14 +17,14 @@ file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbi
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
file.reference.sqlite-jdbc-3.8.11.jar=release/modules/ext/sqlite-jdbc-3.8.11.jar
file.reference.StixLib.jar=release/modules/ext/StixLib.jar
file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar
file.reference.tika-parsers-1.14.jar=release/modules/ext/tika-parsers-1.14.jar
file.reference.Tsk_DataModel_PostgreSQL.jar=release/modules/ext/Tsk_DataModel_PostgreSQL.jar
file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.jar
file.reference.sleuthkit-postgresql-4.6.0.jar=release/modules/ext/sleuthkit-postgresql-4.6.0.jar
file.reference.tika-core-1.17.jar=release/modules/ext/tika-core-1.17.jar
file.reference.tika-parsers-1.17.jar=release/modules/ext/tika-parsers-1.17.jar
file.reference.curator-client-2.8.0.jar=release/modules/ext/curator-client-2.8.0.jar
file.reference.curator-framework-2.8.0.jar=release/modules/ext/curator-framework-2.8.0.jar
file.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0.jar
file.reference.xz-1.5.jar=release/modules/ext/xz-1.5.jar
file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
file.reference.xz-1.6.jar=release/modules/ext/xz-1.6.jar
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
javac.source=1.8
javac.compilerargs=-Xlint -Xlint:-serial

View File

@ -286,6 +286,7 @@
</test-dependency>
</test-type>
</test-dependencies>
<public-packages>
<package>net.sf.sevenzipjbinding</package>
<package>net.sf.sevenzipjbinding.impl</package>
@ -329,12 +330,8 @@
<binary-origin>release/modules/ext/jdom-2.0.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/Tsk_DataModel_PostgreSQL.jar</runtime-relative-path>
<binary-origin>release/modules/ext/Tsk_DataModel_PostgreSQL.jar</binary-origin>
<runtime-relative-path>ext/sleuthkit-postgresql-4.6.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sleuthkit-postgresql-4.6.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opencv-248.jar</runtime-relative-path>
@ -353,8 +350,12 @@
<binary-origin>release/modules/ext/jgraphx-v3.8.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.14.jar</binary-origin>
<runtime-relative-path>ext/commons-compress-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-compress-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-dbcp2-2.1.1.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-dbcp2-2.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jython-standalone-2.7.0.jar</runtime-relative-path>
@ -377,12 +378,12 @@
<binary-origin>release/modules/ext/curator-recipes-2.8.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xz-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xz-1.5.jar</binary-origin>
<runtime-relative-path>ext/metadata-extractor-2.10.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.10.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-5.1.2.jar</binary-origin>
<runtime-relative-path>ext/tika-core-1.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/StixLib.jar</runtime-relative-path>
@ -392,6 +393,10 @@
<runtime-relative-path>ext/curator-client-2.8.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/curator-client-2.8.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sqlite-jdbc-3.8.11.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sqlite-jdbc-3.8.11.jar</binary-origin>
@ -400,6 +405,10 @@
<runtime-relative-path>ext/activemq-all-5.11.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/activemq-all-5.11.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xz-1.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xz-1.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/Rejistry-1.0-SNAPSHOT.jar</runtime-relative-path>
<binary-origin>release/modules/ext/Rejistry-1.0-SNAPSHOT.jar</binary-origin>
@ -412,14 +421,6 @@
<runtime-relative-path>ext/commons-pool2-2.4.2.jar</runtime-relative-path>
<binary-origin>release\modules\ext\commons-pool2-2.4.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/metadata-extractor-2.9.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.9.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-compress-1.12.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-compress-1.12.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jsoup-1.10.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jsoup-1.10.3.jar</binary-origin>
@ -432,6 +433,10 @@
<runtime-relative-path>ext/c3p0-0.9.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/c3p0-0.9.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-5.1.3.jar</binary-origin>
</class-path-extension>
</data>
</configuration>
</project>

View File

@ -223,17 +223,11 @@ ReviewModeCasePanel.MetadataFileHeaderText=Metadata File
OpenMultiUserCasePanel.jLabel1.text=Recent Cases
OpenMultiUserCasePanel.openButton.text=Open
OpenMultiUserCasePanel.cancelButton.text=Cancel
MultiUserCasesPanel.rbWeeks.text=Weeks
MultiUserCasesPanel.rbDays.text=Days
MultiUserCasesPanel.bnShowLog.toolTipText=Display case log file for selected case
MultiUserCasesPanel.bnShowLog.text=&Show Auto Ingest Case Log
MultiUserCasesPanel.rbAllCases.text=Everything
MultiUserCasesPanel.bnRefresh.text=&Refresh
MultiUserCasesPanel.bnOpen.text=&Open
MultiUserCasesPanel.rbGroupLabel.text=Show cases created in the last 10:
MultiUserCasesPanel.rbMonths.text=Months
CueBannerPanel.newCaseLabel.text=New Case
CueBannerPanel.openCaseButton.text=
CueBannerPanel.openCaseLabel.text=Open Case
MultiUserCasesPanel.bnOpenSingleUserCase.text=Open Single-User Case...
CueBannerPanel.newCaseButton.text=
MultiUserCasesPanel.searchLabel.text=Start typing to search by case name
MultiUserCasesPanel.cancelButton.text=Cancel

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 5]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="caseTableScrollPane">
<Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 5]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,296 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2017-2018 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.casemodule;
import java.awt.Component;
import java.lang.reflect.InvocationTargetException;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.netbeans.swing.etable.ETableColumn;
import org.netbeans.swing.etable.ETableColumnModel;
import org.netbeans.swing.outline.DefaultOutlineModel;
import org.netbeans.swing.outline.Outline;
import org.openide.nodes.Node;
import java.awt.EventQueue;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.SwingWorker;
import org.openide.explorer.ExplorerManager;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coordinationservice.CaseNodeData;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.EmptyNode;
/**
* A Swing JPanel with a scroll pane child component. The scroll pane contain
* the table of cases.
*
* Used to display a list of multi user cases and allow the user to open one of
* them.
*
*/
class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider {
private static final long serialVersionUID = 1L;
private final Outline outline;
private ExplorerManager em;
private final org.openide.explorer.view.OutlineView outlineView;
private int originalPathColumnIndex = 0;
private static final Logger LOGGER = Logger.getLogger(CaseBrowser.class.getName());
private LoadCaseMapWorker tableWorker;
@Override
public ExplorerManager getExplorerManager() {
return em;
}
/**
* Creates a new CaseBrowser
*/
CaseBrowser() {
outlineView = new org.openide.explorer.view.OutlineView();
initComponents();
outline = outlineView.getOutline();
outlineView.setPropertyColumns(
Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(),
Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath());
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CaseNode_column_name());
customize();
}
/**
* Configures the the table of cases and its columns.
*/
private void customize() {
outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
TableColumnModel columnModel = outline.getColumnModel();
int dateColumnIndex = 0;
for (int index = 0; index < columnModel.getColumnCount(); index++) {
//get indexes for created date column and path column
if (columnModel.getColumn(index).getHeaderValue().toString().equals(Bundle.CaseNode_column_metadataFilePath())) {
originalPathColumnIndex = index;
} else if (columnModel.getColumn(index).getHeaderValue().toString().equals(Bundle.CaseNode_column_createdTime())) {
dateColumnIndex = index;
}
}
//Hide path column by default will need to
ETableColumn column = (ETableColumn) columnModel.getColumn(originalPathColumnIndex);
((ETableColumnModel) columnModel).setColumnHidden(column, true);
outline.setRootVisible(false);
//Sort on Created date column in descending order by default
outline.setColumnSorted(dateColumnIndex, false, 1);
if (null == em) {
em = new ExplorerManager();
}
caseTableScrollPane.setViewportView(outlineView);
this.setVisible(true);
outline.setRowSelectionAllowed(false);
}
/**
* Add a listener to changes in case selections in the table
*
* @param listener the ListSelectionListener to add
*/
void addListSelectionListener(ListSelectionListener listener) {
outline.getSelectionModel().addListSelectionListener(listener);
}
String getCasePath() {
int[] selectedRows = outline.getSelectedRows();
if (selectedRows.length == 1) {
try {
return ((Node.Property) outline.getModel().getValueAt(outline.convertRowIndexToModel(selectedRows[0]), originalPathColumnIndex)).getValue().toString();
} catch (IllegalAccessException | InvocationTargetException ex) {
LOGGER.log(Level.SEVERE, "Unable to get case path from table.", ex);
}
}
return null;
}
/**
* Check if a row could be and is selected.
*
* @return true if a row is selected, false if no row is selected
*/
boolean isRowSelected() {
return outline.getRowSelectionAllowed() && outline.getSelectedRows().length > 0;
}
@NbBundle.Messages({"CaseBrowser.caseListLoading.message=Please Wait..."})
/**
* Gets the list of cases known to the review mode cases manager and
* refreshes the cases table.
*/
void refresh() {
if (tableWorker == null || tableWorker.isDone()) {
outline.setRowSelectionAllowed(false);
//create a new TableWorker to and execute it in a background thread if one is not currently working
//set the table to display text informing the user that the list is being retreived and disable case selection
EmptyNode emptyNode = new EmptyNode(Bundle.CaseBrowser_caseListLoading_message());
em.setRootContext(emptyNode);
tableWorker = new LoadCaseMapWorker();
tableWorker.execute();
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
caseTableScrollPane = new javax.swing.JScrollPane();
setMinimumSize(new java.awt.Dimension(0, 5));
setPreferredSize(new java.awt.Dimension(5, 5));
setLayout(new java.awt.BorderLayout());
caseTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
caseTableScrollPane.setMinimumSize(new java.awt.Dimension(0, 5));
caseTableScrollPane.setOpaque(false);
caseTableScrollPane.setPreferredSize(new java.awt.Dimension(5, 5));
add(caseTableScrollPane, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane caseTableScrollPane;
// End of variables declaration//GEN-END:variables
/**
* Swingworker to fetch the updated map of cases and their status in a
* background thread
*/
private class LoadCaseMapWorker extends SwingWorker<Void, Void> {
private static final String ALERT_FILE_NAME = "autoingest.alert";
private Map<CaseMetadata, Boolean> cases;
/**
* Gets a list of the cases in the top level case folder
*
* @return List of cases.
*
* @throws CoordinationServiceException
*/
private Map<CaseMetadata, Boolean> getCases() throws CoordinationService.CoordinationServiceException {
Map<CaseMetadata, Boolean> casesMap = new HashMap<>();
List<String> nodeList = CoordinationService.getInstance().getNodeList(CoordinationService.CategoryNode.CASES);
for (String node : nodeList) {
Path casePath = Paths.get(node);
File caseFolder = casePath.toFile();
if (caseFolder.exists()) {
/*
* Search for '*.aut' and 'autoingest.alert' files.
*/
File[] fileArray = caseFolder.listFiles();
if (fileArray == null) {
continue;
}
String autFilePath = null;
boolean alertFileFound = false;
for (File file : fileArray) {
String name = file.getName().toLowerCase();
if (autFilePath == null && name.endsWith(".aut")) {
autFilePath = file.getAbsolutePath();
if (!alertFileFound) {
continue;
}
}
if (!alertFileFound && name.endsWith(ALERT_FILE_NAME)) {
alertFileFound = true;
}
if (autFilePath != null && alertFileFound) {
break;
}
}
if (autFilePath != null) {
try {
boolean hasAlertStatus = false;
if (alertFileFound) {
/*
* When an alert file exists, ignore the node
* data and use the ALERT status.
*/
hasAlertStatus = true;
} else {
byte[] rawData = CoordinationService.getInstance().getNodeData(CoordinationService.CategoryNode.CASES, node);
if (rawData != null && rawData.length > 0) {
/*
* When node data exists, use the status
* stored in the node data.
*/
CaseNodeData caseNodeData = new CaseNodeData(rawData);
if (caseNodeData.getErrorsOccurred()) {
hasAlertStatus = true;
}
}
}
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(autFilePath));
casesMap.put(caseMetadata, hasAlertStatus);
} catch (CaseMetadata.CaseMetadataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
} catch (InterruptedException | CaseNodeData.InvalidDataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case node data for '%s'.", node), ex);
}
}
}
}
return casesMap;
}
@Override
protected Void doInBackground() throws Exception {
try {
cases = getCases();
} catch (CoordinationService.CoordinationServiceException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while refreshing the table.", ex); //NON-NLS
}
return null;
}
@Override
protected void done() {
EventQueue.invokeLater(() -> {
MultiUserNode caseListNode = new MultiUserNode(cases);
em.setRootContext(caseListNode);
outline.setRowSelectionAllowed(true);
});
}
}
}

View File

@ -1,442 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 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.casemodule;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coordinationservice.CaseNodeData;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Handles locating and opening multi-user cases.
*/
final class MultiUserCaseManager {
private static final Logger LOGGER = Logger.getLogger(MultiUserCaseManager.class.getName());
private static final String ALERT_FILE_NAME = "autoingest.alert";
private static MultiUserCaseManager instance;
private CoordinationService coordinationService;
/**
* Gets the multi-user case manager.
*
* @return The multi-user case manager singleton.
*
* @throws MultiUserCaseManagerException
*/
synchronized static MultiUserCaseManager getInstance() throws MultiUserCaseManager.MultiUserCaseManagerException {
if (null == instance) {
instance = new MultiUserCaseManager();
}
return instance;
}
/**
* Constructs an object that handles locating and opening multi-user cases.
*
* @throws MultiUserCaseManagerException
*/
private MultiUserCaseManager() throws MultiUserCaseManagerException {
try {
coordinationService = CoordinationService.getInstance();
} catch (CoordinationServiceException ex) {
throw new MultiUserCaseManager.MultiUserCaseManagerException("Failed to get the coordination service.", ex);
}
}
/**
* Gets a list of the cases in the top level case folder
*
* @return List of cases.
*
* @throws CoordinationServiceException
*/
List<MultiUserCase> getCases() throws CoordinationServiceException {
List<MultiUserCase> cases = new ArrayList<>();
List<String> nodeList = coordinationService.getNodeList(CoordinationService.CategoryNode.CASES);
for (String node : nodeList) {
Path casePath = Paths.get(node);
File caseFolder = casePath.toFile();
if (caseFolder.exists()) {
/*
* Search for '*.aut' and 'autoingest.alert' files.
*/
File[] fileArray = caseFolder.listFiles();
if (fileArray == null) {
continue;
}
String autFilePath = null;
boolean alertFileFound = false;
for (File file : fileArray) {
String name = file.getName().toLowerCase();
if (autFilePath == null && name.endsWith(".aut")) {
autFilePath = file.getAbsolutePath();
if (!alertFileFound) {
continue;
}
}
if (!alertFileFound && name.endsWith(ALERT_FILE_NAME)) {
alertFileFound = true;
}
if (autFilePath != null && alertFileFound) {
break;
}
}
if (autFilePath != null) {
try {
CaseStatus caseStatus;
if (alertFileFound) {
/*
* When an alert file exists, ignore the node data
* and use the ALERT status.
*/
caseStatus = CaseStatus.ALERT;
} else {
byte[] rawData = coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, node);
if (rawData != null && rawData.length > 0) {
/*
* When node data exists, use the status stored
* in the node data.
*/
CaseNodeData caseNodeData = new CaseNodeData(rawData);
if (caseNodeData.getErrorsOccurred()) {
caseStatus = CaseStatus.ALERT;
} else {
caseStatus = CaseStatus.OK;
}
} else {
/*
* When no node data is available, use the 'OK'
* status to avoid confusing the end-user.
*/
caseStatus = CaseStatus.OK;
}
}
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(autFilePath));
cases.add(new MultiUserCase(casePath, caseMetadata, caseStatus));
} catch (CaseMetadata.CaseMetadataException | MultiUserCase.MultiUserCaseException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
} catch (InterruptedException | CaseNodeData.InvalidDataException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading case node data for '%s'.", node), ex);
}
}
}
}
return cases;
}
/**
* Opens a multi-user case.
*
* @param caseMetadataFilePath Path to the case metadata file.
*
* @throws CaseActionException
*/
synchronized void openCase(Path caseMetadataFilePath) throws CaseActionException {
/*
* Open the case.
*/
Case.openAsCurrentCase(caseMetadataFilePath.toString());
}
/**
* Exception type thrown when there is an error completing a multi-user case
* manager operation.
*/
static final class MultiUserCaseManagerException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Constructs an instance of the exception type thrown when there is an
* error completing a multi-user case manager operation.
*
* @param message The exception message.
*/
private MultiUserCaseManagerException(String message) {
super(message);
}
/**
* Constructs an instance of the exception type thrown when there is an
* error completing a multi-user case manager operation.
*
* @param message The exception message.
* @param cause A Throwable cause for the error.
*/
private MultiUserCaseManagerException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* A representation of a multi-user case.
*/
static class MultiUserCase implements Comparable<MultiUserCase> {
private final Path caseDirectoryPath;
private final String caseDisplayName;
private final String metadataFileName;
private final Date createDate;
private final Date lastAccessedDate;
private CaseStatus status;
/**
* Constructs a representation of a multi-user case
*
* @param caseDirectoryPath The case directory path.
* @param caseMetadata The case metadata.
*
* @throws MultiUserCaseException If no case metadata (.aut) file is
* found in the case directory.
*/
MultiUserCase(Path caseDirectoryPath, CaseMetadata caseMetadata, CaseStatus status) throws MultiUserCaseException {
this.caseDirectoryPath = caseDirectoryPath;
caseDisplayName = caseMetadata.getCaseDisplayName();
metadataFileName = caseMetadata.getFilePath().getFileName().toString();
this.status = status;
BasicFileAttributes fileAttrs = null;
try {
fileAttrs = Files.readAttributes(Paths.get(caseDirectoryPath.toString(), metadataFileName), BasicFileAttributes.class);
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("Error reading file attributes of case metadata file in %s, will use current time for case createDate/lastModfiedDate", caseDirectoryPath), ex);
}
if (null != fileAttrs) {
createDate = new Date(fileAttrs.creationTime().toMillis());
lastAccessedDate = new Date(fileAttrs.lastAccessTime().toMillis());
} else {
createDate = new Date();
lastAccessedDate = new Date();
}
}
/**
* Gets the case directory path.
*
* @return The case directory path.
*/
Path getCaseDirectoryPath() {
return this.caseDirectoryPath;
}
/**
* Gets the case display name. This may differ from the name supplied to
* the directory or metadata file names if a case has been renamed.
*
* @return The case display name.
*/
String getCaseDisplayName() {
return this.caseDisplayName;
}
/**
* Gets the creation date for the case, defined as the create time of
* the case metadata file.
*
* @return The case creation date.
*/
Date getCreationDate() {
return this.createDate;
}
/**
* Gets the last accessed date for the case, defined as the last
* accessed time of the case metadata file.
*
* @return The last accessed date.
*/
Date getLastAccessedDate() {
return this.lastAccessedDate;
}
/**
* Gets metadata (.aut) file name.
*
* @return The metadata file name.
*/
String getMetadataFileName() {
return this.metadataFileName;
}
/**
* Gets the status of this case.
*
* @return See CaseStatus enum definition.
*/
CaseStatus getStatus() {
return status;
}
/**
* Gets the case metadata from a case directory path.
*
* @param caseDirectoryPath The case directory path.
*
* @return Case metadata.
*
* @throws CaseMetadata.CaseMetadataException If the CaseMetadata object
* cannot be constructed.
* @throws MultiUserCaseException If no case metadata (.aut)
* file is found in the case
* directory.
*/
private CaseMetadata getCaseMetadataFromCaseDirectoryPath(Path caseDirectoryPath) throws CaseMetadata.CaseMetadataException, MultiUserCaseException {
CaseMetadata caseMetadata = null;
File directory = new File(caseDirectoryPath.toString());
if (directory.isDirectory()) {
File autFile = null;
/*
* Attempt to find an AUT file via a directory scan.
*/
for (File file : directory.listFiles()) {
if (file.getName().toLowerCase().endsWith(CaseMetadata.getFileExtension()) && file.isFile()) {
autFile = file;
break;
}
}
if (autFile == null || !autFile.isFile()) {
throw new MultiUserCaseException(String.format("No case metadata (.aut) file found in the case directory '%s'.", caseDirectoryPath.toString()));
}
caseMetadata = new CaseMetadata(Paths.get(autFile.getAbsolutePath()));
}
return caseMetadata;
}
/**
* Indicates whether or not some other object is "equal to" this
* MultiUserCase object.
*
* @param other The other object.
*
* @return True or false.
*/
@Override
public boolean equals(Object other) {
if (!(other instanceof MultiUserCase)) {
return false;
}
if (other == this) {
return true;
}
return this.caseDirectoryPath.toString().equals(((MultiUserCase) other).caseDirectoryPath.toString());
}
/**
* Returns a hash code value for this MultiUserCase object.
*
* @return The has code.
*/
@Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + Objects.hashCode(this.caseDirectoryPath);
hash = 71 * hash + Objects.hashCode(this.createDate);
hash = 71 * hash + Objects.hashCode(this.caseDisplayName);
return hash;
}
/**
* Compares this MultiUserCase object with another MultiUserCase object
* for order.
*/
@Override
public int compareTo(MultiUserCase other) {
return -this.lastAccessedDate.compareTo(other.getLastAccessedDate());
}
/**
* Comparator for a descending order sort on date created.
*/
static class LastAccessedDateDescendingComparator implements Comparator<MultiUserCase> {
/**
* Compares two MultiUserCase objects for order based on last
* accessed date (descending).
*
* @param object The first MultiUserCase object
* @param otherObject The second MultiUserCase object.
*
* @return A negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than
* the second.
*/
@Override
public int compare(MultiUserCase object, MultiUserCase otherObject) {
return -object.getLastAccessedDate().compareTo(otherObject.getLastAccessedDate());
}
}
/**
* Exception thrown when there is a problem creating a multi-user case.
*/
final class MultiUserCaseException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Constructs an exception to throw when there is a problem creating
* a multi-user case.
*
* @param message The exception message.
*/
private MultiUserCaseException(String message) {
super(message);
}
/**
* Constructs an exception to throw when there is a problem creating
* a multi-user case.
*
* @param message The exception message.
* @param cause The cause of the exception, if it was an
* exception.
*/
private MultiUserCaseException(String message, Throwable cause) {
super(message, cause);
}
}
}
static enum CaseStatus {
OK,
ALERT
}
}

View File

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="rbGroupHistoryLength">
</Component>
</NonVisualComponents>
<Properties>
<Property name="name" type="java.lang.String" value="Completed Cases" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
@ -26,30 +22,19 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="caseExplorerScrollPane" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Component id="searchLabel" min="-2" pref="555" max="-2" attributes="0"/>
<EmptySpace pref="175" max="32767" attributes="0"/>
<Component id="bnOpen" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnOpenSingleUserCase" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnShowLog" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="rbGroupLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rbDays" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rbWeeks" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rbMonths" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="panelFilter" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
<Component id="bnRefresh" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="scrollPaneTable" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -59,26 +44,15 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
<Component id="scrollPaneTable" min="-2" pref="450" max="-2" attributes="0"/>
<Component id="caseExplorerScrollPane" min="-2" pref="450" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnOpen" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnOpenSingleUserCase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnShowLog" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="103" alignment="1" groupAlignment="3" attributes="0">
<Component id="rbDays" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="rbWeeks" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="rbMonths" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="rbGroupLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="panelFilter" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="bnRefresh" alignment="1" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnOpen" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnOpenSingleUserCase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="searchLabel" alignment="3" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -95,140 +69,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="scrollPaneTable">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="casesTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="caseTableModel" type="code"/>
</Property>
<Property name="rowHeight" type="int" value="20"/>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
</Properties>
<Events>
<EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="casesTableMouseClicked"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="bnRefresh">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.bnRefresh.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnRefreshActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JPanel" name="panelFilter">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="rbAllCases" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="rbAllCases" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="rbAllCases">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.rbAllCases.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="rbAllCasesItemStateChanged"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="bnShowLog">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.bnShowLog.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.bnShowLog.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnShowLogActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="rbDays">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.rbDays.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="rbDaysItemStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="rbWeeks">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.rbWeeks.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="rbWeeksItemStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="rbMonths">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="rbGroupHistoryLength"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.rbMonths.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="rbMonthsItemStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="rbGroupLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.rbGroupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnOpenSingleUserCase">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -239,5 +79,26 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOpenSingleUserCaseActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="searchLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="MultiUserCasesPanel.searchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="caseExplorerScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -19,79 +19,29 @@
package org.sleuthkit.autopsy.casemodule;
import java.awt.Cursor;
import java.awt.Desktop;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SortOrder;
import javax.swing.SwingWorker;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.MultiUserCaseManager.MultiUserCase;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.guiutils.LongDateCellRenderer;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.guiutils.GrayableCellRenderer;
import org.sleuthkit.autopsy.guiutils.StatusIconCellRenderer;
/**
* A panel that allows a user to open cases created by auto ingest.
*/
@NbBundle.Messages({"MultiUSerCasesPanel.caseListLoading.message=Retrieving list of cases, please wait..."})
final class MultiUserCasesPanel extends javax.swing.JPanel {
final class MultiUserCasesPanel extends JPanel{
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(MultiUserCasesPanel.class.getName());
private static final String LOG_FILE_NAME = "auto_ingest_log.txt";
private static final int CASE_COL_MIN_WIDTH = 30;
private static final int CASE_COL_MAX_WIDTH = 2000;
private static final int CASE_COL_PREFERRED_WIDTH = 300;
private static final int TIME_COL_MIN_WIDTH = 40;
private static final int TIME_COL_MAX_WIDTH = 250;
private static final int TIME_COL_PREFERRED_WIDTH = 160;
private static final int STATUS_COL_MIN_WIDTH = 55;
private static final int STATUS_COL_MAX_WIDTH = 250;
private static final int STATUS_COL_PREFERRED_WIDTH = 60;
private static final String CASES_POPULATING_MESSAGE = NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUSerCasesPanel.caseListLoading.message");
/*
* The JTable table model for the cases table presented by this view is
* defined by the following string, enum, and array.
*
* TODO (RC): Consider unifying this stuff in an enum as in
* AutoIngestDashboard to make it less error prone.
*/
private static final String CASE_HEADER = NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.CaseHeaderText");
private static final String CREATEDTIME_HEADER = NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.CreatedTimeHeaderText");
private static final String STATUS_ICON_HEADER = NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.StatusIconHeaderText");
private static final String OUTPUT_FOLDER_HEADER = NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.OutputFolderHeaderText");
private static final String METADATA_FILE_HEADER = NbBundle.getMessage(MultiUserCasesPanel.class, "ReviewModeCasePanel.MetadataFileHeaderText");
enum COLUMN_HEADERS {
CASE,
CREATEDTIME,
STATUS_ICON,
OUTPUTFOLDER,
METADATA_FILE
}
private final String[] columnNames = {CASE_HEADER, CREATEDTIME_HEADER, STATUS_ICON_HEADER, OUTPUT_FOLDER_HEADER, METADATA_FILE_HEADER};
private DefaultTableModel caseTableModel;
private JDialog parentDialog;
private LoadTableWorker tableWorker;
private Path currentlySelectedCase;
private static final long serialVersionUID = 1L;
private final JDialog parentDialog;
private final CaseBrowser caseBrowserPanel;
/**
* Constructs a panel that allows a user to open cases created by automated
@ -99,66 +49,19 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
*/
MultiUserCasesPanel(JDialog parentDialog) {
this.parentDialog = parentDialog;
caseTableModel = new DefaultTableModel(columnNames, 0) {
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public Class<?> getColumnClass(int col) {
if (this.getColumnName(col).equals(CREATEDTIME_HEADER)) {
return Date.class;
} else {
return super.getColumnClass(col);
}
}
};
initComponents();
/*
* Configure the columns of the cases table.
*/
TableColumn theColumn;
theColumn = casesTable.getColumn(CASE_HEADER);
theColumn.setCellRenderer(new GrayableCellRenderer());
theColumn.setMinWidth(CASE_COL_MIN_WIDTH);
theColumn.setMaxWidth(CASE_COL_MAX_WIDTH);
theColumn.setPreferredWidth(CASE_COL_PREFERRED_WIDTH);
theColumn.setWidth(CASE_COL_PREFERRED_WIDTH);
theColumn = casesTable.getColumn(CREATEDTIME_HEADER);
theColumn.setCellRenderer(new LongDateCellRenderer());
theColumn.setMinWidth(TIME_COL_MIN_WIDTH);
theColumn.setMaxWidth(TIME_COL_MAX_WIDTH);
theColumn.setPreferredWidth(TIME_COL_PREFERRED_WIDTH);
theColumn.setWidth(TIME_COL_PREFERRED_WIDTH);
theColumn = casesTable.getColumn(STATUS_ICON_HEADER);
theColumn.setCellRenderer(new StatusIconCellRenderer());
theColumn.setMinWidth(STATUS_COL_MIN_WIDTH);
theColumn.setMaxWidth(STATUS_COL_MAX_WIDTH);
theColumn.setPreferredWidth(STATUS_COL_PREFERRED_WIDTH);
theColumn.setWidth(STATUS_COL_PREFERRED_WIDTH);
casesTable.removeColumn(casesTable.getColumn(OUTPUT_FOLDER_HEADER));
casesTable.removeColumn(casesTable.getColumn(METADATA_FILE_HEADER));
casesTable.setRowSorter(new RowSorter<>(caseTableModel));
casesTable.getRowSorter().toggleSortOrder(casesTable.getColumn(CREATEDTIME_HEADER).getModelIndex());
caseBrowserPanel = new CaseBrowser();
caseExplorerScrollPane.add(caseBrowserPanel);
caseExplorerScrollPane.setViewportView(caseBrowserPanel);
/*
* Listen for row selection changes and set button state for the current
* selection.
*/
casesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
//Ignore extra messages.
if (e.getValueIsAdjusting()) {
return;
}
caseBrowserPanel.addListSelectionListener((ListSelectionEvent e) -> {
setButtons();
});
}
/**
@ -166,87 +69,15 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
* refreshes the cases table.
*/
void refresh() {
if (tableWorker == null || tableWorker.isDone()) {
//create a new TableWorker to and execute it in a background thread if one is not currently working
currentlySelectedCase = getSelectedCase();
//set the table to display text informing the user that the list is being retreived and disable case selection
caseTableModel.setRowCount(0);
casesTable.setRowSelectionAllowed(false);
caseTableModel.addRow(new Object[]{CASES_POPULATING_MESSAGE, null, null, "", ""});
tableWorker = new LoadTableWorker();
tableWorker.execute();
}
}
/**
* Gets the current selection in the cases table.
*
* @return A path representing the current selected case, null if there is
* no selection.
*/
private Path getSelectedCase() {
try {
int selectedRow = casesTable.getSelectedRow();
if (selectedRow >= 0 && selectedRow < casesTable.getRowCount()) {
return Paths.get(caseTableModel.getValueAt(casesTable.convertRowIndexToModel(selectedRow), COLUMN_HEADERS.CASE.ordinal()).toString());
}
} catch (Exception ignored) {
return null;
}
return null;
}
/**
* Sets the current selection in the cases table.
*
* @param path The case folder path of the case to select.
*/
private void setSelectedCase(Path path) {
if (path != null) {
try {
for (int row = 0; row < casesTable.getRowCount(); ++row) {
Path temp = Paths.get(caseTableModel.getValueAt(casesTable.convertRowIndexToModel(row), COLUMN_HEADERS.CASE.ordinal()).toString());
if (temp.compareTo(path) == 0) { // found it
casesTable.setRowSelectionInterval(row, row);
return;
}
}
} catch (Exception ignored) {
casesTable.clearSelection();
}
}
casesTable.clearSelection();
caseBrowserPanel.refresh();
}
/**
* Enables/disables the Open and Show Log buttons based on the case selected
* in the cases table.
*/
private void setButtons() {
boolean openEnabled = casesTable.getRowSelectionAllowed() && casesTable.getSelectedRow() >= 0 && casesTable.getSelectedRow() < casesTable.getRowCount();
bnOpen.setEnabled(openEnabled);
Path pathToLog = getSelectedCaseLogFilePath();
boolean showLogEnabled = openEnabled && pathToLog != null && pathToLog.toFile().exists();
bnShowLog.setEnabled(showLogEnabled);
}
/**
* Retrieves the log file path for the selected case in the cases table.
*
* @return The case log path.
*/
private Path getSelectedCaseLogFilePath() {
Path retValue = null;
int selectedRow = casesTable.getSelectedRow();
int rowCount = casesTable.getRowCount();
if (selectedRow >= 0 && selectedRow < rowCount) {
String caseDirectory = (String) caseTableModel.getValueAt(casesTable.convertRowIndexToModel(selectedRow), COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
retValue = Paths.get(caseDirectory, LOG_FILE_NAME);
}
return retValue;
void setButtons() {
bnOpen.setEnabled(caseBrowserPanel.isRowSelected());
}
/**
@ -254,56 +85,34 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
*
* @param caseMetadataFilePath The path to the case metadata file.
*/
private void openCase(Path caseMetadataFilePath) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
private void openCase(String caseMetadataFilePath) {
if (caseMetadataFilePath != null) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
StartupWindowProvider.getInstance().close();
if (parentDialog != null) {
parentDialog.setVisible(false);
}
new Thread(() -> {
try {
MultiUserCaseManager.getInstance().openCase(caseMetadataFilePath);
} catch (CaseActionException | MultiUserCaseManager.MultiUserCaseManagerException ex) {
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
}
SwingUtilities.invokeLater(() -> {
//GUI changes done back on the EDT
StartupWindowProvider.getInstance().open();
});
} finally {
SwingUtilities.invokeLater(() -> {
//GUI changes done back on the EDT
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
});
StartupWindowProvider.getInstance().close();
if (parentDialog != null) {
parentDialog.setVisible(false);
}
}).start();
}
/**
* Indicates whether or not a time satisfies a time filter defined by this
* panel's time filter radio buttons.
*
* @param currentTime The current date and time in milliseconds from the
* Unix epoch.
* @param inputTime The date and time to be tested as milliseconds from
* the Unix epoch.
*/
private boolean passesTimeFilter(long currentTime, long inputTime) {
long numberOfUnits = 10;
long multiplier = 1;
if (rbAllCases.isSelected()) {
return true;
} else if (rbMonths.isSelected()) {
multiplier = 31;
} else if (rbWeeks.isSelected()) {
multiplier = 7;
} else if (rbDays.isSelected()) {
multiplier = 1;
new Thread(() -> {
try {
Case.openAsCurrentCase(caseMetadataFilePath);
} catch (CaseActionException ex) {
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
}
SwingUtilities.invokeLater(() -> {
//GUI changes done back on the EDT
StartupWindowProvider.getInstance().open();
});
} finally {
SwingUtilities.invokeLater(() -> {
//GUI changes done back on the EDT
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
});
}
}).start();
}
return ((currentTime - inputTime) / (1000 * 60 * 60 * 24)) < (numberOfUnits * multiplier);
}
/**
@ -345,19 +154,11 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
rbGroupHistoryLength = new javax.swing.ButtonGroup();
bnOpen = new javax.swing.JButton();
scrollPaneTable = new javax.swing.JScrollPane();
casesTable = new javax.swing.JTable();
bnRefresh = new javax.swing.JButton();
panelFilter = new javax.swing.JPanel();
rbAllCases = new javax.swing.JRadioButton();
bnShowLog = new javax.swing.JButton();
rbDays = new javax.swing.JRadioButton();
rbWeeks = new javax.swing.JRadioButton();
rbMonths = new javax.swing.JRadioButton();
rbGroupLabel = new javax.swing.JLabel();
bnOpenSingleUserCase = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
searchLabel = new javax.swing.JLabel();
caseExplorerScrollPane = new javax.swing.JScrollPane();
setName("Completed Cases"); // NOI18N
setPreferredSize(new java.awt.Dimension(960, 485));
@ -370,84 +171,6 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
}
});
casesTable.setModel(caseTableModel);
casesTable.setRowHeight(20);
casesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
casesTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
casesTableMouseClicked(evt);
}
});
scrollPaneTable.setViewportView(casesTable);
org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnRefresh.text")); // NOI18N
bnRefresh.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnRefreshActionPerformed(evt);
}
});
rbGroupHistoryLength.add(rbAllCases);
rbAllCases.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(rbAllCases, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbAllCases.text")); // NOI18N
rbAllCases.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbAllCasesItemStateChanged(evt);
}
});
javax.swing.GroupLayout panelFilterLayout = new javax.swing.GroupLayout(panelFilter);
panelFilter.setLayout(panelFilterLayout);
panelFilterLayout.setHorizontalGroup(
panelFilterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelFilterLayout.createSequentialGroup()
.addComponent(rbAllCases)
.addGap(0, 0, Short.MAX_VALUE))
);
panelFilterLayout.setVerticalGroup(
panelFilterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelFilterLayout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(rbAllCases))
);
org.openide.awt.Mnemonics.setLocalizedText(bnShowLog, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnShowLog.text")); // NOI18N
bnShowLog.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnShowLog.toolTipText")); // NOI18N
bnShowLog.setEnabled(false);
bnShowLog.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnShowLogActionPerformed(evt);
}
});
rbGroupHistoryLength.add(rbDays);
org.openide.awt.Mnemonics.setLocalizedText(rbDays, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbDays.text")); // NOI18N
rbDays.setName(""); // NOI18N
rbDays.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbDaysItemStateChanged(evt);
}
});
rbGroupHistoryLength.add(rbWeeks);
org.openide.awt.Mnemonics.setLocalizedText(rbWeeks, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbWeeks.text")); // NOI18N
rbWeeks.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbWeeksItemStateChanged(evt);
}
});
rbGroupHistoryLength.add(rbMonths);
org.openide.awt.Mnemonics.setLocalizedText(rbMonths, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbMonths.text")); // NOI18N
rbMonths.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
rbMonthsItemStateChanged(evt);
}
});
rbGroupLabel.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rbGroupLabel, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.rbGroupLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnOpenSingleUserCase, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.bnOpenSingleUserCase.text")); // NOI18N
bnOpenSingleUserCase.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -455,55 +178,45 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.cancelButton.text")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(searchLabel, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "MultiUserCasesPanel.searchLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(caseExplorerScrollPane)
.addGroup(layout.createSequentialGroup()
.addGap(4, 4, 4)
.addComponent(searchLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 555, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 175, Short.MAX_VALUE)
.addComponent(bnOpen, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnOpenSingleUserCase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnShowLog)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE)
.addComponent(rbGroupLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rbDays)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rbWeeks)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rbMonths)
.addGap(0, 0, 0)
.addComponent(panelFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(14, 14, 14)
.addComponent(bnRefresh))
.addComponent(scrollPaneTable))
.addComponent(cancelButton)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(6, 6, 6)
.addComponent(scrollPaneTable, javax.swing.GroupLayout.PREFERRED_SIZE, 450, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(caseExplorerScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 450, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnOpen)
.addComponent(bnOpenSingleUserCase)
.addComponent(bnShowLog))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(rbDays)
.addComponent(rbWeeks)
.addComponent(rbMonths)
.addComponent(rbGroupLabel))
.addComponent(panelFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(bnRefresh, javax.swing.GroupLayout.Alignment.TRAILING))
.addGap(0, 0, 0))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancelButton)
.addComponent(bnOpen)
.addComponent(bnOpenSingleUserCase)
.addComponent(searchLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@ -513,129 +226,24 @@ final class MultiUserCasesPanel extends javax.swing.JPanel {
* @param evt -- The event that caused this to be called
*/
private void bnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenActionPerformed
int modelRow = casesTable.convertRowIndexToModel(casesTable.getSelectedRow());
String caseDirectory = (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
Path caseMetadataFilePath = Paths.get(caseDirectory, (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.METADATA_FILE.ordinal()));
openCase(caseMetadataFilePath);
openCase(caseBrowserPanel.getCasePath());
}//GEN-LAST:event_bnOpenActionPerformed
/**
* Refresh button action
*
* @param evt -- The event that caused this to be called
*/
private void bnRefreshActionPerformed(java.awt.event.ActionEvent evt) {
refresh();
}
private void rbDaysItemStateChanged(java.awt.event.ItemEvent evt) {
if (rbDays.isSelected()) {
refresh();
}
}
private void rbAllCasesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbAllCasesItemStateChanged
if (rbAllCases.isSelected()) {
refresh();
}
}//GEN-LAST:event_rbAllCasesItemStateChanged
private void rbMonthsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbMonthsItemStateChanged
if (rbMonths.isSelected()) {
refresh();
}
}//GEN-LAST:event_rbMonthsItemStateChanged
private void rbWeeksItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbWeeksItemStateChanged
if (rbWeeks.isSelected()) {
refresh();
}
}//GEN-LAST:event_rbWeeksItemStateChanged
private void bnShowLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnShowLogActionPerformed
Path pathToLog = getSelectedCaseLogFilePath();
if (pathToLog != null) {
try {
if (pathToLog.toFile().exists()) {
Desktop.getDesktop().edit(pathToLog.toFile());
} else {
JOptionPane.showMessageDialog(this, org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.cannotFindLog"),
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.unableToShowLogFile"), JOptionPane.ERROR_MESSAGE);
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("Error attempting to open case auto ingest log file %s", pathToLog), ex);
JOptionPane.showMessageDialog(this,
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.cannotOpenLog"),
org.openide.util.NbBundle.getMessage(MultiUserCasesPanel.class, "DisplayLogDialog.unableToShowLogFile"),
JOptionPane.PLAIN_MESSAGE);
}
}
}//GEN-LAST:event_bnShowLogActionPerformed
private void casesTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_casesTableMouseClicked
if (evt.getClickCount() == 2 && casesTable.getRowSelectionAllowed() && casesTable.getSelectedRow() >= 0 && casesTable.getSelectedRow() < casesTable.getRowCount()) {
int modelRow = casesTable.convertRowIndexToModel(casesTable.getSelectedRow());
String caseDirectory = (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.OUTPUTFOLDER.ordinal());
Path caseMetadataFilePath = Paths.get(caseDirectory, (String) caseTableModel.getValueAt(modelRow, COLUMN_HEADERS.METADATA_FILE.ordinal()));
openCase(caseMetadataFilePath);
}
}//GEN-LAST:event_casesTableMouseClicked
private void bnOpenSingleUserCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOpenSingleUserCaseActionPerformed
Lookup.getDefault().lookup(CaseOpenAction.class).openCaseSelectionWindow();
}//GEN-LAST:event_bnOpenSingleUserCaseActionPerformed
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
if (parentDialog != null) {
parentDialog.setVisible(false);
}
}//GEN-LAST:event_cancelButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnOpen;
private javax.swing.JButton bnOpenSingleUserCase;
private javax.swing.JButton bnRefresh;
private javax.swing.JButton bnShowLog;
private javax.swing.JTable casesTable;
private javax.swing.JPanel panelFilter;
private javax.swing.JRadioButton rbAllCases;
private javax.swing.JRadioButton rbDays;
private javax.swing.ButtonGroup rbGroupHistoryLength;
private javax.swing.JLabel rbGroupLabel;
private javax.swing.JRadioButton rbMonths;
private javax.swing.JRadioButton rbWeeks;
private javax.swing.JScrollPane scrollPaneTable;
private javax.swing.JButton cancelButton;
private javax.swing.JScrollPane caseExplorerScrollPane;
private javax.swing.JLabel searchLabel;
// End of variables declaration//GEN-END:variables
private class LoadTableWorker extends SwingWorker<Void, Void> {
private List<MultiUserCase> cases;
@Override
protected Void doInBackground() throws Exception {
try {
MultiUserCaseManager manager = MultiUserCaseManager.getInstance();
cases = manager.getCases();
} catch (MultiUserCaseManager.MultiUserCaseManagerException | CoordinationService.CoordinationServiceException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while refreshing the table.", ex); //NON-NLS
}
return null;
}
@Override
protected void done() {
caseTableModel.setRowCount(0);
long now = new Date().getTime();
for (MultiUserCase autoIngestCase : cases) {
if (autoIngestCase.getCreationDate() != null && passesTimeFilter(now, autoIngestCase.getCreationDate().getTime())) {
caseTableModel.addRow(new Object[]{
autoIngestCase.getCaseDisplayName(),
autoIngestCase.getCreationDate(),
(MultiUserCaseManager.CaseStatus.OK != autoIngestCase.getStatus()) ? StatusIconCellRenderer.Status.WARNING : StatusIconCellRenderer.Status.OK,
autoIngestCase.getCaseDirectoryPath().toString(),
autoIngestCase.getMetadataFileName()});
}
}
//ensure the cases are able to be selected
casesTable.setRowSelectionAllowed(true);
setSelectedCase(currentlySelectedCase);
setButtons();
}
}
}

View File

@ -0,0 +1,241 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2017-2018 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.casemodule;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
/**
* A root node containing child nodes of the multi user cases
*/
final class MultiUserNode extends AbstractNode {
@Messages({"CaseNode.column.name=Name",
"CaseNode.column.createdTime=Created Time",
"CaseNode.column.status=Status",
"CaseNode.column.metadataFilePath=Path"})
private static final Logger LOGGER = Logger.getLogger(MultiUserNode.class.getName());
private static final String LOG_FILE_NAME = "auto_ingest_log.txt";
/**
* Provides a root node with children which each represent a case.
*
* @param caseMap the map of cases and a boolean indicating if they have an
* alert
*/
MultiUserNode(Map<CaseMetadata, Boolean> caseMap) {
super(Children.create(new MultiUserNodeChildren(caseMap), true));
}
static class MultiUserNodeChildren extends ChildFactory<Entry<CaseMetadata, Boolean>> {
private final Map<CaseMetadata, Boolean> caseMap;
MultiUserNodeChildren(Map<CaseMetadata, Boolean> caseMap) {
this.caseMap = caseMap;
}
@Override
protected boolean createKeys(List<Entry<CaseMetadata, Boolean>> list) {
if (caseMap != null && caseMap.size() > 0) {
list.addAll(caseMap.entrySet());
}
return true;
}
@Override
protected Node createNodeForKey(Entry<CaseMetadata, Boolean> key) {
return new MultiUserCaseNode(key);
}
}
/**
* A node which represents a single multi user case.
*/
static final class MultiUserCaseNode extends AbstractNode {
private final String caseName;
private final String caseCreatedDate;
private final String caseMetadataFilePath;
private final boolean caseHasAlert;
private final Path caseLogFilePath;
MultiUserCaseNode(Entry<CaseMetadata, Boolean> multiUserCase) {
super(Children.LEAF);
caseName = multiUserCase.getKey().getCaseDisplayName();
caseCreatedDate = multiUserCase.getKey().getCreatedDate();
caseHasAlert = multiUserCase.getValue();
super.setName(caseName);
setName(caseName);
setDisplayName(caseName);
caseMetadataFilePath = multiUserCase.getKey().getFilePath().toString();
caseLogFilePath = Paths.get(multiUserCase.getKey().getCaseDirectory(), LOG_FILE_NAME);
}
/**
* Returns action to open the Case represented by this node
* @return an action which will open the current case
*/
@Override
public Action getPreferredAction() {
return new OpenMultiUserCaseAction(caseMetadataFilePath);
}
@Messages({"MultiUserNode.AlertColumn.text=Alert"}) //text to display when there is an alert present
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
if (ss == null) {
ss = Sheet.createPropertiesSet();
s.put(ss);
}
ss.put(new NodeProperty<>(Bundle.CaseNode_column_name(), Bundle.CaseNode_column_name(), Bundle.CaseNode_column_name(),
caseName));
ss.put(new NodeProperty<>(Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
caseCreatedDate));
ss.put(new NodeProperty<>(Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(), Bundle.CaseNode_column_status(),
(caseHasAlert == true ? Bundle.MultiUserNode_AlertColumn_text() : "")));
ss.put(new NodeProperty<>(Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath(),
caseMetadataFilePath));
return s;
}
@Override
public Action[] getActions(boolean context) {
List<Action> actions = new ArrayList<>();
actions.add(new OpenMultiUserCaseAction(caseMetadataFilePath)); //open case context menu option
actions.add(new OpenCaseLogAction(caseLogFilePath));
return actions.toArray(new Action[actions.size()]);
}
}
@Messages({"MultiUserNode.OpenMultiUserCaseAction.text=Open Case"})
/**
* An action that opens the specified case and hides the multi user case
* panel.
*/
private static final class OpenMultiUserCaseAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final String caseMetadataFilePath;
OpenMultiUserCaseAction(String path) {
super(Bundle.MultiUserNode_OpenMultiUserCaseAction_text());
caseMetadataFilePath = path;
}
@Override
public void actionPerformed(ActionEvent e) {
StartupWindowProvider.getInstance().close();
MultiUserCasesDialog.getInstance().setVisible(false);
new Thread(
() -> {
try {
Case.openAsCurrentCase(caseMetadataFilePath);
} catch (CaseActionException ex) {
if (null != ex.getCause() && !(ex.getCause() instanceof CaseActionCancelledException)) {
LOGGER.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetadataFilePath), ex); //NON-NLS
MessageNotifyUtil.Message.error(ex.getCause().getLocalizedMessage());
}
SwingUtilities.invokeLater(() -> {
//GUI changes done back on the EDT
StartupWindowProvider.getInstance().open();
MultiUserCasesDialog.getInstance().setVisible(true);
});
}
}
).start();
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); //To change body of generated methods, choose Tools | Templates.
}
}
@Messages({"MultiUserNode.OpenCaseLogAction.text=Open Log File"})
/**
* An action that opens the specified case and hides the multi user case
* panel.
*/
private static final class OpenCaseLogAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final Path pathToLog;
OpenCaseLogAction(Path caseLogFilePath) {
super(Bundle.MultiUserNode_OpenCaseLogAction_text());
pathToLog = caseLogFilePath;
this.setEnabled(caseLogFilePath != null && caseLogFilePath.toFile().exists());
}
@Override
public void actionPerformed(ActionEvent e) {
if (pathToLog != null) {
try {
if (pathToLog.toFile().exists()) {
Desktop.getDesktop().edit(pathToLog.toFile());
} else {
JOptionPane.showMessageDialog(MultiUserCasesDialog.getInstance(), org.openide.util.NbBundle.getMessage(MultiUserNode.class, "DisplayLogDialog.cannotFindLog"),
org.openide.util.NbBundle.getMessage(MultiUserNode.class, "DisplayLogDialog.unableToShowLogFile"), JOptionPane.ERROR_MESSAGE);
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("Error attempting to open case auto ingest log file %s", pathToLog), ex);
JOptionPane.showMessageDialog(MultiUserCasesDialog.getInstance(),
org.openide.util.NbBundle.getMessage(MultiUserNode.class, "DisplayLogDialog.cannotOpenLog"),
org.openide.util.NbBundle.getMessage(MultiUserNode.class, "DisplayLogDialog.unableToShowLogFile"),
JOptionPane.PLAIN_MESSAGE);
}
}
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); //To change body of generated methods, choose Tools | Templates.
}
}
}

View File

@ -33,3 +33,7 @@ MessageContentViewer.directionText.text=direction
MessageContentViewer.ccLabel.text=CC:
MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments
MessageContentViewer.viewInNewWindowButton.text=View in New Window
JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file:
JPEGViewerDummy.jTextField1.text=jTextField1
SQLiteViewer.jLabel1.text=Table
SQLiteViewer.numEntriesField.text=num Entries

View File

@ -0,0 +1,50 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import java.awt.Component;
import java.util.List;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Defines an interface for application specific content viewer
*
*/
interface FileTypeViewer {
/**
* Returns list of MIME types supported by this viewer
*/
List<String> getSupportedMIMETypes();
/**
* Display the given file's content in the view panel
*/
void setFile(AbstractFile file);
/**
* Returns panel
*/
Component getComponent();
/**
* Clears the data in the panel
*/
void resetComponent();
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<LayoutCode>
<CodeStatement>
<CodeExpression id="1">
<ExpressionOrigin>
<ExpressionProvider type="ComponentRef">
<ComponentRef name="."/>
</ExpressionProvider>
</ExpressionOrigin>
</CodeExpression>
<StatementProvider type="CodeMethod">
<CodeMethod name="setLayout" class="java.awt.Container" parameterTypes="java.awt.LayoutManager"/>
</StatementProvider>
<Parameters>
<CodeExpression id="2">
<ExpressionOrigin>
<ExpressionProvider type="CodeConstructor">
<CodeConstructor class="javax.swing.OverlayLayout" parameterTypes="java.awt.Container"/>
</ExpressionProvider>
<Parameters>
<CodeExpression id="1"/>
</Parameters>
</ExpressionOrigin>
</CodeExpression>
</Parameters>
</CodeStatement>
</LayoutCode>
</Form>

View File

@ -0,0 +1,235 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import com.google.common.base.Strings;
import java.awt.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Generic Application content viewer
*/
@ServiceProvider(service = DataContentViewer.class, position = 5)
public class FileViewer extends javax.swing.JPanel implements DataContentViewer {
private static final int CONFIDENCE_LEVEL = 7;
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName());
private final Map<String, FileTypeViewer> mimeTypeToViewerMap = new HashMap<>();
// TBD: This hardcoded list of viewers should be replaced with a dynamic lookup
private static final FileTypeViewer[] KNOWN_VIEWERS = new FileTypeViewer[]{
// new JPEGViewerDummy(), // this if for testing only
new SQLiteViewer()
};
private FileTypeViewer lastViewer;
/**
* Creates new form ApplicationContentViewer
*/
public FileViewer() {
// init the mimetype to viewer map
for (FileTypeViewer cv : KNOWN_VIEWERS) {
cv.getSupportedMIMETypes().forEach((mimeType) -> {
if (mimeTypeToViewerMap.containsKey(mimeType) == false) {
mimeTypeToViewerMap.put(mimeType, cv);
} else {
LOGGER.log(Level.WARNING, "Duplicate viewer for mimtype: {0}", mimeType); //NON-NLS
}
});
}
initComponents();
LOGGER.log(Level.INFO, "Created ApplicationContentViewer instance: {0}", this); //NON-NLS
}
/**
* Get the FileTypeViewer for a given mimetype
*
* @param mimeType
*
* @return FileTypeViewer, null if no known content viewer supports the mimetype
*/
private FileTypeViewer getSupportingViewer(String mimeType) {
return mimeTypeToViewerMap.get(mimeType);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new javax.swing.OverlayLayout(this));
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
@Override
public void setNode(Node selectedNode) {
resetComponent();
if (selectedNode == null) {
return;
}
AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
if (file == null) {
return;
}
String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
try {
FileTypeDetector fileTypeDetector = new FileTypeDetector();
mimeType = fileTypeDetector.detectMIMEType(file);
}catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize FileTypeDetector.", ex); //NON-NLS
return;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return;
}
else {
FileTypeViewer viewer = getSupportingViewer(mimeType);
if (viewer != null) {
lastViewer = viewer;
viewer.setFile(file);
this.removeAll();
this.add(viewer.getComponent());
this.repaint();
}
}
}
@Override
@NbBundle.Messages("ApplicationContentViewer.title=Application")
public String getTitle() {
return Bundle.ApplicationContentViewer_title();
}
@Override
@NbBundle.Messages("ApplicationContentViewer.toolTip=Displays file contents.")
public String getToolTip() {
return Bundle.ApplicationContentViewer_toolTip();
}
@Override
public DataContentViewer createInstance() {
return new FileViewer();
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
if (lastViewer != null) {
lastViewer.resetComponent();
}
this.removeAll();
lastViewer = null;
}
@Override
public boolean isSupported(Node node) {
if (node == null) {
return false;
}
AbstractFile aFile = node.getLookup().lookup(AbstractFile.class);
if (aFile == null) {
return false;
}
String mimeType = aFile.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", aFile.getName()); //NON-NLS
try {
FileTypeDetector fileTypeDetector = new FileTypeDetector();
mimeType = fileTypeDetector.detectMIMEType(aFile);
}catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize FileTypeDetector.", ex); //NON-NLS
return false;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return false;
} else {
return (getSupportingViewer(mimeType) != null);
}
}
@Override
public int isPreferred(Node node) {
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
try {
FileTypeDetector fileTypeDetector = new FileTypeDetector();
mimeType = fileTypeDetector.detectMIMEType(file);
}catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize FileTypeDetector.", ex); //NON-NLS
return 0;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return 0;
} else {
if (null != getSupportingViewer(mimeType)) {
return CONFIDENCE_LEVEL;
}
}
return 0;
}
}

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="43" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="35" max="-2" attributes="0"/>
<Component id="jTextField1" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="120" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="269" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="JPEGViewerDummy.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="jTextField1">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="JPEGViewerDummy.jTextField1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,89 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.contentviewers;
import java.awt.Component;
import java.util.Arrays;
import java.util.List;
import org.sleuthkit.datamodel.AbstractFile;
public class JPEGViewerDummy extends javax.swing.JPanel implements FileTypeViewer {
public static final String[] SUPPORTED_MIMETYPES = new String[]{"image/jpeg"};
/**
* Creates new form JPEGViewer
*/
public JPEGViewerDummy() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
jTextField1 = new javax.swing.JTextField();
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(JPEGViewerDummy.class, "JPEGViewerDummy.jLabel1.text")); // NOI18N
jTextField1.setEditable(false);
jTextField1.setText(org.openide.util.NbBundle.getMessage(JPEGViewerDummy.class, "JPEGViewerDummy.jTextField1.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(43, 43, 43)
.addComponent(jLabel1)
.addGap(35, 35, 35)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(120, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(269, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@Override
public List<String> getSupportedMIMETypes() {
return Arrays.asList(SUPPORTED_MIMETYPES);
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
this.jTextField1.setText("");
}
@Override
public void setFile(AbstractFile file) {
this.jTextField1.setText(file.getName());
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel1;
private javax.swing.JTextField jTextField1;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jHdrPanel" alignment="0" max="32767" attributes="0"/>
<Component id="jTableDataPanel" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jHdrPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="jTableDataPanel" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="jHdrPanel">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="tablesDropdownList" min="-2" pref="130" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
<Component id="numEntriesField" min="-2" pref="71" max="-2" attributes="0"/>
<EmptySpace pref="130" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="tablesDropdownList" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="numEntriesField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="16" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JComboBox" name="tablesDropdownList">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tablesDropdownListActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="numEntriesField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.numEntriesField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="numEntriesFieldActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jTableDataPanel">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="275" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="jTable1">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="4" rowCount="4">
<Column editable="true" title="Title 1" type="java.lang.Object"/>
<Column editable="true" title="Title 2" type="java.lang.Object"/>
<Column editable="true" title="Title 3" type="java.lang.Object"/>
<Column editable="true" title="Title 4" type="java.lang.Object"/>
</Table>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,395 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import java.awt.Component;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
import javax.swing.JComboBox;
import javax.swing.SwingWorker;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.AbstractFile;
public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
public static final String[] SUPPORTED_MIMETYPES = new String[]{"application/x-sqlite3"};
private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName());
private Connection connection = null;
private String tmpDBPathName = null;
private File tmpDBFile = null;
// TBD: Change the value to be a Array of ColDefs
Map<String, String> dbTablesMap = new TreeMap<>();
/**
* Creates new form SQLiteViewer
*/
public SQLiteViewer() {
initComponents();
customizeComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jHdrPanel = new javax.swing.JPanel();
tablesDropdownList = new javax.swing.JComboBox<>();
jLabel1 = new javax.swing.JLabel();
numEntriesField = new javax.swing.JTextField();
jTableDataPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
tablesDropdownList.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
tablesDropdownList.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tablesDropdownListActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.jLabel1.text")); // NOI18N
numEntriesField.setEditable(false);
numEntriesField.setText(org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.numEntriesField.text")); // NOI18N
numEntriesField.setBorder(null);
numEntriesField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
numEntriesFieldActionPerformed(evt);
}
});
javax.swing.GroupLayout jHdrPanelLayout = new javax.swing.GroupLayout(jHdrPanel);
jHdrPanel.setLayout(jHdrPanelLayout);
jHdrPanelLayout.setHorizontalGroup(
jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jHdrPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(23, 23, 23)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(130, Short.MAX_VALUE))
);
jHdrPanelLayout.setVerticalGroup(
jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jHdrPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(16, Short.MAX_VALUE))
);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null}
},
new String [] {
"Title 1", "Title 2", "Title 3", "Title 4"
}
));
jScrollPane1.setViewportView(jTable1);
javax.swing.GroupLayout jTableDataPanelLayout = new javax.swing.GroupLayout(jTableDataPanel);
jTableDataPanel.setLayout(jTableDataPanelLayout);
jTableDataPanelLayout.setHorizontalGroup(
jTableDataPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jTableDataPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGap(15, 15, 15))
);
jTableDataPanelLayout.setVerticalGroup(
jTableDataPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jTableDataPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE)
.addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jHdrPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jTableDataPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jHdrPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jTableDataPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void numEntriesFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_numEntriesFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_numEntriesFieldActionPerformed
private void tablesDropdownListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tablesDropdownListActionPerformed
JComboBox<String> cb = (JComboBox<String>) evt.getSource();
String tableName = (String) cb.getSelectedItem();
if (null == tableName) {
return;
}
readTable(tableName);
}//GEN-LAST:event_tablesDropdownListActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel jHdrPanel;
private javax.swing.JLabel jLabel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
private javax.swing.JPanel jTableDataPanel;
private javax.swing.JTextField numEntriesField;
private javax.swing.JComboBox<String> tablesDropdownList;
// End of variables declaration//GEN-END:variables
@Override
public List<String> getSupportedMIMETypes() {
return Arrays.asList(SUPPORTED_MIMETYPES);
}
@Override
public void setFile(AbstractFile file) {
processSQLiteFile(file);
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
dbTablesMap.clear();
tablesDropdownList.setEnabled(true);
tablesDropdownList.removeAllItems();
numEntriesField.setText("");
// close DB connection to file
if (null != connection) {
try {
connection.close();
connection = null;
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to close DB connection to file.", ex); //NON-NLS
}
}
// delete last temp file
if (null != tmpDBFile) {
tmpDBFile.delete();
tmpDBFile = null;
}
}
private void customizeComponents() {
// add a actionListener to jTablesComboBox
}
/**
* Process the given SQLite DB file
*
* @param sqliteFile -
*
* @return none
*/
private void processSQLiteFile(AbstractFile sqliteFile) {
tablesDropdownList.removeAllItems();
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
try {
// Copy the file to temp folder
tmpDBPathName = Case.getCurrentCase().getTempDirectory() + File.separator + sqliteFile.getName() + "-" + sqliteFile.getId();
tmpDBFile = new File(tmpDBPathName);
ContentUtils.writeToFile(sqliteFile, tmpDBFile);
// Open copy using JDBC
Class.forName("org.sqlite.JDBC"); //NON-NLS //load JDBC driver
connection = DriverManager.getConnection("jdbc:sqlite:" + tmpDBPathName); //NON-NLS
// Read all table names and schema
return getTables();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Failed to copy DB file.", ex); //NON-NLS
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to Open DB.", ex); //NON-NLS
} catch (ClassNotFoundException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize JDBC Sqlite.", ex); //NON-NLS
}
return false;
}
@Override
protected void done() {
super.done();
try {
boolean status = get();
if ((status == true) && (dbTablesMap.size() > 0)) {
dbTablesMap.keySet().forEach((tableName) -> {
tablesDropdownList.addItem(tableName);
});
} else {
// Populate error message
tablesDropdownList.addItem("No tables found");
tablesDropdownList.setEnabled(false);
}
} catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while opening DB file", ex); //NON-NLS
}
}
}.execute();
}
/**
* Gets the table names and their schema from loaded SQLite db file
*
* @return true if success, false otherwise
*/
private boolean getTables() {
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(
"SELECT name, sql FROM sqlite_master "
+ " WHERE type= 'table' "
+ " ORDER BY name;"); //NON-NLS
while (resultSet.next()) {
String tableName = resultSet.getString("name"); //NON-NLS
String tableSQL = resultSet.getString("sql"); //NON-NLS
dbTablesMap.put(tableName, tableSQL);
String query = "PRAGMA table_info(" + tableName + ")"; //NON-NLS
ResultSet rs2;
try {
Statement statement2 = connection.createStatement();
rs2 = statement2.executeQuery(query);
while (rs2.next()) {
// System.out.println("RAMAN: Col Name = " + rs2.getString("name"));
// System.out.println("RAMAN: Col Type = " + rs2.getString("type"));
// RAMAN TBD: parse and save the table schema
}
} catch (Exception ex) {
LOGGER.log(Level.WARNING, "Error while trying to get columns from sqlite db." + connection, ex); //NON-NLS
}
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error getting table names from the DB", e); //NON-NLS
}
return true;
}
private void readTable(String tableName) {
// TBD: need to handle cancelling if one is already in progress
new SwingWorker<Integer, Void>() {
@Override
protected Integer doInBackground() throws Exception {
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(
"SELECT COUNT(*) as count FROM " + tableName); //NON-NLS
// TBD: read the rows here and popluate the ExplorerManager.
return resultSet.getInt("count");
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to get data for table.", ex); //NON-NLS
}
//NON-NLS
return 0;
}
@Override
protected void done() {
super.done();
try {
int numRows = get();
numEntriesField.setText(numRows + " entries");
} catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while reading table.", ex); //NON-NLS
}
}
}.execute();
}
enum SQLStorageClass {
NULL,
INTEGER,
REAL,
TEXT,
BLOB
};
private class SQLColDef {
private final String colName;
private final SQLStorageClass storageClass;
SQLColDef(String colName, SQLStorageClass sc) {
this.colName = colName;
this.storageClass = sc;
}
}
}

View File

@ -178,7 +178,7 @@ final class AddRawImageTask implements Runnable {
logger.log(Level.SEVERE, errorMessage, ex);
criticalErrorOccurred = true;
} finally {
caseDatabase.releaseSingleUserCaseReadLock();
caseDatabase.releaseSingleUserCaseWriteLock();
}
}

View File

@ -0,0 +1,7 @@
SelectDriveDialog.bnOk.text=Ok
SelectDriveDialog.bnRefresh.text=Refresh
SelectDriveDialog.lbSelectDrive.text=Select the drive to copy the application and script to:
SelectDriveDialog.jLabel1.text=Select drive to use for live triage (may take time to load):
SelectDriveDialog.errorLabel.text=jLabel2
SelectDriveDialog.bnCancel.text=Cancel
SelectDriveDialog.jTextArea1.text=This feature copies the application and a batch file to a removable drive,\nallowing systems to be analyzed without installing the software or\nimaging the drives.\n\nTo analyze a system, insert the drive and run "RunFromUSB.bat" as\nadministrator, then select the "Local Disk" option on the Add Data Source\npanel.

View File

@ -0,0 +1,284 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.livetriage;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.InvalidPathException;
import java.util.logging.Level;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import javax.swing.JOptionPane;
import java.awt.Frame;
import javax.swing.SwingWorker;
import org.apache.commons.io.FileUtils;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.livetriage.CreateLiveTriageDriveAction")
@ActionReference(path = "Menu/Tools", position = 1401)
@ActionRegistration(displayName = "#CTL_CreateLiveTriageDriveAction", lazy = false)
@NbBundle.Messages({"CTL_CreateLiveTriageDriveAction=Make Live Triage Drive"})
public final class CreateLiveTriageDriveAction extends CallableSystemAction implements PropertyChangeListener {
private static final String DISPLAY_NAME = Bundle.CTL_CreateLiveTriageDriveAction();
private ModalDialogProgressIndicator progressIndicator = null;
private String drivePath = "";
private CopyFilesWorker worker;
@Override
public boolean isEnabled() {
return true;
}
@NbBundle.Messages({"CreateLiveTriageDriveAction.error.title=Error creating live triage disk",
"CreateLiveTriageDriveAction.exenotfound.message=Executable could not be found",
"CreateLiveTriageDriveAction.batchFileError.message=Error creating batch file",
"CreateLiveTriageDriveAction.appPathError.message=Could not location application directory",
"CreateLiveTriageDriveAction.copyError.message=Could not copy application. Only works on installed version.",
"CreateLiveTriageDriveAction.success.title=Success",
"CreateLiveTriageDriveAction.success.message=Live triage drive created. Use RunFromUSB.bat to run the application"
})
@Override
@SuppressWarnings("fallthrough")
public void performAction() {
Frame mainWindow = WindowManager.getDefault().getMainWindow();
// If this is an installed version, there should be an <appName>64.exe file in the bin folder
String appName = UserPreferences.getAppName();
String exeName = appName + "64.exe";
String installPath = PlatformUtil.getInstallPath();
Path exePath = Paths.get(installPath, "bin", exeName);
if (!exePath.toFile().exists()) {
JOptionPane.showMessageDialog(mainWindow,
Bundle.CreateLiveTriageDriveAction_exenotfound_message(),
Bundle.CreateLiveTriageDriveAction_error_title(),
JOptionPane.ERROR_MESSAGE);
return;
}
Path applicationBasePath;
try {
applicationBasePath = exePath.getParent().getParent();
} catch (InvalidPathException ex) {
JOptionPane.showMessageDialog(mainWindow,
Bundle.CreateLiveTriageDriveAction_appPathError_message(),
Bundle.CreateLiveTriageDriveAction_error_title(),
JOptionPane.ERROR_MESSAGE);
return;
}
SelectDriveDialog driveDialog = new SelectDriveDialog(mainWindow, true);
driveDialog.display();
if (!driveDialog.getSelectedDrive().isEmpty()) {
drivePath = driveDialog.getSelectedDrive();
if (drivePath.startsWith("\\\\.\\")) {
drivePath = drivePath.substring(4);
}
worker = new CopyFilesWorker(applicationBasePath, drivePath, appName);
worker.addPropertyChangeListener(this);
worker.execute();
}
}
@NbBundle.Messages({"# {0} - drivePath",
"CreateLiveTriageDriveAction.progressBar.text=Copying live triage files to {0}",
"CreateLiveTriageDriveAction.progressBar.title=Please wait"})
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())
&& (SwingWorker.StateValue.STARTED.equals(evt.getNewValue()))) {
// Setup progress bar.
String displayStr = NbBundle.getMessage(this.getClass(), "CreateLiveTriageDriveAction.progressBar.text",
drivePath);
progressIndicator = new ModalDialogProgressIndicator(WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(this.getClass(), "CreateLiveTriageDriveAction.progressBar.title"));
progressIndicator.start(displayStr);
} else if ("state".equals(evt.getPropertyName())
&& (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) {
if (progressIndicator != null) {
progressIndicator.finish();
}
if (worker.hadError()) {
MessageNotifyUtil.Message.error(NbBundle.getMessage(CopyFilesWorker.class, "CopyFilesWorker.error.text"));
} else {
MessageNotifyUtil.Message.info(NbBundle.getMessage(CopyFilesWorker.class, "CopyFilesWorker.done.text"));
}
}
}
private class CopyFilesWorker extends SwingWorker<Void, Void> {
private final Path sourceFolder;
private final String drivePath;
private final String appName;
private boolean error = false;
CopyFilesWorker(Path sourceFolder, String drivePath, String appName) {
this.sourceFolder = sourceFolder;
this.drivePath = drivePath;
this.appName = appName;
}
boolean hadError() {
return error;
}
@Override
protected Void doInBackground() throws Exception {
copyBatchFile(drivePath, appName);
copyApplication(sourceFolder, drivePath, appName);
return null;
}
@NbBundle.Messages({"CopyFilesWorker.error.text=Error copying live triage files",
"CopyFilesWorker.done.text=Finished creating live triage disk"})
@Override
protected void done() {
try {
super.get();
} catch (Exception ex) {
error = true;
Logger.getLogger(CreateLiveTriageDriveAction.class.getName()).log(Level.SEVERE, "Fatal error during live triage drive creation", ex); //NON-NLS
}
}
}
private void copyApplication(Path sourceFolder, String destBaseFolder, String appName) throws IOException {
// Create an appName folder in the destination
Path destAppFolder = Paths.get(destBaseFolder, appName);
if (!destAppFolder.toFile().exists()) {
if (!destAppFolder.toFile().mkdirs()) {
throw new IOException("Failed to create directory " + destAppFolder.toString());
}
}
// Now copy the files
FileUtils.copyDirectory(sourceFolder.toFile(), destAppFolder.toFile());
}
private void copyBatchFile(String destPath, String appName) throws IOException, InvalidPathException {
Path batchFilePath = Paths.get(destPath, "RunFromUSB.bat");
FileUtils.writeStringToFile(batchFilePath.toFile(), getBatchFileContents(appName), "UTF-8");
}
private String getBatchFileContents(String appName) {
String batchFile
= "@echo off\n"
+ "\n"
+ "REM This restores the working directory when using 'Run as administrator'"
+ "@setlocal enableextensions\n"
+ "@cd /d \"%~dp0\""
+ "\n"
+ "SET appName=\"" + appName + "\"\n"
+ "\n"
+ "REM Create the configData directory. Exit if it does not exist after attempting to create it\n"
+ "if not exist configData mkdir configData\n"
+ "if not exist configData (\n"
+ " echo Error creating directory configData\n"
+ " goto end\n"
+ ")\n"
+ "\n"
+ "REM Create the userdir sub directory. Exit if it does not exist after attempting to create it\n"
+ "if not exist configData\\userdir mkdir configData\\userdir\n"
+ "if not exist configData\\userdir (\n"
+ " echo Error creating directory configData\\userdir\n"
+ " goto end\n"
+ ")\n"
+ "\n"
+ "REM Create the cachedir sub directory. Exit if it does not exist after attempting to create it\n"
+ "REM If it exists to start with, delete it to clear out old data\n"
+ "if exist configData\\cachedir rd /s /q configData\\cachedir\n"
+ "mkdir configData\\cachedir\n"
+ "if not exist configData\\cachedir (\n"
+ " echo Error creating directory configData\\cachedir\n"
+ " goto end\n"
+ ")\n"
+ "\n"
+ "REM Create the temp sub directory. Exit if it does not exist after attempting to create it\n"
+ "REM If it exists to start with, delete it to clear out old data\n"
+ "if exist configData\\temp rd /s /q configData\\temp\n"
+ "mkdir configData\\temp\n"
+ "if not exist configData\\temp (\n"
+ " echo Error creating directory configData\\temp\n"
+ " goto end\n"
+ ")\n"
+ "\n"
+ "REM Create the cases directory. It's ok if this fails.\n"
+ "if not exist cases mkdir cases\n"
+ "\n"
+ "if exist %appName% (\n"
+ " if not exist %appName%\\bin\\%appName%64.exe (\n"
+ " echo %appName%\\bin\\%appName%64.exe does not exist\n"
+ " goto end\n"
+ " )\n"
+ " %appName%\\bin\\%appName%64.exe --userdir ..\\configData\\userdir --cachedir ..\\configData\\cachedir -J-Djava.io.tmpdir=..\\configData\\temp\n"
+ ") else (\n"
+ " echo Could not find %appName% directory\n"
+ " goto end\n"
+ ")\n"
+ "\n"
+ ":end\n"
+ "\n"
+ "REM Keep the cmd window open in case there was an error\n"
+ "@pause\n";
return batchFile;
}
@Override
public String getName() {
return DISPLAY_NAME;
}
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
@Override
public boolean asynchronous() {
return false; // run on edt
}
}

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="bnRefresh" pref="112" max="32767" attributes="0"/>
<EmptySpace pref="48" max="32767" attributes="0"/>
<Component id="bnOk" min="-2" pref="101" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" pref="101" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="0" pref="0" max="32767" attributes="0"/>
<Component id="jLabel1" alignment="0" max="32767" attributes="0"/>
<Component id="jSeparator1" alignment="0" max="32767" attributes="0"/>
<Component id="errorLabel" alignment="0" max="32767" attributes="0"/>
<Component id="jScrollPane2" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane2" min="-2" pref="107" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="112" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnRefresh" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnOk" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="diskTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="model" type="code"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/livetriage/Bundle.properties" key="SelectDriveDialog.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnRefresh">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/livetriage/Bundle.properties" key="SelectDriveDialog.bnRefresh.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnRefreshActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnOk">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/livetriage/Bundle.properties" key="SelectDriveDialog.bnOk.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOkActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="errorLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/livetriage/Bundle.properties" key="SelectDriveDialog.errorLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JSeparator" name="jSeparator1">
</Component>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/livetriage/Bundle.properties" key="SelectDriveDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="jTextArea1">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="0"/>
</Property>
<Property name="rows" type="int" value="5"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/livetriage/Bundle.properties" key="SelectDriveDialog.jTextArea1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,388 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.livetriage;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.LocalDisk;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
/**
*
*/
class SelectDriveDialog extends javax.swing.JDialog {
private List<LocalDisk> disks = new ArrayList<>();
private final LocalDiskModel model = new LocalDiskModel();
private final java.awt.Frame parent;
private String drivePath = "";
/**
* Creates new form SelectDriveDialog
*/
@NbBundle.Messages({"SelectDriveDialog.title=Create Live Triage Drive"})
SelectDriveDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
this.parent = parent;
model.loadDisks();
bnOk.setEnabled(false);
diskTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (diskTable.getSelectedRow() >= 0 && diskTable.getSelectedRow() < disks.size()) {
bnOk.setEnabled(true);
} else { //The selection changed to nothing valid being selected, such as with ctrl+click
bnOk.setEnabled(false);
}
}
});
}
void display() {
this.setTitle(Bundle.SelectDriveDialog_title());
final Dimension parentSize = parent.getSize();
final Point parentLocationOnScreen = parent.getLocationOnScreen();
final Dimension childSize = this.getSize();
int x;
int y;
x = (parentSize.width - childSize.width) / 2;
y = (parentSize.height - childSize.height) / 2;
x += parentLocationOnScreen.x;
y += parentLocationOnScreen.y;
setLocation(x, y);
setVisible(true);
}
String getSelectedDrive() {
return this.drivePath;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
diskTable = new javax.swing.JTable();
jLabel1 = new javax.swing.JLabel();
bnRefresh = new javax.swing.JButton();
bnOk = new javax.swing.JButton();
errorLabel = new javax.swing.JLabel();
jSeparator1 = new javax.swing.JSeparator();
bnCancel = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
diskTable.setModel(model);
jScrollPane1.setViewportView(diskTable);
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, "SelectDriveDialog.jLabel1.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, "SelectDriveDialog.bnRefresh.text")); // NOI18N
bnRefresh.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnRefreshActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(bnOk, org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, "SelectDriveDialog.bnOk.text")); // NOI18N
bnOk.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnOkActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(errorLabel, org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, "SelectDriveDialog.errorLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, "SelectDriveDialog.bnCancel.text")); // NOI18N
bnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnCancelActionPerformed(evt);
}
});
jScrollPane2.setBorder(null);
jTextArea1.setBackground(new java.awt.Color(240, 240, 240));
jTextArea1.setColumns(20);
jTextArea1.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
jTextArea1.setRows(5);
jTextArea1.setText(org.openide.util.NbBundle.getMessage(SelectDriveDialog.class, "SelectDriveDialog.jTextArea1.text")); // NOI18N
jTextArea1.setBorder(null);
jScrollPane2.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(bnRefresh, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 48, Short.MAX_VALUE)
.addComponent(bnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jSeparator1)
.addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jScrollPane2))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnRefresh)
.addComponent(bnCancel)
.addComponent(bnOk))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(errorLabel)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void bnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnRefreshActionPerformed
model.loadDisks();
}//GEN-LAST:event_bnRefreshActionPerformed
private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed
if (diskTable.getSelectedRow() >= 0 && diskTable.getSelectedRow() < disks.size()) {
LocalDisk selectedDisk = disks.get(diskTable.getSelectedRow());
drivePath = selectedDisk.getPath();
} else {
drivePath = "";
}
dispose();
}//GEN-LAST:event_bnOkActionPerformed
private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
dispose();
}//GEN-LAST:event_bnCancelActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnCancel;
private javax.swing.JButton bnOk;
private javax.swing.JButton bnRefresh;
private javax.swing.JTable diskTable;
private javax.swing.JLabel errorLabel;
private javax.swing.JLabel jLabel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration//GEN-END:variables
/**
* Table model for displaying information from LocalDisk Objects in a table.
*/
@NbBundle.Messages({"SelectDriveDialog.localDiskModel.loading.msg=",
"SelectDriveDialog.localDiskModel.nodrives.msg=Executable could not be found",
"SelectDriveDialog.diskTable.column1.title=Disk Name",
"SelectDriveDialog.diskTable.column2.title=Disk Size",
"SelectDriveDialog.errLabel.disksNotDetected.text=Disks were not detected. On some systems it requires admin privileges",
"SelectDriveDialog.errLabel.disksNotDetected.toolTipText=Disks were not detected."
})
private class LocalDiskModel implements TableModel {
private LocalDiskThread worker = null;
private boolean ready = false;
private volatile boolean loadingDisks = false;
//private String SELECT = "Select a local disk:";
private final String LOADING = NbBundle.getMessage(this.getClass(), "SelectDriveDialog.localDiskModel.loading.msg");
private final String NO_DRIVES = NbBundle.getMessage(this.getClass(), "SelectDriveDialog.localDiskModel.nodrives.msg");
private void loadDisks() {
// if there is a worker already building the lists, then cancel it first.
if (loadingDisks && worker != null) {
worker.cancel(false);
}
// Clear the lists
errorLabel.setText("");
diskTable.setEnabled(false);
ready = false;
loadingDisks = true;
worker = new LocalDiskThread();
worker.execute();
}
@Override
public int getRowCount() {
if (disks.isEmpty()) {
return 0;
}
return disks.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int columnIndex) {
switch (columnIndex) {
case 0:
return NbBundle.getMessage(this.getClass(), "SelectDriveDialog.diskTable.column1.title");
case 1:
return NbBundle.getMessage(this.getClass(), "SelectDriveDialog.diskTable.column2.title");
default:
return "Unnamed"; //NON-NLS
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (ready) {
if (disks.isEmpty()) {
return NO_DRIVES;
}
switch (columnIndex) {
case 0:
return disks.get(rowIndex).getName();
case 1:
return disks.get(rowIndex).getReadableSize();
default:
return disks.get(rowIndex).getPath();
}
} else {
return LOADING;
}
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
//setter does nothing they should not be able to modify table
}
@Override
public void addTableModelListener(TableModelListener l) {
}
@Override
public void removeTableModelListener(TableModelListener l) {
}
/**
* Gets the lists of physical drives and partitions and combines them
* into a list of disks.
*/
class LocalDiskThread extends SwingWorker<Object, Void> {
private final Logger logger = Logger.getLogger(LocalDiskThread.class.getName());
private List<LocalDisk> partitions = new ArrayList<>();
@Override
protected Object doInBackground() throws Exception {
// Populate the lists
partitions = new ArrayList<>();
partitions = PlatformUtil.getPartitions();
return null;
}
/**
* Display any error messages that might of occurred when getting
* the lists of physical drives or partitions.
*/
private void displayErrors() {
if (partitions.isEmpty()) {
if (PlatformUtil.isWindowsOS()) {
errorLabel.setText(
NbBundle.getMessage(this.getClass(), "SelectDriveDialog.errLabel.disksNotDetected.text"));
errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
"SelectDriveDialog.errLabel.disksNotDetected.toolTipText"));
} else {
errorLabel.setText(
NbBundle.getMessage(this.getClass(), "SelectDriveDialog.errLabel.drivesNotDetected.text"));
errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
"SelectDriveDialog.errLabel.drivesNotDetected.toolTipText"));
}
errorLabel.setVisible(true);
diskTable.setEnabled(false);
}
}
@Override
protected void done() {
try {
super.get(); //block and get all exceptions thrown while doInBackground()
} catch (CancellationException ex) {
logger.log(Level.INFO, "Loading local disks was canceled."); //NON-NLS
} catch (InterruptedException ex) {
logger.log(Level.INFO, "Loading local disks was interrupted."); //NON-NLS
} catch (Exception ex) {
logger.log(Level.SEVERE, "Fatal error when loading local disks", ex); //NON-NLS
} finally {
if (!this.isCancelled()) {
displayErrors();
worker = null;
loadingDisks = false;
disks = new ArrayList<>();
disks.addAll(partitions);
if (disks.size() > 0) {
diskTable.setEnabled(true);
diskTable.clearSelection();
}
ready = true;
}
}
diskTable.revalidate();
}
}
}
}

View File

@ -51,6 +51,7 @@ import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.parser.microsoft.OfficeParserConfig;
import org.apache.tika.sax.BodyContentHandler;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
@ -231,11 +232,13 @@ class MSOfficeEmbeddedContentExtractor {
// write limit (which defaults to 100,000 characters.
ContentHandler contentHandler = new BodyContentHandler(-1);
// TODO: this will be needed once we upgrade to Tika 1.16 or later.
// OfficeParserConfig officeParserConfig = new OfficeParserConfig();
// officeParserConfig.setUseSAXPptxExtractor(true);
// officeParserConfig.setUseSAXDocxExtractor(true);
// parseContext.set(OfficeParserConfig.class, officeParserConfig);
// Use the more memory efficient Tika SAX parsers for DOCX and
// PPTX files (it already uses SAX for XLSX).
OfficeParserConfig officeParserConfig = new OfficeParserConfig();
officeParserConfig.setUseSAXPptxExtractor(true);
officeParserConfig.setUseSAXDocxExtractor(true);
parseContext.set(OfficeParserConfig.class, officeParserConfig);
EmbeddedDocumentExtractor extractor = new EmbeddedContentExtractor(parseContext);
parseContext.set(EmbeddedDocumentExtractor.class, extractor);
ReadContentInputStream stream = new ReadContentInputStream(abstractFile);

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -177,6 +177,8 @@ public class FileTypeDetector {
*
* @return A MIME type name. If file type could not be detected, or results
* were uncertain, octet-stream is returned.
*
*/
public String detectMIMEType(AbstractFile file) {
/*

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013 - 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -47,13 +47,13 @@ ReportBodyFile.getDesc.text=Body file format report with MAC times for every fil
ReportBodyFile.getFilePath.text=BodyFile.txt
ReportKML.progress.querying=Querying files...
ReportKML.progress.loading=Loading files...
ReportKML.getName.text=Google Earth/KML
ReportKML.getName.text=Google Earth KML
ReportKML.getDesc.text=KML format report with coordinates for relevant files. This format can be used for google earth views.
ReportKML.getFilePath.text=ReportKML.kml
ReportBranding.defaultReportTitle.text=Autopsy Forensic Report
ReportBranding.defaultReportFooter.text=Powered by Autopsy Open Source Digital Forensics Platform - www.sleuthkit.org
ReportExcel.numAartifacts.text=Number of artifacts\:
ReportExcel.getName.text=Results - Excel
ReportExcel.getName.text=Excel Report
ReportExcel.getDesc.text=A report about results and tagged items in Excel (XLS) format.
ReportExcel.sheetName.text=Summary
ReportExcel.cellVal.summary=Summary
@ -177,12 +177,12 @@ ReportGenerator.errors.reportErrorText=Error generating report:
ReportHTML.addThumbRows.dataType.title=Tagged Images - {0}
ReportHTML.addThumbRows.dataType.msg=Tagged Results and Contents that contain images.
ReportHTML.thumbLink.tags=Tags\:
ReportHTML.getName.text=Results - HTML
ReportHTML.getName.text=HTML Report
ReportHTML.getDesc.text=A report about results and tagged items in HTML format.
ReportHTML.writeIndex.title=for case {0}
ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup.
ReportHTML.writeIndex.noFrames.seeNav=Please see <a href\="nav.html">the navigation page</a> for artifact links,
ReportHTML.writeIndex.seeSum=and <a href\="summary.html">the summary page</a> for a case summary.
ReportHTML.writeIndex.noFrames.seeNav=Please see <a href\="content\nav.html">the navigation page</a> for artifact links,
ReportHTML.writeIndex.seeSum=and <a href\="content\summary.html">the summary page</a> for a case summary.
ReportHTML.writeNav.title=Report Navigation
ReportHTML.writeNav.h1=Report Navigation
ReportHTML.writeNav.summary=Case Summary
@ -190,7 +190,7 @@ ReportHTML.writeSum.title=Case Summary
ReportHTML.writeSum.warningMsg=<span>Warning, this report was run before ingest services completed\!</span>
#
# autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum,
# examiner as a regex signature to skip index.html and summary.html
# examiner as a regex signature to skip report.html and summary.html
#
ReportHTML.writeSum.reportGenOn.text=HTML Report Generated on {0}
ReportHTML.writeSum.caseName=Case\:

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013 - 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2012-2014 Basis Technology Corp.
* Copyright 2012-2018 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
@ -76,7 +76,7 @@ class ReportBodyFile implements GeneralReportModule {
progressPanel.setIndeterminate(false);
progressPanel.start();
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportBodyFile.progress.querying"));
reportPath = baseReportDir + "BodyFile.txt"; //NON-NLS
reportPath = baseReportDir + getRelativeFilePath(); //NON-NLS
currentCase = Case.getCurrentCase();
skCase = currentCase.getSleuthkitCase();

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2017 Basis Technology Corp.
* Copyright 2013-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Copyright 2013 - 2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -63,7 +63,7 @@ class ReportGenerator {
*/
private ReportProgressPanel progressPanel;
private final String reportPath;
private static final String REPORT_PATH_FMT_STR = "%s" + File.separator + "%s %s %s" + File.separator;
private final ReportGenerationPanel reportGenerationPanel = new ReportGenerationPanel();
static final String REPORTS_DIR = "Reports"; //NON-NLS
@ -89,23 +89,10 @@ class ReportGenerator {
* Creates a report generator.
*/
ReportGenerator() {
// Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String dateNoTime = dateFormat.format(date);
this.reportPath = currentCase.getReportDirectory() + File.separator + currentCase.getDisplayName() + " " + dateNoTime + File.separator;
this.errorList = new ArrayList<>();
// Create the root reports directory.
try {
FileUtil.createFolder(new File(this.reportPath));
} catch (IOException ex) {
errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedMakeRptFolder"));
logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex); //NON-NLS
}
}
/**
* Display the progress panels to the user, and add actions to close the
* parent dialog.
@ -143,11 +130,12 @@ class ReportGenerator {
/**
* Run the GeneralReportModules using a SwingWorker.
*/
void generateGeneralReport(GeneralReportModule generalReportModule) {
void generateGeneralReport(GeneralReportModule generalReportModule) throws IOException {
if (generalReportModule != null) {
setupProgressPanel(generalReportModule);
String reportDir = createReportDirectory(generalReportModule);
setupProgressPanel(generalReportModule, reportDir);
ReportWorker worker = new ReportWorker(() -> {
generalReportModule.generateReport(reportPath, progressPanel);
generalReportModule.generateReport(reportDir, progressPanel);
});
worker.execute();
displayProgressPanel();
@ -162,11 +150,12 @@ class ReportGenerator {
* @param tagSelections the enabled/disabled state of the tag names
* to be included in the report
*/
void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) {
void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) throws IOException {
if (tableReport != null && null != artifactTypeSelections) {
setupProgressPanel(tableReport);
String reportDir = createReportDirectory(tableReport);
setupProgressPanel(tableReport, reportDir);
ReportWorker worker = new ReportWorker(() -> {
tableReport.startReport(reportPath);
tableReport.startReport(reportDir);
TableReportGenerator generator = new TableReportGenerator(artifactTypeSelections, tagNameSelections, progressPanel, tableReport);
generator.execute();
tableReport.endReport();
@ -185,15 +174,16 @@ class ReportGenerator {
* @param enabledInfo the Information that should be included about each
* file in the report.
*/
void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) {
void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) throws IOException {
if (fileReportModule != null && null != enabledInfo) {
String reportDir = createReportDirectory(fileReportModule);
List<FileReportDataTypes> enabled = new ArrayList<>();
for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
if (e.getValue()) {
enabled.add(e.getKey());
}
}
setupProgressPanel(fileReportModule);
setupProgressPanel(fileReportModule, reportDir);
ReportWorker worker = new ReportWorker(() -> {
if (progressPanel.getStatus() != ReportStatus.CANCELED) {
progressPanel.start();
@ -204,7 +194,7 @@ class ReportGenerator {
List<AbstractFile> files = getFiles();
int numFiles = files.size();
if (progressPanel.getStatus() != ReportStatus.CANCELED) {
fileReportModule.startReport(reportPath);
fileReportModule.startReport(reportDir);
fileReportModule.startTable(enabled);
}
progressPanel.setIndeterminate(false);
@ -259,15 +249,31 @@ class ReportGenerator {
}
}
private void setupProgressPanel(ReportModule module) {
private void setupProgressPanel(ReportModule module, String reportDir) {
String reportFilePath = module.getRelativeFilePath();
if (!reportFilePath.isEmpty()) {
this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportPath + reportFilePath);
this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportDir + reportFilePath);
} else {
this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
}
}
private static String createReportDirectory(ReportModule module) throws IOException {
Case currentCase = Case.getCurrentCase();
// Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String dateNoTime = dateFormat.format(date);
String reportPath = String.format(REPORT_PATH_FMT_STR, currentCase.getReportDirectory(), currentCase.getDisplayName(), module.getName(), dateNoTime);
// Create the root reports directory.
try {
FileUtil.createFolder(new File(reportPath));
} catch (IOException ex) {
throw new IOException("Failed to make report folder, unable to generate reports.", ex);
}
return reportPath;
}
private class ReportWorker extends SwingWorker<Void, Void> {
private final Runnable doInBackground;

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2012-2014 Basis Technology Corp.
* Copyright 2012-2018 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
@ -72,6 +72,7 @@ class ReportHTML implements TableReportModule {
private static final String THUMBS_REL_PATH = "thumbs" + File.separator; //NON-NLS
private static ReportHTML instance;
private static final int MAX_THUMBS_PER_PAGE = 1000;
private static final String HTML_SUBDIR = "content";
private Case currentCase;
private SleuthkitCase skCase;
static Integer THUMBNAIL_COLUMNS = 5;
@ -79,6 +80,7 @@ class ReportHTML implements TableReportModule {
private Map<String, Integer> dataTypes;
private String path;
private String thumbsPath;
private String subPath;
private String currentDataType; // name of current data type
private Integer rowCount; // number of rows (aka artifacts or tags) for the current data type
private Writer out;
@ -107,6 +109,7 @@ class ReportHTML implements TableReportModule {
path = "";
thumbsPath = "";
subPath = "";
currentDataType = "";
rowCount = 0;
@ -157,7 +160,7 @@ class ReportHTML implements TableReportModule {
if (null != artifactType) {
// set the icon file name
iconFileName = dataTypeToFileName(artifactType.getDisplayName()) + ".png"; //NON-NLS
iconFilePath = path + File.separator + iconFileName;
iconFilePath = subPath + File.separator + iconFileName;
// determine the source image to use
switch (artifactType) {
@ -268,7 +271,7 @@ class ReportHTML implements TableReportModule {
logger.log(Level.WARNING, "useDataTypeIcon: unhandled artifact type = " + dataType); //NON-NLS
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/star.png"); //NON-NLS
iconFileName = "star.png"; //NON-NLS
iconFilePath = path + File.separator + iconFileName;
iconFilePath = subPath + File.separator + iconFileName;
break;
}
} else if (dataType.startsWith(ARTIFACT_TYPE.TSK_ACCOUNT.getDisplayName())) {
@ -281,11 +284,11 @@ class ReportHTML implements TableReportModule {
*/
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/accounts.png"); //NON-NLS
iconFileName = "accounts.png"; //NON-NLS
iconFilePath = path + File.separator + iconFileName;
iconFilePath = subPath + File.separator + iconFileName;
} else { // no defined artifact found for this dataType
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/star.png"); //NON-NLS
iconFileName = "star.png"; //NON-NLS
iconFilePath = path + File.separator + iconFileName;
iconFilePath = subPath + File.separator + iconFileName;
}
try {
@ -325,10 +328,11 @@ class ReportHTML implements TableReportModule {
// Refresh the HTML report
refresh();
// Setup the path for the HTML report
this.path = baseReportDir + "HTML Report" + File.separator; //NON-NLS
this.thumbsPath = this.path + "thumbs" + File.separator; //NON-NLS
this.path = baseReportDir; //NON-NLS
this.subPath = this.path + HTML_SUBDIR + File.separator;
this.thumbsPath = this.subPath + THUMBS_REL_PATH; //NON-NLS
try {
FileUtil.createFolder(new File(this.path));
FileUtil.createFolder(new File(this.subPath));
FileUtil.createFolder(new File(this.thumbsPath));
} catch (IOException ex) {
logger.log(Level.SEVERE, "Unable to make HTML report folder."); //NON-NLS
@ -367,7 +371,7 @@ class ReportHTML implements TableReportModule {
public void startDataType(String name, String description) {
String title = dataTypeToFileName(name);
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + title + ".html"), "UTF-8")); //NON-NLS
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(subPath + title + ".html"), "UTF-8")); //NON-NLS
} catch (FileNotFoundException ex) {
logger.log(Level.SEVERE, "File not found: {0}", ex); //NON-NLS
} catch (UnsupportedEncodingException ex) {
@ -747,7 +751,7 @@ class ReportHTML implements TableReportModule {
// Make a folder for the local file with the same tagName as the tag.
StringBuilder localFilePath = new StringBuilder(); // full path
localFilePath.append(path);
localFilePath.append(subPath);
localFilePath.append(dirName2);
File localFileFolder = new File(localFilePath.toString());
if (!localFileFolder.exists()) {
@ -777,7 +781,7 @@ class ReportHTML implements TableReportModule {
}
// get the relative path
return localFilePath.toString().substring(path.length());
return localFilePath.toString().substring(subPath.length());
}
/**
@ -795,7 +799,7 @@ class ReportHTML implements TableReportModule {
@Override
public String getRelativeFilePath() {
return "HTML Report" + File.separator + "index.html"; //NON-NLS
return "report.html"; //NON-NLS
}
@Override
@ -814,7 +818,7 @@ class ReportHTML implements TableReportModule {
private void writeCss() {
Writer cssOut = null;
try {
cssOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + "index.css"), "UTF-8")); //NON-NLS NON-NLS
cssOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(subPath + "index.css"), "UTF-8")); //NON-NLS NON-NLS
String css = "body {margin: 0px; padding: 0px; background: #FFFFFF; font: 13px/20px Arial, Helvetica, sans-serif; color: #535353;}\n"
+ //NON-NLS
"#content {padding: 30px;}\n"
@ -875,7 +879,7 @@ class ReportHTML implements TableReportModule {
*/
private void writeIndex() {
Writer indexOut = null;
String indexFilePath = path + "index.html"; //NON-NLS
String indexFilePath = path + "report.html"; //NON-NLS
try {
indexOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexFilePath), "UTF-8")); //NON-NLS
StringBuilder index = new StringBuilder();
@ -883,7 +887,7 @@ class ReportHTML implements TableReportModule {
String iconPath = reportBranding.getAgencyLogoPath();
if (iconPath == null) {
// use default Autopsy icon if custom icon is not set
iconPath = "favicon.ico";
iconPath = HTML_SUBDIR + "favicon.ico";
} else {
iconPath = Paths.get(reportBranding.getAgencyLogoPath()).getFileName().toString(); //ref to writeNav() for agency_logo
}
@ -895,8 +899,8 @@ class ReportHTML implements TableReportModule {
index.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"); //NON-NLS
index.append("</head>\n"); //NON-NLS
index.append("<frameset cols=\"350px,*\">\n"); //NON-NLS
index.append("<frame src=\"nav.html\" name=\"nav\">\n"); //NON-NLS
index.append("<frame src=\"summary.html\" name=\"content\">\n"); //NON-NLS
index.append("<frame src=\"" + HTML_SUBDIR).append(File.separator).append("nav.html\" name=\"nav\">\n"); //NON-NLS
index.append("<frame src=\"" + HTML_SUBDIR).append(File.separator).append("summary.html\" name=\"content\">\n"); //NON-NLS
index.append("<noframes>").append(NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.noFrames.msg")).append("<br />\n"); //NON-NLS
index.append(NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.noFrames.seeNav")).append("<br />\n"); //NON-NLS
index.append(NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.seeSum")).append("</noframes>\n"); //NON-NLS
@ -906,7 +910,7 @@ class ReportHTML implements TableReportModule {
Case.getCurrentCase().addReport(indexFilePath, NbBundle.getMessage(this.getClass(),
"ReportHTML.writeIndex.srcModuleName.text"), "");
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error creating Writer for index.html: {0}", ex); //NON-NLS
logger.log(Level.SEVERE, "Error creating Writer for report.html: {0}", ex); //NON-NLS
} catch (TskCoreException ex) {
String errorMessage = String.format("Error adding %s to case as a report", indexFilePath); //NON-NLS
logger.log(Level.SEVERE, errorMessage, ex);
@ -927,7 +931,7 @@ class ReportHTML implements TableReportModule {
private void writeNav() {
Writer navOut = null;
try {
navOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + "nav.html"), "UTF-8")); //NON-NLS
navOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(subPath + "nav.html"), "UTF-8")); //NON-NLS
StringBuilder nav = new StringBuilder();
nav.append("<html>\n<head>\n\t<title>").append( //NON-NLS
NbBundle.getMessage(this.getClass(), "ReportHTML.writeNav.title"))
@ -972,24 +976,24 @@ class ReportHTML implements TableReportModule {
String generatorLogoPath = reportBranding.getGeneratorLogoPath();
if (generatorLogoPath != null && !generatorLogoPath.isEmpty()) {
File from = new File(generatorLogoPath);
File to = new File(path);
File to = new File(subPath);
FileUtil.copyFile(FileUtil.toFileObject(from), FileUtil.toFileObject(to), "generator_logo"); //NON-NLS
}
String agencyLogoPath = reportBranding.getAgencyLogoPath();
if (agencyLogoPath != null && !agencyLogoPath.isEmpty()) {
Path destinationPath = Paths.get(path);
Path destinationPath = Paths.get(subPath);
Files.copy(Files.newInputStream(Paths.get(agencyLogoPath)), destinationPath.resolve(Paths.get(agencyLogoPath).getFileName())); //NON-NLS
}
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/favicon.ico"); //NON-NLS
output = new FileOutputStream(new File(path + File.separator + "favicon.ico"));
output = new FileOutputStream(new File(subPath + "favicon.ico"));
FileUtil.copy(in, output);
in.close();
output.close();
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/summary.png"); //NON-NLS
output = new FileOutputStream(new File(path + File.separator + "summary.png"));
output = new FileOutputStream(new File(subPath + "summary.png"));
FileUtil.copy(in, output);
in.close();
output.close();
@ -1019,7 +1023,7 @@ class ReportHTML implements TableReportModule {
private void writeSummary() {
Writer out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + "summary.html"), "UTF-8")); //NON-NLS
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(subPath + "summary.html"), "UTF-8")); //NON-NLS
StringBuilder head = new StringBuilder();
head.append("<html>\n<head>\n<title>").append( //NON-NLS
NbBundle.getMessage(this.getClass(), "ReportHTML.writeSum.title")).append("</title>\n"); //NON-NLS

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2014-2016 Basis Technology Corp.
* Copyright 2014-2018 Basis Technology Corp.
* contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -104,6 +104,7 @@ class ReportKML implements GeneralReportModule {
progressPanel.start();
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.querying"));
String kmlFileFullPath = baseReportDir + REPORT_KML; //NON-NLS
currentCase = Case.getCurrentCase();
skCase = currentCase.getSleuthkitCase();

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2013-2015 Basis Technology Corp.
* Copyright 2013-2018 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
@ -26,12 +26,14 @@ import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.WizardDescriptor;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
@ -70,12 +72,17 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
TableReportModule tableReport = (TableReportModule) wiz.getProperty("tableModule");
GeneralReportModule generalReport = (GeneralReportModule) wiz.getProperty("generalModule");
FileReportModule fileReport = (FileReportModule) wiz.getProperty("fileModule");
if (tableReport != null) {
generator.generateTableReport(tableReport, (Map<BlackboardArtifact.Type, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
} else if (generalReport != null) {
generator.generateGeneralReport(generalReport);
} else if (fileReport != null) {
generator.generateFileListReport(fileReport, (Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
try {
if (tableReport != null) {
generator.generateTableReport(tableReport, (Map<BlackboardArtifact.Type, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
} else if (generalReport != null) {
generator.generateGeneralReport(generalReport);
} else if (fileReport != null) {
generator.generateFileListReport(fileReport, (Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
}
} catch (IOException e) {
NotifyDescriptor descriptor = new NotifyDescriptor.Message(e.getMessage(), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(descriptor);
}
}
}

View File

@ -28,8 +28,8 @@
<dependency conf="autopsy_core->*" org="log4j" name="log4j" rev="1.2.17"/>
<!-- <dependency conf="autopsy_core->*" org="org.jdom" name="jdom" rev="1.1.3"/> -->
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-excelant" rev="3.15"/>
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-scratchpad" rev="3.15"/>
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-excelant" rev="3.17"/>
<dependency conf="autopsy_core->*" org="org.apache.poi" name="poi-scratchpad" rev="3.17"/>
<!-- process and system monitoring, note: matching native libs pulled from thirdparty -->
<dependency conf="autopsy_core->*" org="org.fusesource" name="sigar" rev="1.6.4" />

View File

@ -58,11 +58,11 @@ file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar
file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar
file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar
file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar
file.reference.poi-3.15.jar=release/modules/ext/poi-3.15.jar
file.reference.poi-excelant-3.15.jar=release/modules/ext/poi-excelant-3.15.jar
file.reference.poi-ooxml-3.15.jar=release/modules/ext/poi-ooxml-3.15.jar
file.reference.poi-ooxml-schemas-3.15.jar=release/modules/ext/poi-ooxml-schemas-3.15.jar
file.reference.poi-scratchpad-3.15.jar=release/modules/ext/poi-scratchpad-3.15.jar
file.reference.poi-3.17.jar=release/modules/ext/poi-3.17.jar
file.reference.poi-excelant-3.17.jar=release/modules/ext/poi-excelant-3.17.jar
file.reference.poi-ooxml-3.17.jar=release/modules/ext/poi-ooxml-3.17.jar
file.reference.poi-ooxml-schemas-3.17.jar=release/modules/ext/poi-ooxml-schemas-3.17.jar
file.reference.poi-scratchpad-3.17.jar=release/modules/ext/poi-scratchpad-3.17.jar
file.reference.reflections-0.9.8.jar=release/modules/ext/reflections-0.9.8.jar
file.reference.servlet-api-2.5.jar=release/modules/ext/servlet-api-2.5.jar
file.reference.sigar-1.6.4-sources.jar=release/modules/ext/sigar-1.6.4-sources.jar

View File

@ -295,17 +295,10 @@
<package>org.apache.log4j.xml</package>
<package>org.apache.poi</package>
<package>org.apache.poi.common.usermodel</package>
<package>org.apache.poi.common.usermodel.fonts</package>
<package>org.apache.poi.ddf</package>
<package>org.apache.poi.dev</package>
<package>org.apache.poi.extractor</package>
<package>org.apache.poi.hdf.event</package>
<package>org.apache.poi.hdf.extractor</package>
<package>org.apache.poi.hdf.extractor.data</package>
<package>org.apache.poi.hdf.extractor.util</package>
<package>org.apache.poi.hdf.model</package>
<package>org.apache.poi.hdf.model.hdftypes</package>
<package>org.apache.poi.hdf.model.hdftypes.definitions</package>
<package>org.apache.poi.hdf.model.util</package>
<package>org.apache.poi.hdgf</package>
<package>org.apache.poi.hdgf.chunks</package>
<package>org.apache.poi.hdgf.dev</package>
@ -313,6 +306,9 @@
<package>org.apache.poi.hdgf.extractor</package>
<package>org.apache.poi.hdgf.pointers</package>
<package>org.apache.poi.hdgf.streams</package>
<package>org.apache.poi.hemf.extractor</package>
<package>org.apache.poi.hemf.hemfplus.record</package>
<package>org.apache.poi.hemf.record</package>
<package>org.apache.poi.hmef</package>
<package>org.apache.poi.hmef.attribute</package>
<package>org.apache.poi.hmef.dev</package>
@ -325,7 +321,6 @@
<package>org.apache.poi.hpsf</package>
<package>org.apache.poi.hpsf.extractor</package>
<package>org.apache.poi.hpsf.wellknown</package>
<package>org.apache.poi.hslf</package>
<package>org.apache.poi.hslf.blip</package>
<package>org.apache.poi.hslf.dev</package>
<package>org.apache.poi.hslf.exceptions</package>
@ -358,7 +353,11 @@
<package>org.apache.poi.hssf.record.crypto</package>
<package>org.apache.poi.hssf.record.pivottable</package>
<package>org.apache.poi.hssf.usermodel</package>
<package>org.apache.poi.hssf.usermodel.helpers</package>
<package>org.apache.poi.hssf.util</package>
<package>org.apache.poi.hwmf.draw</package>
<package>org.apache.poi.hwmf.record</package>
<package>org.apache.poi.hwmf.usermodel</package>
<package>org.apache.poi.hwpf</package>
<package>org.apache.poi.hwpf.converter</package>
<package>org.apache.poi.hwpf.dev</package>
@ -372,18 +371,30 @@
<package>org.apache.poi.openxml4j.opc</package>
<package>org.apache.poi.openxml4j.opc.internal</package>
<package>org.apache.poi.openxml4j.opc.internal.marshallers</package>
<package>org.apache.poi.openxml4j.opc.internal.signature</package>
<package>org.apache.poi.openxml4j.opc.internal.unmarshallers</package>
<package>org.apache.poi.openxml4j.opc.signature</package>
<package>org.apache.poi.openxml4j.util</package>
<package>org.apache.poi.poifs.common</package>
<package>org.apache.poi.poifs.crypt</package>
<package>org.apache.poi.poifs.crypt.agile</package>
<package>org.apache.poi.poifs.crypt.binaryrc4</package>
<package>org.apache.poi.poifs.crypt.cryptoapi</package>
<package>org.apache.poi.poifs.crypt.dsig</package>
<package>org.apache.poi.poifs.crypt.dsig.facets</package>
<package>org.apache.poi.poifs.crypt.dsig.services</package>
<package>org.apache.poi.poifs.crypt.standard</package>
<package>org.apache.poi.poifs.crypt.temp</package>
<package>org.apache.poi.poifs.crypt.xor</package>
<package>org.apache.poi.poifs.dev</package>
<package>org.apache.poi.poifs.eventfilesystem</package>
<package>org.apache.poi.poifs.filesystem</package>
<package>org.apache.poi.poifs.macros</package>
<package>org.apache.poi.poifs.nio</package>
<package>org.apache.poi.poifs.property</package>
<package>org.apache.poi.poifs.storage</package>
<package>org.apache.poi.sl.draw</package>
<package>org.apache.poi.sl.draw.binding</package>
<package>org.apache.poi.sl.draw.geom</package>
<package>org.apache.poi.sl.image</package>
<package>org.apache.poi.sl.usermodel</package>
<package>org.apache.poi.ss</package>
<package>org.apache.poi.ss.excelant</package>
@ -401,15 +412,27 @@
<package>org.apache.poi.ss.formula.udf</package>
<package>org.apache.poi.ss.usermodel</package>
<package>org.apache.poi.ss.usermodel.charts</package>
<package>org.apache.poi.ss.usermodel.helpers</package>
<package>org.apache.poi.ss.util</package>
<package>org.apache.poi.ss.util.cellwalk</package>
<package>org.apache.poi.util</package>
<package>org.apache.poi.xslf</package>
<package>org.apache.poi.wp.usermodel</package>
<package>org.apache.poi.xdgf.exceptions</package>
<package>org.apache.poi.xdgf.extractor</package>
<package>org.apache.poi.xdgf.geom</package>
<package>org.apache.poi.xdgf.usermodel</package>
<package>org.apache.poi.xdgf.usermodel.section</package>
<package>org.apache.poi.xdgf.usermodel.section.geometry</package>
<package>org.apache.poi.xdgf.usermodel.shape</package>
<package>org.apache.poi.xdgf.usermodel.shape.exceptions</package>
<package>org.apache.poi.xdgf.util</package>
<package>org.apache.poi.xdgf.xml</package>
<package>org.apache.poi.xslf.extractor</package>
<package>org.apache.poi.xslf.model</package>
<package>org.apache.poi.xslf.model.geom</package>
<package>org.apache.poi.xslf.usermodel</package>
<package>org.apache.poi.xslf.util</package>
<package>org.apache.poi.xssf</package>
<package>org.apache.poi.xssf.binary</package>
<package>org.apache.poi.xssf.dev</package>
<package>org.apache.poi.xssf.eventusermodel</package>
<package>org.apache.poi.xssf.extractor</package>
@ -620,6 +643,8 @@
<package>org.openxmlformats.schemas.spreadsheetml.x2006.main.impl</package>
<package>org.openxmlformats.schemas.wordprocessingml.x2006.main</package>
<package>org.openxmlformats.schemas.wordprocessingml.x2006.main.impl</package>
<package>org.openxmlformats.schemas.xpackage.x2006.digitalSignature</package>
<package>org.openxmlformats.schemas.xpackage.x2006.digitalSignature.impl</package>
<package>org.reflections</package>
<package>org.reflections.adapters</package>
<package>org.reflections.scanners</package>
@ -643,17 +668,10 @@
<package>org.xml.sax.ext</package>
<package>org.xml.sax.helpers</package>
<package>repackage</package>
<package>schemaorg_apache_xmlbeans.system.sE130CAA0A01A7CDE5A2B4FEB8B311707</package>
<package>schemaorg_apache_xmlbeans.system.sXMLCONFIG</package>
<package>schemaorg_apache_xmlbeans.system.sXMLLANG</package>
<package>schemaorg_apache_xmlbeans.system.sXMLSCHEMA</package>
<package>schemaorg_apache_xmlbeans.system.sXMLTOOLS</package>
<package>schemasMicrosoftComOfficeExcel</package>
<package>schemasMicrosoftComOfficeExcel.impl</package>
<package>schemasMicrosoftComOfficeOffice</package>
<package>schemasMicrosoftComOfficeOffice.impl</package>
<package>schemasMicrosoftComVml</package>
<package>schemasMicrosoftComVml.impl</package>
</public-packages>
<class-path-extension>
<runtime-relative-path>ext/commons-logging-1.1.2-sources.jar</runtime-relative-path>
@ -763,10 +781,6 @@
<runtime-relative-path>ext/joda-time-2.4-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/joda-time-2.4-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-excelant-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-excelant-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-psd-3.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-psd-3.2.jar</binary-origin>
@ -823,10 +837,6 @@
<runtime-relative-path>ext/jfxtras-fxml-8.0-r4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jfxtras-fxml-8.0-r4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/joda-time-2.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/joda-time-2.4.jar</binary-origin>
@ -851,18 +861,22 @@
<runtime-relative-path>ext/guava-19.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/guava-19.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-schemas-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-scratchpad-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-scratchpad-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-io-2.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-io-2.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-schemas-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-scratchpad-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-scratchpad-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/imageio-bmp-3.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/imageio-bmp-3.2.jar</binary-origin>
@ -887,6 +901,10 @@
<runtime-relative-path>ext/ant-1.8.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/ant-1.8.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-excelant-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-excelant-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/javassist-3.12.1.GA.jar</runtime-relative-path>
<binary-origin>release/modules/ext/javassist-3.12.1.GA.jar</binary-origin>
@ -899,6 +917,10 @@
<runtime-relative-path>ext/commons-logging-1.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-1.1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/controlsfx-8.40.11.jar</runtime-relative-path>
<binary-origin>release/modules/ext/controlsfx-8.40.11.jar</binary-origin>
@ -911,10 +933,6 @@
<runtime-relative-path>ext/javaee-api-5.0-2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/javaee-api-5.0-2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/common-image-3.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/common-image-3.2.jar</binary-origin>

View File

@ -6,7 +6,7 @@
</configurations>
<dependencies>
<dependency conf="experimental->default" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="10.3.1"/>
<dependency conf="experimental->default" org="org.apache.tika" name="tika-core" rev="1.14"/>
<dependency conf="experimental->default" org="org.apache.tika" name="tika-core" rev="1.17"/>
<dependency conf="experimental->default" org="org.postgresql" name="postgresql" rev="9.4-1201-jdbc41"/>
<dependency conf="experimental->default" org="com.mchange" name="c3p0" rev="0.9.5"/>
<dependency conf="experimental->default" org="com.fasterxml.jackson.core" name="jackson-core" rev="2.7.0"/>

View File

@ -3,7 +3,7 @@ file.reference.jackson-core-2.7.0.jar=release/modules/ext/jackson-core-2.7.0.jar
file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar
file.reference.mchange-commons-java-0.2.9.jar=release/modules/ext/mchange-commons-java-0.2.9.jar
file.reference.postgresql-9.4-1201-jdbc41.jar=release/modules/ext/postgresql-9.4-1201-jdbc41.jar
file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar
file.reference.tika-core-1.17.jar=release/modules/ext/tika-core-1.17.jar
javac.source=1.8
javac.compilerargs=-Xlint -Xlint:-serial
javadoc.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1-javadoc.jar

View File

@ -146,12 +146,12 @@
<package>org.sleuthkit.autopsy.experimental.configuration</package>
</public-packages>
<class-path-extension>
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
<runtime-relative-path>ext/LGoodDatePicker-10.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/LGoodDatePicker-10.3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/LGoodDatePicker-10.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/LGoodDatePicker-10.3.1.jar</binary-origin>
<runtime-relative-path>ext/tika-core-1.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/mchange-commons-java-0.2.9.jar</runtime-relative-path>

View File

@ -22,7 +22,7 @@
<dependency conf="autopsy->*" org="org.apache.solr" name="solr-solrj" rev="4.9.1"/>
<dependency conf="autopsy->*" org="commons-lang" name="commons-lang" rev="2.4"/>
<dependency conf="autopsy->*" org="commons-validator" name="commons-validator" rev="1.5.1"/>
<dependency conf="autopsy->*" org="org.apache.tika" name="tika-parsers" rev="1.14"/>
<dependency conf="autopsy->*" org="org.apache.tika" name="tika-parsers" rev="1.17"/>
<!-- metadata-extractor is required by Tika but it depends on version 2.6.2 which suffers
from an XMP library issue. -->

View File

@ -1,6 +1,5 @@
file.reference.aopalliance-1.0.jar=release/modules/ext/aopalliance-1.0.jar
file.reference.apache-mime4j-core-0.7.2.jar=release/modules/ext/apache-mime4j-core-0.7.2.jar
file.reference.apache-mime4j-dom-0.7.2.jar=release/modules/ext/apache-mime4j-dom-0.7.2.jar
file.reference.apache-mime4j-core-0.8.1.jar=release/modules/ext/apache-mime4j-core-0.8.1.jar
file.reference.apache-mime4j-dom-0.8.1.jar=release/modules/ext/apache-mime4j-dom-0.8.1.jar
file.reference.asm-5.0.4.jar=release/modules/ext/asm-5.0.4.jar
file.reference.asm-all-3.1.jar=release/modules/ext/asm-all-3.1.jar
file.reference.bcmail-jdk15on-1.54.jar=release/modules/ext/bcmail-jdk15on-1.54.jar
@ -15,7 +14,7 @@ file.reference.commons-beanutils-1.9.2.jar=release/modules/ext/commons-beanutils
file.reference.commons-codec-1.10.jar=release/modules/ext/commons-codec-1.10.jar
file.reference.commons-collections-3.2.2.jar=release/modules/ext/commons-collections-3.2.2.jar
file.reference.commons-collections4-4.1.jar=release/modules/ext/commons-collections4-4.1.jar
file.reference.commons-compress-1.12.jar=release/modules/ext/commons-compress-1.12.jar
file.reference.commons-compress-1.14.jar=release/modules/ext/commons-compress-1.14.jar
file.reference.commons-csv-1.0.jar=release/modules/ext/commons-csv-1.0.jar
file.reference.commons-digester-1.8.1.jar=release/modules/ext/commons-digester-1.8.1.jar
file.reference.commons-exec-1.3.jar=release/modules/ext/commons-exec-1.3.jar
@ -26,35 +25,34 @@ file.reference.commons-logging-api-1.1.jar=release/modules/ext/commons-logging-a
file.reference.commons-validator-1.5.1-javadoc.jar=release/modules/ext/commons-validator-1.5.1-javadoc.jar
file.reference.commons-validator-1.5.1-sources.jar=release/modules/ext/commons-validator-1.5.1-sources.jar
file.reference.commons-validator-1.5.1.jar=release/modules/ext/commons-validator-1.5.1.jar
file.reference.commons-vfs2-2.0.jar=release/modules/ext/commons-vfs2-2.0.jar
file.reference.ctakes-core-3.2.2.jar=release/modules/ext/ctakes-core-3.2.2.jar
file.reference.ctakes-core-res-3.2.2.jar=release/modules/ext/ctakes-core-res-3.2.2.jar
file.reference.ctakes-type-system-3.2.2.jar=release/modules/ext/ctakes-type-system-3.2.2.jar
file.reference.ctakes-utils-3.2.2.jar=release/modules/ext/ctakes-utils-3.2.2.jar
file.reference.curvesapi-1.04.jar=release/modules/ext/curvesapi-1.04.jar
file.reference.cxf-core-3.0.3.jar=release/modules/ext/cxf-core-3.0.3.jar
file.reference.cxf-rt-frontend-jaxrs-3.0.3.jar=release/modules/ext/cxf-rt-frontend-jaxrs-3.0.3.jar
file.reference.cxf-rt-rs-client-3.0.3.jar=release/modules/ext/cxf-rt-rs-client-3.0.3.jar
file.reference.cxf-rt-transports-http-3.0.3.jar=release/modules/ext/cxf-rt-transports-http-3.0.3.jar
file.reference.cxf-core-3.0.16.jar=release/modules/ext/cxf-core-3.0.16.jar
file.reference.cxf-rt-frontend-jaxrs-3.0.16.jar=release/modules/ext/cxf-rt-frontend-jaxrs-3.0.16.jar
file.reference.cxf-rt-rs-client-3.0.16.jar=release/modules/ext/cxf-rt-rs-client-3.0.16.jar
file.reference.cxf-rt-transports-http-3.0.16.jar=release/modules/ext/cxf-rt-transports-http-3.0.16.jar
file.reference.ehcache-core-2.6.2.jar=release/modules/ext/ehcache-core-2.6.2.jar
file.reference.findstructapi-0.0.1.jar=release/modules/ext/findstructapi-0.0.1.jar
file.reference.fontbox-2.0.3.jar=release/modules/ext/fontbox-2.0.3.jar
file.reference.fontbox-2.0.8.jar=release/modules/ext/fontbox-2.0.8.jar
file.reference.geoapi-3.0.0.jar=release/modules/ext/geoapi-3.0.0.jar
file.reference.grib-4.5.5.jar=release/modules/ext/grib-4.5.5.jar
file.reference.gson-2.2.4.jar=release/modules/ext/gson-2.2.4.jar
file.reference.gson-2.8.1.jar=release/modules/ext/gson-2.8.1.jar
file.reference.guava-17.0.jar=release/modules/ext/guava-17.0.jar
file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar
file.reference.httpclient-4.3.1.jar=release/modules/ext/httpclient-4.3.1.jar
file.reference.httpcore-4.3.jar=release/modules/ext/httpcore-4.3.jar
file.reference.httpclient-4.5.4.jar=release/modules/ext/httpclient-4.5.4.jar
file.reference.httpcore-4.4.1.jar=release/modules/ext/httpcore-4.4.1.jar
file.reference.httpmime-4.3.1.jar=release/modules/ext/httpmime-4.3.1.jar
file.reference.httpcore-4.4.7.jar=release/modules/ext/httpcore-4.4.7.jar
file.reference.httpmime-4.4.1.jar=release/modules/ext/httpmime-4.4.1.jar
file.reference.httpmime-4.5.4.jar=release/modules/ext/httpmime-4.5.4.jar
file.reference.httpservices-4.5.5.jar=release/modules/ext/httpservices-4.5.5.jar
file.reference.icu4j-3.8.jar=release/modules/ext/icu4j-3.8.jar
file.reference.isoparser-1.1.18.jar=release/modules/ext/isoparser-1.1.18.jar
file.reference.jackcess-2.1.4.jar=release/modules/ext/jackcess-2.1.4.jar
file.reference.jackcess-encrypt-2.1.1.jar=release/modules/ext/jackcess-encrypt-2.1.1.jar
file.reference.jackson-core-2.8.1.jar=release/modules/ext/jackson-core-2.8.1.jar
file.reference.jackcess-2.1.8.jar=release/modules/ext/jackcess-2.1.8.jar
file.reference.jackcess-encrypt-2.1.2.jar=release/modules/ext/jackcess-encrypt-2.1.2.jar
file.reference.jackson-core-2.9.2.jar=release/modules/ext/jackson-core-2.9.2.jar
file.reference.jakarta-regexp-1.4.jar=release/modules/ext/jakarta-regexp-1.4.jar
file.reference.java-libpst-0.8.1.jar=release/modules/ext/java-libpst-0.8.1.jar
file.reference.javax.annotation-api-1.2.jar=release/modules/ext/javax.annotation-api-1.2.jar
@ -63,20 +61,17 @@ file.reference.jcip-annotations-1.0.jar=release/modules/ext/jcip-annotations-1.0
file.reference.jcommander-1.35.jar=release/modules/ext/jcommander-1.35.jar
file.reference.jdom-1.0.jar=release/modules/ext/jdom-1.0.jar
file.reference.jdom2-2.0.4.jar=release/modules/ext/jdom2-2.0.4.jar
file.reference.jempbox-1.8.12.jar=release/modules/ext/jempbox-1.8.12.jar
file.reference.jempbox-1.8.13.jar=release/modules/ext/jempbox-1.8.13.jar
file.reference.jericho-html-3.3-javadoc.jar=release/modules/ext/jericho-html-3.3-javadoc.jar
file.reference.jericho-html-3.3-sources.jar=release/modules/ext/jericho-html-3.3-sources.jar
file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar
file.reference.jhighlight-1.0.2.jar=release/modules/ext/jhighlight-1.0.2.jar
file.reference.jj2000-5.2.jar=release/modules/ext/jj2000-5.2.jar
file.reference.jmatio-1.2.jar=release/modules/ext/jmatio-1.2.jar
file.reference.jna-4.1.0.jar=release/modules/ext/jna-4.1.0.jar
file.reference.joda-time-2.2.jar=release/modules/ext/joda-time-2.2.jar
file.reference.json-20140107.jar=release/modules/ext/json-20140107.jar
file.reference.json-simple-1.1.1.jar=release/modules/ext/json-simple-1.1.1.jar
file.reference.jsoup-1.7.2.jar=release/modules/ext/jsoup-1.7.2.jar
file.reference.jsr-275-0.9.3.jar=release/modules/ext/jsr-275-0.9.3.jar
file.reference.junit-4.11.jar=release/modules/ext/junit-4.11.jar
file.reference.juniversalchardet-1.0.3.jar=release/modules/ext/juniversalchardet-1.0.3.jar
file.reference.junrar-0.7.jar=release/modules/ext/junrar-0.7.jar
file.reference.jVinci-2.6.0.jar=release/modules/ext/jVinci-2.6.0.jar
@ -88,10 +83,7 @@ file.reference.lucene-core-4.0.0.jar=release/modules/ext/lucene-core-4.0.0.jar
file.reference.lucene-queries-4.0.0.jar=release/modules/ext/lucene-queries-4.0.0.jar
file.reference.lucene-queryparser-4.0.0.jar=release/modules/ext/lucene-queryparser-4.0.0.jar
file.reference.lucene-sandbox-4.0.0.jar=release/modules/ext/lucene-sandbox-4.0.0.jar
file.reference.maven-scm-api-1.4.jar=release/modules/ext/maven-scm-api-1.4.jar
file.reference.maven-scm-provider-svn-commons-1.4.jar=release/modules/ext/maven-scm-provider-svn-commons-1.4.jar
file.reference.maven-scm-provider-svnexe-1.4.jar=release/modules/ext/maven-scm-provider-svnexe-1.4.jar
file.reference.metadata-extractor-2.9.1.jar=release/modules/ext/metadata-extractor-2.9.1.jar
file.reference.metadata-extractor-2.10.1.jar=release/modules/ext/metadata-extractor-2.10.1.jar
file.reference.netcdf4-4.5.5.jar=release/modules/ext/netcdf4-4.5.5.jar
file.reference.noggit-0.5.jar=release/modules/ext/noggit-0.5.jar
file.reference.openaifsm-0.0.1.jar=release/modules/ext/openaifsm-0.0.1.jar
@ -101,18 +93,15 @@ file.reference.org.apache.felix.scr.annotations-1.6.0.jar=release/modules/ext/or
file.reference.org.apache.felix.scr.generator-1.1.2.jar=release/modules/ext/org.apache.felix.scr.generator-1.1.2.jar
file.reference.org.osgi.compendium-4.0.0.jar=release/modules/ext/org.osgi.compendium-4.0.0.jar
file.reference.org.osgi.core-4.0.0.jar=release/modules/ext/org.osgi.core-4.0.0.jar
file.reference.pdfbox-2.0.3.jar=release/modules/ext/pdfbox-2.0.3.jar
file.reference.pdfbox-debugger-2.0.3.jar=release/modules/ext/pdfbox-debugger-2.0.3.jar
file.reference.pdfbox-tools-2.0.3.jar=release/modules/ext/pdfbox-tools-2.0.3.jar
file.reference.plexus-utils-1.5.6.jar=release/modules/ext/plexus-utils-1.5.6.jar
file.reference.poi-3.15.jar=release/modules/ext/poi-3.15.jar
file.reference.poi-ooxml-3.15.jar=release/modules/ext/poi-ooxml-3.15.jar
file.reference.poi-ooxml-schemas-3.15.jar=release/modules/ext/poi-ooxml-schemas-3.15.jar
file.reference.poi-scratchpad-3.15.jar=release/modules/ext/poi-scratchpad-3.15.jar
file.reference.pdfbox-2.0.8.jar=release/modules/ext/pdfbox-2.0.8.jar
file.reference.pdfbox-tools-2.0.8.jar=release/modules/ext/pdfbox-tools-2.0.8.jar
file.reference.poi-3.17.jar=release/modules/ext/poi-3.17.jar
file.reference.poi-ooxml-3.17.jar=release/modules/ext/poi-ooxml-3.17.jar
file.reference.poi-ooxml-schemas-3.17.jar=release/modules/ext/poi-ooxml-schemas-3.17.jar
file.reference.poi-scratchpad-3.17.jar=release/modules/ext/poi-scratchpad-3.17.jar
file.reference.protobuf-java-2.5.0.jar=release/modules/ext/protobuf-java-2.5.0.jar
file.reference.qdox-1.12.jar=release/modules/ext/qdox-1.12.jar
file.reference.quartz-2.2.0.jar=release/modules/ext/quartz-2.2.0.jar
file.reference.regexp-1.3.jar=release/modules/ext/regexp-1.3.jar
file.reference.rome-1.5.1.jar=release/modules/ext/rome-1.5.1.jar
file.reference.rome-utils-1.5.1.jar=release/modules/ext/rome-utils-1.5.1.jar
file.reference.sis-metadata-0.6.jar=release/modules/ext/sis-metadata-0.6.jar
@ -120,24 +109,18 @@ file.reference.sis-netcdf-0.6.jar=release/modules/ext/sis-netcdf-0.6.jar
file.reference.sis-referencing-0.6.jar=release/modules/ext/sis-referencing-0.6.jar
file.reference.sis-storage-0.6.jar=release/modules/ext/sis-storage-0.6.jar
file.reference.sis-utility-0.6.jar=release/modules/ext/sis-utility-0.6.jar
file.reference.slf4j-api-1.7.12.jar=release/modules/ext/slf4j-api-1.7.12.jar
file.reference.slf4j-api-1.7.24.jar=release/modules/ext/slf4j-api-1.7.24.jar
file.reference.solr-solrj-4.9.1-javadoc.jar=release/modules/ext/solr-solrj-4.9.1-javadoc.jar
file.reference.solr-solrj-4.9.1-sources.jar=release/modules/ext/solr-solrj-4.9.1-sources.jar
file.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1.jar
file.reference.spring-aop-3.1.2.RELEASE.jar=release/modules/ext/spring-aop-3.1.2.RELEASE.jar
file.reference.spring-asm-3.1.2.RELEASE.jar=release/modules/ext/spring-asm-3.1.2.RELEASE.jar
file.reference.spring-beans-3.1.2.RELEASE.jar=release/modules/ext/spring-beans-3.1.2.RELEASE.jar
file.reference.spring-context-3.1.2.RELEASE.jar=release/modules/ext/spring-context-3.1.2.RELEASE.jar
file.reference.spring-core-3.1.2.RELEASE.jar=release/modules/ext/spring-core-3.1.2.RELEASE.jar
file.reference.spring-expression-3.1.2.RELEASE.jar=release/modules/ext/spring-expression-3.1.2.RELEASE.jar
file.reference.sqlite-jdbc-3.8.11.2.jar=release/modules/ext/sqlite-jdbc-3.8.11.2.jar
file.reference.sqlite-jdbc-3.19.3.jar=release/modules/ext/sqlite-jdbc-3.19.3.jar
file.reference.sqlwrapper-0.0.1.jar=release/modules/ext/sqlwrapper-0.0.1.jar
file.reference.stax2-api-3.1.4.jar=release/modules/ext/stax2-api-3.1.4.jar
file.reference.tagsoup-1.2.1.jar=release/modules/ext/tagsoup-1.2.1.jar
file.reference.tika-core-1.14.jar=release/modules/ext/tika-core-1.14.jar
file.reference.tika-parsers-1.14-javadoc.jar=release/modules/ext/tika-parsers-1.14-javadoc.jar
file.reference.tika-parsers-1.14-sources.jar=release/modules/ext/tika-parsers-1.14-sources.jar
file.reference.tika-parsers-1.14.jar=release/modules/ext/tika-parsers-1.14.jar
file.reference.tika-core-1.17.jar=release/modules/ext/tika-core-1.17.jar
file.reference.tika-parsers-1.17-javadoc.jar=release/modules/ext/tika-parsers-1.17-javadoc.jar
file.reference.tika-parsers-1.17-sources.jar=release/modules/ext/tika-parsers-1.17-sources.jar
file.reference.tika-parsers-1.17.jar=release/modules/ext/tika-parsers-1.17.jar
file.reference.udunits-4.5.5.jar=release/modules/ext/udunits-4.5.5.jar
file.reference.uimafit-core-2.1.0.jar=release/modules/ext/uimafit-core-2.1.0.jar
file.reference.uimaj-adapter-vinci-2.6.0.jar=release/modules/ext/uimaj-adapter-vinci-2.6.0.jar
@ -150,9 +133,7 @@ file.reference.vorbis-java-core-0.8.jar=release/modules/ext/vorbis-java-core-0.8
file.reference.vorbis-java-tika-0.8.jar=release/modules/ext/vorbis-java-tika-0.8.jar
file.reference.woodstox-core-asl-4.4.1.jar=release/modules/ext/woodstox-core-asl-4.4.1.jar
file.reference.xmlbeans-2.6.0.jar=release/modules/ext/xmlbeans-2.6.0.jar
file.reference.xmlschema-core-2.1.0.jar=release/modules/ext/xmlschema-core-2.1.0.jar
file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.jar
file.reference.xz-1.5.jar=release/modules/ext/xz-1.5.jar
file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
javac.source=1.8
javac.compilerargs=-Xlint -Xlint:-serial

View File

@ -141,6 +141,10 @@
<runtime-relative-path>ext/commons-validator-1.5.1-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-validator-1.5.1-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/apache-mime4j-dom-0.8.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/apache-mime4j-dom-0.8.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-digester-1.8.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-digester-1.8.1.jar</binary-origin>
@ -149,14 +153,14 @@
<runtime-relative-path>ext/jwnl-1.3.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jwnl-1.3.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-core-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/lucene-queryparser-4.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/lucene-queryparser-4.0.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpclient-4.5.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpclient-4.5.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/uimaj-examples-2.4.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/uimaj-examples-2.4.0.jar</binary-origin>
@ -165,10 +169,6 @@
<runtime-relative-path>ext/cdm-4.5.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cdm-4.5.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/gson-2.2.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/gson-2.2.4.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>
@ -177,6 +177,10 @@
<runtime-relative-path>ext/geoapi-3.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/geoapi-3.0.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-compress-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-compress-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/hamcrest-core-1.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/hamcrest-core-1.3.jar</binary-origin>
@ -197,30 +201,34 @@
<runtime-relative-path>ext/xmlbeans-2.6.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmlbeans-2.6.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/maven-scm-api-1.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/maven-scm-api-1.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/quartz-2.2.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/quartz-2.2.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackcess-2.1.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackcess-2.1.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/slf4j-api-1.7.12.jar</runtime-relative-path>
<binary-origin>release/modules/ext/slf4j-api-1.7.12.jar</binary-origin>
<runtime-relative-path>ext/sqlite-jdbc-3.19.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sqlite-jdbc-3.19.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/guava-17.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/guava-17.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/metadata-extractor-2.10.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.10.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/apache-mime4j-core-0.8.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/apache-mime4j-core-0.8.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opennlp-maxent-3.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/opennlp-maxent-3.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/pdfbox-tools-2.0.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/pdfbox-tools-2.0.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jVinci-2.6.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jVinci-2.6.0.jar</binary-origin>
@ -229,18 +237,14 @@
<runtime-relative-path>ext/json-simple-1.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/json-simple-1.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sis-utility-0.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sis-utility-0.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jj2000-5.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jj2000-5.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpclient-4.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpclient-4.3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jhighlight-1.0.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jhighlight-1.0.2.jar</binary-origin>
@ -258,12 +262,12 @@
<binary-origin>release/modules/ext/ctakes-utils-3.2.2.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>
<runtime-relative-path>ext/cxf-rt-rs-client-3.0.16.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-rt-rs-client-3.0.16.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-compress-1.12.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-compress-1.12.jar</binary-origin>
<runtime-relative-path>ext/jempbox-1.8.13.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jempbox-1.8.13.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/openaifsm-0.0.1.jar</runtime-relative-path>
@ -277,14 +281,18 @@
<runtime-relative-path>ext/commons-collections4-4.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-collections4-4.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/cxf-rt-rs-client-3.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-rt-rs-client-3.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-5.1.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackcess-2.1.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackcess-2.1.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/findstructapi-0.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/findstructapi-0.0.1.jar</binary-origin>
@ -317,6 +325,22 @@
<runtime-relative-path>ext/commons-codec-1.10.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-codec-1.10.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/gson-2.8.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/gson-2.8.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-schemas-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-scratchpad-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-scratchpad-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/lucene-queries-4.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/lucene-queries-4.0.0.jar</binary-origin>
@ -326,45 +350,25 @@
<binary-origin>release/modules/ext/bcprov-jdk15on-1.54.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-schemas-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-scratchpad-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-scratchpad-3.15.jar</binary-origin>
<runtime-relative-path>ext/fontbox-2.0.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/fontbox-2.0.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-vfs2-2.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-vfs2-2.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.14.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.14.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackcess-encrypt-2.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackcess-encrypt-2.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/spring-expression-3.1.2.RELEASE.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spring-expression-3.1.2.RELEASE.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/lucene-analyzers-common-4.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/lucene-analyzers-common-4.0.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.14-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.14-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/javax.ws.rs-api-2.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/javax.ws.rs-api-2.0.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpmime-4.5.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpmime-4.5.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/junrar-0.7.jar</runtime-relative-path>
<binary-origin>release/modules/ext/junrar-0.7.jar</binary-origin>
@ -378,21 +382,13 @@
<binary-origin>release/modules/ext/noggit-0.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmlschema-core-2.1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmlschema-core-2.1.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpmime-4.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpmime-4.3.1.jar</binary-origin>
<runtime-relative-path>ext/poi-ooxml-3.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-3.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jna-4.1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jna-4.1.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xz-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xz-1.5.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>
@ -410,37 +406,17 @@
<binary-origin>release/modules/ext/grib-4.5.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/maven-scm-provider-svn-commons-1.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/maven-scm-provider-svn-commons-1.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.15.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/spring-aop-3.1.2.RELEASE.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spring-aop-3.1.2.RELEASE.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/json-20140107.jar</runtime-relative-path>
<binary-origin>release/modules/ext/json-20140107.jar</binary-origin>
<runtime-relative-path>ext/jackson-core-2.9.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackson-core-2.9.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/uimaj-core-2.5.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/uimaj-core-2.5.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/pdfbox-2.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/pdfbox-2.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jmatio-1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jmatio-1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/metadata-extractor-2.9.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.9.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-csv-1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-csv-1.0.jar</binary-origin>
@ -466,21 +442,13 @@
<binary-origin>release/modules/ext/httpservices-4.5.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/plexus-utils-1.5.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/plexus-utils-1.5.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/fontbox-2.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/fontbox-2.0.3.jar</binary-origin>
<runtime-relative-path>ext/httpcore-4.4.7.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpcore-4.4.7.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcmail-jdk15on-1.54.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcmail-jdk15on-1.54.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/spring-beans-3.1.2.RELEASE.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spring-beans-3.1.2.RELEASE.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1-javadoc.jar</binary-origin>
@ -490,8 +458,8 @@
<binary-origin>release/modules/ext/asm-all-3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.14-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.14-javadoc.jar</binary-origin>
<runtime-relative-path>ext/tika-parsers-1.17-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.17-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/icu4j-3.8.jar</runtime-relative-path>
@ -501,10 +469,6 @@
<runtime-relative-path>ext/curvesapi-1.04.jar</runtime-relative-path>
<binary-origin>release/modules/ext/curvesapi-1.04.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-5.1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sis-referencing-0.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sis-referencing-0.6.jar</binary-origin>
@ -521,6 +485,10 @@
<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/tika-core-1.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/lucene-core-4.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/lucene-core-4.0.0.jar</binary-origin>
@ -533,10 +501,6 @@
<runtime-relative-path>ext/commons-logging-1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackson-core-2.8.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackson-core-2.8.1.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>
@ -545,10 +509,18 @@
<runtime-relative-path>ext/c3p0-0.9.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/c3p0-0.9.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.17-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.17-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sqlwrapper-0.0.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sqlwrapper-0.0.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jackcess-encrypt-2.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jackcess-encrypt-2.1.2.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>
@ -557,18 +529,10 @@
<runtime-relative-path>ext/udunits-4.5.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/udunits-4.5.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/aopalliance-1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/aopalliance-1.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-collections-3.2.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/cxf-rt-frontend-jaxrs-3.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-rt-frontend-jaxrs-3.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/uimaj-document-annotation-2.5.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/uimaj-document-annotation-2.5.0.jar</binary-origin>
@ -577,41 +541,29 @@
<runtime-relative-path>ext/woodstox-core-asl-4.4.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/woodstox-core-asl-4.4.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-3.15.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-3.15.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/pdfbox-2.0.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/pdfbox-2.0.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/zookeeper-3.4.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/zookeeper-3.4.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/cxf-rt-transports-http-3.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-rt-transports-http-3.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/pdfbox-debugger-2.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/pdfbox-debugger-2.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/spring-core-3.1.2.RELEASE.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spring-core-3.1.2.RELEASE.jar</binary-origin>
<runtime-relative-path>ext/cxf-rt-transports-http-3.0.16.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-rt-transports-http-3.0.16.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/netcdf4-4.5.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/netcdf4-4.5.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/spring-asm-3.1.2.RELEASE.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spring-asm-3.1.2.RELEASE.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/junit-4.11.jar</runtime-relative-path>
<binary-origin>release/modules/ext/junit-4.11.jar</binary-origin>
<runtime-relative-path>ext/slf4j-api-1.7.24.jar</runtime-relative-path>
<binary-origin>release/modules/ext/slf4j-api-1.7.24.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/protobuf-java-2.5.0.jar</runtime-relative-path>
@ -642,37 +594,17 @@
<binary-origin>release/modules/ext/commons-lang-2.6.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sqlite-jdbc-3.8.11.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sqlite-jdbc-3.8.11.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jempbox-1.8.12.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jempbox-1.8.12.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/maven-scm-provider-svnexe-1.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/maven-scm-provider-svnexe-1.4.jar</binary-origin>
<runtime-relative-path>ext/cxf-core-3.0.16.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-core-3.0.16.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/opennlp-tools-1.5.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/opennlp-tools-1.5.3.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-utils-1.5.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/rome-utils-1.5.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpcore-4.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpcore-4.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/pdfbox-tools-2.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/pdfbox-tools-2.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/sis-storage-0.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sis-storage-0.6.jar</binary-origin>
@ -689,6 +621,10 @@
<runtime-relative-path>ext/uimafit-core-2.1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/uimafit-core-2.1.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/cxf-rt-frontend-jaxrs-3.0.16.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-rt-frontend-jaxrs-3.0.16.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/cleartk-util-2.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cleartk-util-2.0.0.jar</binary-origin>
@ -697,14 +633,6 @@
<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/cxf-core-3.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/cxf-core-3.0.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/regexp-1.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/regexp-1.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-beanutils-1.9.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-beanutils-1.9.2.jar</binary-origin>
@ -713,10 +641,6 @@
<runtime-relative-path>ext/ehcache-core-2.6.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/ehcache-core-2.6.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/spring-context-3.1.2.RELEASE.jar</runtime-relative-path>
<binary-origin>release/modules/ext/spring-context-3.1.2.RELEASE.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/ctakes-type-system-3.2.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/ctakes-type-system-3.2.2.jar</binary-origin>

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -24,6 +24,7 @@ import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
@ -35,6 +36,8 @@ import javax.swing.table.AbstractTableModel;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
@ -45,6 +48,7 @@ class GlobalListsManagementPanel extends javax.swing.JPanel implements OptionsPa
private static final long serialVersionUID = 1L;
private final KeywordListTableModel tableModel;
private final org.sleuthkit.autopsy.keywordsearch.GlobalListSettingsPanel globalListSettingsPanel;
private final static String LAST_KEYWORD_LIST_PATH_KEY = "KeyWordImport_List";
GlobalListsManagementPanel(org.sleuthkit.autopsy.keywordsearch.GlobalListSettingsPanel gsp) {
this.globalListSettingsPanel = gsp;
@ -345,8 +349,13 @@ class GlobalListsManagementPanel extends javax.swing.JPanel implements OptionsPa
}//GEN-LAST:event_newListButtonActionPerformed
private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
String lastBaseDirectory = Paths.get(PlatformUtil.getUserConfigDirectory(), "KeywordList").toString();
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY)) {
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY);
}
File importFolder = new File(lastBaseDirectory);
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(importFolder);
final String[] AUTOPSY_EXTENSIONS = new String[]{"xml"}; //NON-NLS
final String[] ENCASE_EXTENSIONS = new String[]{"txt"}; //NON-NLS
FileNameExtensionFilter autopsyFilter = new FileNameExtensionFilter(
@ -430,7 +439,7 @@ class GlobalListsManagementPanel extends javax.swing.JPanel implements OptionsPa
KeywordSearchUtil.displayDialog(
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
}
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_KEYWORD_LIST_PATH_KEY, selFile.getParent());
}
tableModel.resync();

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode;
import static org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType.LOCATION;
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
import org.sleuthkit.autopsy.datamodel.EmptyNode;
import org.sleuthkit.autopsy.datamodel.KeyValue;
import org.sleuthkit.autopsy.datamodel.KeyValueNode;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.KeyValueQueryContent;
@ -63,21 +64,21 @@ import org.sleuthkit.datamodel.TskCoreException;
* Responsible for assembling nodes and columns in the right way and performing
* lazy queries as needed.
*/
class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
class KeywordSearchResultFactory extends ChildFactory<KeyValue> {
private static final Logger logger = Logger.getLogger(KeywordSearchResultFactory.class.getName());
private static final Logger LOGGER = Logger.getLogger(KeywordSearchResultFactory.class.getName());
//common properties (superset of all Node properties) to be displayed as columns
static final List<String> COMMON_PROPERTIES =
Stream.concat(
static final List<String> COMMON_PROPERTIES
= Stream.concat(
Stream.of(
TSK_KEYWORD,
TSK_KEYWORD_REGEXP,
TSK_KEYWORD_PREVIEW)
.map(BlackboardAttribute.ATTRIBUTE_TYPE::getDisplayName),
.map(BlackboardAttribute.ATTRIBUTE_TYPE::getDisplayName),
Arrays.stream(AbstractAbstractFileNode.AbstractFilePropertyType.values())
.map(Object::toString))
.collect(Collectors.toList());
.map(Object::toString))
.collect(Collectors.toList());
private final Collection<QueryRequest> queryRequests;
@ -93,7 +94,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
* @param toPopulate property set map for a Node
*/
@Override
protected boolean createKeys(List<KeyValueQueryContent> toPopulate) {
protected boolean createKeys(List<KeyValue> toPopulate) {
for (QueryRequest queryRequest : queryRequests) {
/**
@ -130,7 +131,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
* @return
*/
@NbBundle.Messages({"KeywordSearchResultFactory.query.exception.msg=Could not perform the query "})
private boolean createFlatKeys(KeywordSearchQuery queryRequest, List<KeyValueQueryContent> toPopulate) {
private boolean createFlatKeys(KeywordSearchQuery queryRequest, List<KeyValue> toPopulate) {
/**
* Execute the requested query.
@ -139,15 +140,15 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
try {
queryResults = queryRequest.performQuery();
} catch (KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.SEVERE, "Could not perform the query " + queryRequest.getQueryString(), ex); //NON-NLS
LOGGER.log(Level.SEVERE, "Could not perform the query " + queryRequest.getQueryString(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(Bundle.KeywordSearchResultFactory_query_exception_msg() + queryRequest.getQueryString(), ex.getCause().getMessage());
return false;
}
SleuthkitCase tskCase = null;
SleuthkitCase tskCase;
try {
tskCase = Case.getCurrentCase().getSleuthkitCase();
} catch (IllegalStateException ex) {
logger.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS
LOGGER.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS
return false;
}
@ -159,16 +160,16 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
* Get file properties.
*/
Map<String, Object> properties = new LinkedHashMap<>();
Content content = null;
String contentName = "";
Content content;
String contentName;
try {
content = tskCase.getContentById(hit.getContentID());
if (content == null) {
logger.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS
LOGGER.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS
LOGGER.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS
return false;
}
@ -191,7 +192,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
try {
hitName = tskCase.getBlackboardArtifact(hit.getArtifactID().get()).getDisplayName() + " Artifact"; //NON-NLS
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting blckboard artifact by id", ex);
LOGGER.log(Level.SEVERE, "Error getting blckboard artifact by id", ex);
return false;
}
} else {
@ -202,9 +203,13 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
}
// Add all the nodes to toPopulate at once. Minimizes node creation
// EDT threads, which can slow and/or hang the UI on large queries.
toPopulate.addAll(tempList);
if (hitNumber == 0) {
toPopulate.add(new KeyValue("This KeyValue Is Empty", 0));
} else {
// Add all the nodes to toPopulate at once. Minimizes node creation
// EDT threads, which can slow and/or hang the UI on large queries.
toPopulate.addAll(tempList);
}
//write to bb
//cannot reuse snippet in BlackboardResultWriter
@ -239,15 +244,25 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
return hits.values();
}
@NbBundle.Messages({"KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found."})
@Override
protected Node createNodeForKey(KeyValueQueryContent key) {
final Content content = key.getContent();
QueryResults hits = key.getHits();
protected Node createNodeForKey(KeyValue key) {
Node resultNode;
Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.singleton(content));
if (key instanceof KeyValueQueryContent) {
final Content content = ((KeyValueQueryContent) key).getContent();
QueryResults hits = ((KeyValueQueryContent) key).getHits();
//wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization
return new KeywordSearchFilterNode(hits, kvNode);
Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.singleton(content));
//wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization
resultNode = new KeywordSearchFilterNode(hits, kvNode);
} else {
resultNode = new EmptyNode("This Node Is Empty");
resultNode.setDisplayName(NbBundle.getMessage(this.getClass(), "KeywordSearchResultFactory.createNodeForKey.noResultsFound.text"));
}
return resultNode;
}
@ -308,7 +323,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
*/
static class BlackboardResultWriter extends SwingWorker<Void, Void> {
private static final List<BlackboardResultWriter> writers = new ArrayList<>();
private static final List<BlackboardResultWriter> WRITERS = new ArrayList<>();
private ProgressHandle progress;
private final KeywordSearchQuery query;
private final QueryResults hits;
@ -343,24 +358,24 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
try {
get();
} catch (InterruptedException | CancellationException ex) {
logger.log(Level.WARNING, "User cancelled writing of ad hoc search query results for '{0}' to the blackboard", query.getQueryString()); //NON-NLS
LOGGER.log(Level.WARNING, "User cancelled writing of ad hoc search query results for '{0}' to the blackboard", query.getQueryString()); //NON-NLS
} catch (ExecutionException ex) {
logger.log(Level.SEVERE, "Error writing of ad hoc search query results for " + query.getQueryString() + " to the blackboard", ex); //NON-NLS
LOGGER.log(Level.SEVERE, "Error writing of ad hoc search query results for " + query.getQueryString() + " to the blackboard", ex); //NON-NLS
}
}
private static synchronized void registerWriter(BlackboardResultWriter writer) {
writers.add(writer);
WRITERS.add(writer);
}
private static synchronized void deregisterWriter(BlackboardResultWriter writer) {
writers.remove(writer);
WRITERS.remove(writer);
}
static synchronized void stopAllWriters() {
for (BlackboardResultWriter w : writers) {
for (BlackboardResultWriter w : WRITERS) {
w.cancel(true);
writers.remove(w);
WRITERS.remove(w);
}
}
}

View File

@ -33,7 +33,11 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.tika.Tika;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.parser.ParsingReader;
import org.apache.tika.parser.microsoft.OfficeParserConfig;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
@ -48,6 +52,8 @@ class TikaTextExtractor extends FileTextExtractor {
static final private Logger logger = Logger.getLogger(TikaTextExtractor.class.getName());
private final ExecutorService tikaParseExecutor = Executors.newSingleThreadExecutor();
private final AutoDetectParser parser = new AutoDetectParser();
private static final List<String> TIKA_SUPPORTED_TYPES
= new Tika().getParser().getSupportedTypes(new ParseContext())
.stream()
@ -64,8 +70,18 @@ class TikaTextExtractor extends FileTextExtractor {
ReadContentInputStream stream = new ReadContentInputStream(sourceFile);
Metadata metadata = new Metadata();
ParseContext parseContext = new ParseContext();
parseContext.set(Parser.class, parser);
// Use the more memory efficient Tika SAX parsers for DOCX and
// PPTX files (it already uses SAX for XLSX).
OfficeParserConfig officeParserConfig = new OfficeParserConfig();
officeParserConfig.setUseSAXPptxExtractor(true);
officeParserConfig.setUseSAXDocxExtractor(true);
parseContext.set(OfficeParserConfig.class, officeParserConfig);
//Parse the file in a task, a convenient way to have a timeout...
final Future<Reader> future = tikaParseExecutor.submit(() -> new Tika().parse(stream, metadata));
final Future<Reader> future = tikaParseExecutor.submit(() -> new ParsingReader(parser, stream, metadata, parseContext));
try {
final Reader tikaReader = future.get(getTimeout(sourceFile.getSize()), TimeUnit.SECONDS);

View File

@ -1,5 +1,5 @@
#Updated by build script
#Fri, 05 Jan 2018 10:31:22 -0500
#Fri, 05 Jan 2018 12:14:19 -0500
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314
SPLASH_WIDTH=538

View File

@ -1,4 +1,4 @@
#Updated by build script
#Fri, 05 Jan 2018 10:31:22 -0500
#Fri, 05 Jan 2018 12:14:19 -0500
CTL_MainWindow_Title=Autopsy 4.5.0
CTL_MainWindow_Title_No_Project=Autopsy 4.5.0

View File

@ -652,10 +652,10 @@ class TestData(object):
# we are looking for is the only one in the self.reports_dir folder
html_path = ""
for fs in os.listdir(self.reports_dir):
html_path = make_path(self.reports_dir, fs)
if os.path.isdir(html_path):
if "HTML Report" in fs:
html_path = make_path(self.reports_dir, fs)
break
return make_path(html_path, os.listdir(html_path)[0])
return html_path
def get_sorted_data_path(self, file_type):
"""Get the path to the BlackboardDump file that corresponds to the given DBType.