diff --git a/Core/ivy.xml b/Core/ivy.xml index 35cb8de904..6d67fb0992 100644 --- a/Core/ivy.xml +++ b/Core/ivy.xml @@ -15,8 +15,8 @@ - - + + diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index ee7a175733..9adbad3e9a 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -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 @@ -8,7 +8,7 @@ file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.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 @@ -16,14 +16,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.sleuthkit-postgresql-4.6.0.jar=release/modules/ext/sleuthkit-postgresql-4.6.0.jar -file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.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 diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index a05219b32e..53471a3396 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -329,10 +329,6 @@ ext/jdom-2.0.5.jar release/modules/ext/jdom-2.0.5.jar - - ext/tika-core-1.14.jar - release/modules/ext/tika-core-1.14.jar - ext/sleuthkit-postgresql-4.6.0.jar release/modules/ext/sleuthkit-postgresql-4.6.0.jar @@ -346,12 +342,12 @@ release/modules/ext/curator-framework-2.8.0.jar - ext/commons-dbcp2-2.1.1.jar - release\modules\ext\commons-dbcp2-2.1.1.jar + ext/commons-compress-1.14.jar + release/modules/ext/commons-compress-1.14.jar - ext/tika-parsers-1.14.jar - release/modules/ext/tika-parsers-1.14.jar + ext/commons-dbcp2-2.1.1.jar + release\modules\ext\commons-dbcp2-2.1.1.jar ext/jython-standalone-2.7.0.jar @@ -374,12 +370,12 @@ release/modules/ext/curator-recipes-2.8.0.jar - ext/xz-1.5.jar - release/modules/ext/xz-1.5.jar + ext/metadata-extractor-2.10.1.jar + release/modules/ext/metadata-extractor-2.10.1.jar - ext/xmpcore-5.1.2.jar - release/modules/ext/xmpcore-5.1.2.jar + ext/tika-core-1.17.jar + release/modules/ext/tika-core-1.17.jar ext/StixLib.jar @@ -389,6 +385,10 @@ ext/curator-client-2.8.0.jar release/modules/ext/curator-client-2.8.0.jar + + ext/tika-parsers-1.17.jar + release/modules/ext/tika-parsers-1.17.jar + ext/sqlite-jdbc-3.8.11.jar release/modules/ext/sqlite-jdbc-3.8.11.jar @@ -397,6 +397,10 @@ ext/activemq-all-5.11.1.jar release/modules/ext/activemq-all-5.11.1.jar + + ext/xz-1.6.jar + release/modules/ext/xz-1.6.jar + ext/Rejistry-1.0-SNAPSHOT.jar release/modules/ext/Rejistry-1.0-SNAPSHOT.jar @@ -409,14 +413,6 @@ ext/commons-pool2-2.4.2.jar release\modules\ext\commons-pool2-2.4.2.jar - - ext/metadata-extractor-2.9.1.jar - release/modules/ext/metadata-extractor-2.9.1.jar - - - ext/commons-compress-1.12.jar - release/modules/ext/commons-compress-1.12.jar - ext/jsoup-1.10.3.jar release/modules/ext/jsoup-1.10.3.jar @@ -429,6 +425,10 @@ ext/c3p0-0.9.5.jar release/modules/ext/c3p0-0.9.5.jar + + ext/xmpcore-5.1.3.jar + release/modules/ext/xmpcore-5.1.3.jar + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 1cc822fea5..ab2b5c12dc 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -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 diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form new file mode 100644 index 0000000000..edda7a749c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.form @@ -0,0 +1,47 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java new file mode 100644 index 0000000000..9440ca1356 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseBrowser.java @@ -0,0 +1,296 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2017-2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.awt.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") + // //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); + }// //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 { + + private static final String ALERT_FILE_NAME = "autoingest.alert"; + private Map cases; + + /** + * Gets a list of the cases in the top level case folder + * + * @return List of cases. + * + * @throws CoordinationServiceException + */ + private Map getCases() throws CoordinationService.CoordinationServiceException { + Map casesMap = new HashMap<>(); + List 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); + }); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCaseManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCaseManager.java deleted file mode 100644 index bedc09d799..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCaseManager.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.casemodule; - -import java.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 getCases() throws CoordinationServiceException { - List cases = new ArrayList<>(); - List 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 { - - 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 { - - /** - * 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 - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form index 58ef6f79fb..3f897d70c0 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.form @@ -1,10 +1,6 @@
- - - - @@ -26,30 +22,19 @@ - + - + + - + + - - - - - - - - - - - - - + - @@ -59,26 +44,15 @@ - + - - - - - - - - - - - - - - - - + + + + + - + @@ -95,140 +69,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -239,5 +79,26 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java index e0d63f07d7..a2a2ec13ad 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserCasesPanel.java @@ -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 { // //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)) ); }// //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 { - - private List 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(); - } - } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java new file mode 100644 index 0000000000..9443ae35e9 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/MultiUserNode.java @@ -0,0 +1,241 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2017-2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.awt.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 caseMap) { + super(Children.create(new MultiUserNodeChildren(caseMap), true)); + } + + static class MultiUserNodeChildren extends ChildFactory> { + + private final Map caseMap; + + MultiUserNodeChildren(Map caseMap) { + this.caseMap = caseMap; + } + + @Override + protected boolean createKeys(List> list) { + if (caseMap != null && caseMap.size() > 0) { + list.addAll(caseMap.entrySet()); + } + return true; + } + + @Override + protected Node createNodeForKey(Entry 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 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 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. + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java index e6e8afed52..2713992139 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNodeVisitor.java @@ -41,7 +41,7 @@ public interface DisplayableItemNodeVisitor { T visit(LocalFileNode dfn); T visit(VirtualDirectoryNode ldn); - + T visit(LocalDirectoryNode ldn); T visit(DirectoryNode dn); diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddRawImageTask.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddRawImageTask.java index 14a3dc9e2f..3d576eebf0 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddRawImageTask.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddRawImageTask.java @@ -178,7 +178,7 @@ final class AddRawImageTask implements Runnable { logger.log(Level.SEVERE, errorMessage, ex); criticalErrorOccurred = true; } finally { - caseDatabase.releaseSingleUserCaseReadLock(); + caseDatabase.releaseSingleUserCaseWriteLock(); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java index 4a3a20da07..7fca6a896c 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java @@ -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); diff --git a/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java b/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java index 899de3630c..9d08bf7115 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/stix/STIXReportModule.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2013 - 2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,7 +29,7 @@ import java.util.Map; import java.util.logging.Level; import javax.swing.JPanel; import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; +import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.namespace.QName; import org.mitre.cybox.cybox_2.ObjectType; @@ -100,7 +100,7 @@ public class STIXReportModule implements GeneralReportModule { // Start the progress bar and setup the report progressPanel.setIndeterminate(false); progressPanel.start(); - progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.readSTIX")); + progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "STIXReportModule.progress.readSTIX")); reportPath = baseReportDir + getRelativeFilePath(); File reportFile = new File(reportPath); // Check if the user wants to display all output or just hits diff --git a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties index 09c6fa8906..2da0862826 100644 --- a/Core/src/org/sleuthkit/autopsy/report/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/report/Bundle.properties @@ -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 the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page 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=Warning, this report was run before ingest services completed\! # # 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\: diff --git a/Core/src/org/sleuthkit/autopsy/report/FileReportText.java b/Core/src/org/sleuthkit/autopsy/report/FileReportText.java index 6b22e4a962..c9a239cf0a 100644 --- a/Core/src/org/sleuthkit/autopsy/report/FileReportText.java +++ b/Core/src/org/sleuthkit/autopsy/report/FileReportText.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2013 - 2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java b/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java index c495ac2c72..33609f7333 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportBodyFile.java @@ -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 42six 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(); diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java index 56de46f04d..19526a0a19 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportExcel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2017 Basis Technology Corp. + * Copyright 2013-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -66,7 +66,7 @@ class ReportExcel implements TableReportModule { public void startReport(String baseReportDir) { // Set the path and save it for when the report is written to disk. this.reportPath = baseReportDir + getRelativeFilePath(); - + // Make a workbook. wb = new XSSFWorkbook(); diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java index afad0d5746..0c8aa263c3 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportGenerator.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2013 - 2018 Basis Technology Corp. * Contact: carrier sleuthkit 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 String reportPathFormatString; private final ReportGenerationPanel reportGenerationPanel = new ReportGenerationPanel(); static final String REPORTS_DIR = "Reports"; //NON-NLS @@ -93,19 +93,12 @@ class ReportGenerator { 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.reportPathFormatString = currentCase.getReportDirectory() + File.separator + currentCase.getDisplayName() + " %s " + 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. @@ -145,9 +138,17 @@ class ReportGenerator { */ void generateGeneralReport(GeneralReportModule generalReportModule) { if (generalReportModule != null) { + reportPathFormatString = String.format(reportPathFormatString, generalReportModule.getName()); + // Create the root reports directory. + try { + FileUtil.createFolder(new File(reportPathFormatString)); + } 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 + } setupProgressPanel(generalReportModule); ReportWorker worker = new ReportWorker(() -> { - generalReportModule.generateReport(reportPath, progressPanel); + generalReportModule.generateReport(reportPathFormatString, progressPanel); }); worker.execute(); displayProgressPanel(); @@ -164,9 +165,17 @@ class ReportGenerator { */ void generateTableReport(TableReportModule tableReport, Map artifactTypeSelections, Map tagNameSelections) { if (tableReport != null && null != artifactTypeSelections) { + reportPathFormatString = String.format(reportPathFormatString, tableReport.getName()); + // Create the root reports directory. + try { + FileUtil.createFolder(new File(reportPathFormatString)); + } 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 + } setupProgressPanel(tableReport); ReportWorker worker = new ReportWorker(() -> { - tableReport.startReport(reportPath); + tableReport.startReport(reportPathFormatString); TableReportGenerator generator = new TableReportGenerator(artifactTypeSelections, tagNameSelections, progressPanel, tableReport); generator.execute(); tableReport.endReport(); @@ -187,6 +196,14 @@ class ReportGenerator { */ void generateFileListReport(FileReportModule fileReportModule, Map enabledInfo) { if (fileReportModule != null && null != enabledInfo) { + reportPathFormatString = String.format(reportPathFormatString, fileReportModule.getName()); + // Create the root reports directory. + try { + FileUtil.createFolder(new File(reportPathFormatString)); + } 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 + } List enabled = new ArrayList<>(); for (Entry e : enabledInfo.entrySet()) { if (e.getValue()) { @@ -204,7 +221,7 @@ class ReportGenerator { List files = getFiles(); int numFiles = files.size(); if (progressPanel.getStatus() != ReportStatus.CANCELED) { - fileReportModule.startReport(reportPath); + fileReportModule.startReport(reportPathFormatString); fileReportModule.startTable(enabled); } progressPanel.setIndeterminate(false); @@ -262,7 +279,7 @@ class ReportGenerator { private void setupProgressPanel(ReportModule module) { String reportFilePath = module.getRelativeFilePath(); if (!reportFilePath.isEmpty()) { - this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportPath + reportFilePath); + this.progressPanel = reportGenerationPanel.addReport(module.getName(), String.format(reportPathFormatString, module.getName()) + reportFilePath); } else { this.progressPanel = reportGenerationPanel.addReport(module.getName(), null); } diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java index 834fb69710..88d9fe44b1 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportHTML.java @@ -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 42six 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 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("\n"); //NON-NLS index.append("\n"); //NON-NLS index.append("\n"); //NON-NLS - index.append("\n"); //NON-NLS - index.append("\n"); //NON-NLS + index.append("\n"); //NON-NLS + index.append("\n"); //NON-NLS index.append("").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("\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("\n\n\t").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("\n"); //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportKML.java b/Core/src/org/sleuthkit/autopsy/report/ReportKML.java index a24850c514..f089855e0c 100644 --- a/Core/src/org/sleuthkit/autopsy/report/ReportKML.java +++ b/Core/src/org/sleuthkit/autopsy/report/ReportKML.java @@ -2,7 +2,7 @@ * * Autopsy Forensic Browser * - * Copyright 2014-2016 Basis Technology Corp. + * Copyright 2014-2018 Basis Technology Corp. * contact: carrier sleuthkit 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(); diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index b5de9e9ac2..a5f7aab768 100644 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -28,8 +28,8 @@ - - + + diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 09225d0115..4031d14fc3 100644 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -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 diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 5b4cb9fd83..ca89b8c1c2 100644 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -295,17 +295,10 @@ org.apache.log4j.xml org.apache.poi org.apache.poi.common.usermodel + org.apache.poi.common.usermodel.fonts org.apache.poi.ddf org.apache.poi.dev org.apache.poi.extractor - org.apache.poi.hdf.event - org.apache.poi.hdf.extractor - org.apache.poi.hdf.extractor.data - org.apache.poi.hdf.extractor.util - org.apache.poi.hdf.model - org.apache.poi.hdf.model.hdftypes - org.apache.poi.hdf.model.hdftypes.definitions - org.apache.poi.hdf.model.util org.apache.poi.hdgf org.apache.poi.hdgf.chunks org.apache.poi.hdgf.dev @@ -313,6 +306,9 @@ org.apache.poi.hdgf.extractor org.apache.poi.hdgf.pointers org.apache.poi.hdgf.streams + org.apache.poi.hemf.extractor + org.apache.poi.hemf.hemfplus.record + org.apache.poi.hemf.record org.apache.poi.hmef org.apache.poi.hmef.attribute org.apache.poi.hmef.dev @@ -325,7 +321,6 @@ org.apache.poi.hpsf org.apache.poi.hpsf.extractor org.apache.poi.hpsf.wellknown - org.apache.poi.hslf org.apache.poi.hslf.blip org.apache.poi.hslf.dev org.apache.poi.hslf.exceptions @@ -358,7 +353,11 @@ org.apache.poi.hssf.record.crypto org.apache.poi.hssf.record.pivottable org.apache.poi.hssf.usermodel + org.apache.poi.hssf.usermodel.helpers org.apache.poi.hssf.util + org.apache.poi.hwmf.draw + org.apache.poi.hwmf.record + org.apache.poi.hwmf.usermodel org.apache.poi.hwpf org.apache.poi.hwpf.converter org.apache.poi.hwpf.dev @@ -372,18 +371,30 @@ org.apache.poi.openxml4j.opc org.apache.poi.openxml4j.opc.internal org.apache.poi.openxml4j.opc.internal.marshallers - org.apache.poi.openxml4j.opc.internal.signature org.apache.poi.openxml4j.opc.internal.unmarshallers - org.apache.poi.openxml4j.opc.signature org.apache.poi.openxml4j.util org.apache.poi.poifs.common org.apache.poi.poifs.crypt + org.apache.poi.poifs.crypt.agile + org.apache.poi.poifs.crypt.binaryrc4 + org.apache.poi.poifs.crypt.cryptoapi + org.apache.poi.poifs.crypt.dsig + org.apache.poi.poifs.crypt.dsig.facets + org.apache.poi.poifs.crypt.dsig.services + org.apache.poi.poifs.crypt.standard + org.apache.poi.poifs.crypt.temp + org.apache.poi.poifs.crypt.xor org.apache.poi.poifs.dev org.apache.poi.poifs.eventfilesystem org.apache.poi.poifs.filesystem + org.apache.poi.poifs.macros org.apache.poi.poifs.nio org.apache.poi.poifs.property org.apache.poi.poifs.storage + org.apache.poi.sl.draw + org.apache.poi.sl.draw.binding + org.apache.poi.sl.draw.geom + org.apache.poi.sl.image org.apache.poi.sl.usermodel org.apache.poi.ss org.apache.poi.ss.excelant @@ -401,15 +412,27 @@ org.apache.poi.ss.formula.udf org.apache.poi.ss.usermodel org.apache.poi.ss.usermodel.charts + org.apache.poi.ss.usermodel.helpers org.apache.poi.ss.util org.apache.poi.ss.util.cellwalk org.apache.poi.util - org.apache.poi.xslf + org.apache.poi.wp.usermodel + org.apache.poi.xdgf.exceptions + org.apache.poi.xdgf.extractor + org.apache.poi.xdgf.geom + org.apache.poi.xdgf.usermodel + org.apache.poi.xdgf.usermodel.section + org.apache.poi.xdgf.usermodel.section.geometry + org.apache.poi.xdgf.usermodel.shape + org.apache.poi.xdgf.usermodel.shape.exceptions + org.apache.poi.xdgf.util + org.apache.poi.xdgf.xml org.apache.poi.xslf.extractor org.apache.poi.xslf.model - org.apache.poi.xslf.model.geom org.apache.poi.xslf.usermodel org.apache.poi.xslf.util + org.apache.poi.xssf + org.apache.poi.xssf.binary org.apache.poi.xssf.dev org.apache.poi.xssf.eventusermodel org.apache.poi.xssf.extractor @@ -620,6 +643,8 @@ org.openxmlformats.schemas.spreadsheetml.x2006.main.impl org.openxmlformats.schemas.wordprocessingml.x2006.main org.openxmlformats.schemas.wordprocessingml.x2006.main.impl + org.openxmlformats.schemas.xpackage.x2006.digitalSignature + org.openxmlformats.schemas.xpackage.x2006.digitalSignature.impl org.reflections org.reflections.adapters org.reflections.scanners @@ -643,17 +668,10 @@ org.xml.sax.ext org.xml.sax.helpers repackage - schemaorg_apache_xmlbeans.system.sE130CAA0A01A7CDE5A2B4FEB8B311707 schemaorg_apache_xmlbeans.system.sXMLCONFIG schemaorg_apache_xmlbeans.system.sXMLLANG schemaorg_apache_xmlbeans.system.sXMLSCHEMA schemaorg_apache_xmlbeans.system.sXMLTOOLS - schemasMicrosoftComOfficeExcel - schemasMicrosoftComOfficeExcel.impl - schemasMicrosoftComOfficeOffice - schemasMicrosoftComOfficeOffice.impl - schemasMicrosoftComVml - schemasMicrosoftComVml.impl ext/commons-logging-1.1.2-sources.jar @@ -763,10 +781,6 @@ ext/joda-time-2.4-javadoc.jar release/modules/ext/joda-time-2.4-javadoc.jar - - ext/poi-excelant-3.15.jar - release/modules/ext/poi-excelant-3.15.jar - ext/imageio-psd-3.2.jar release/modules/ext/imageio-psd-3.2.jar @@ -823,10 +837,6 @@ ext/jfxtras-fxml-8.0-r4.jar release/modules/ext/jfxtras-fxml-8.0-r4.jar - - ext/poi-ooxml-3.15.jar - release/modules/ext/poi-ooxml-3.15.jar - ext/joda-time-2.4.jar release/modules/ext/joda-time-2.4.jar @@ -851,18 +861,22 @@ ext/guava-19.0.jar release/modules/ext/guava-19.0.jar + + ext/poi-3.17.jar + release/modules/ext/poi-3.17.jar + + + ext/poi-ooxml-schemas-3.17.jar + release/modules/ext/poi-ooxml-schemas-3.17.jar + + + ext/poi-scratchpad-3.17.jar + release/modules/ext/poi-scratchpad-3.17.jar + ext/commons-io-2.5.jar release/modules/ext/commons-io-2.5.jar - - ext/poi-ooxml-schemas-3.15.jar - release/modules/ext/poi-ooxml-schemas-3.15.jar - - - ext/poi-scratchpad-3.15.jar - release/modules/ext/poi-scratchpad-3.15.jar - ext/imageio-bmp-3.2.jar release/modules/ext/imageio-bmp-3.2.jar @@ -887,6 +901,10 @@ ext/ant-1.8.2.jar release/modules/ext/ant-1.8.2.jar + + ext/poi-excelant-3.17.jar + release/modules/ext/poi-excelant-3.17.jar + ext/javassist-3.12.1.GA.jar release/modules/ext/javassist-3.12.1.GA.jar @@ -899,6 +917,10 @@ ext/commons-logging-1.1.2.jar release/modules/ext/commons-logging-1.1.2.jar + + ext/poi-ooxml-3.17.jar + release/modules/ext/poi-ooxml-3.17.jar + ext/controlsfx-8.40.11.jar release/modules/ext/controlsfx-8.40.11.jar @@ -911,10 +933,6 @@ ext/javaee-api-5.0-2.jar release/modules/ext/javaee-api-5.0-2.jar - - ext/poi-3.15.jar - release/modules/ext/poi-3.15.jar - ext/common-image-3.2.jar release/modules/ext/common-image-3.2.jar diff --git a/Experimental/ivy.xml b/Experimental/ivy.xml index 93d6dafa8d..965af1bc12 100644 --- a/Experimental/ivy.xml +++ b/Experimental/ivy.xml @@ -6,7 +6,7 @@ - + diff --git a/Experimental/nbproject/project.properties b/Experimental/nbproject/project.properties index 1bd0e2fc90..2db8202ab7 100644 --- a/Experimental/nbproject/project.properties +++ b/Experimental/nbproject/project.properties @@ -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 diff --git a/Experimental/nbproject/project.xml b/Experimental/nbproject/project.xml index 8293608102..f2bf6d1996 100644 --- a/Experimental/nbproject/project.xml +++ b/Experimental/nbproject/project.xml @@ -146,12 +146,12 @@ org.sleuthkit.autopsy.experimental.configuration - ext/tika-core-1.14.jar - release/modules/ext/tika-core-1.14.jar + ext/LGoodDatePicker-10.3.1.jar + release/modules/ext/LGoodDatePicker-10.3.1.jar - ext/LGoodDatePicker-10.3.1.jar - release/modules/ext/LGoodDatePicker-10.3.1.jar + ext/tika-core-1.17.jar + release/modules/ext/tika-core-1.17.jar ext/mchange-commons-java-0.2.9.jar diff --git a/KeywordSearch/ivy.xml b/KeywordSearch/ivy.xml index 3ceb4e6378..fc6aa00269 100644 --- a/KeywordSearch/ivy.xml +++ b/KeywordSearch/ivy.xml @@ -22,7 +22,7 @@ - + diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties index 5aa1b716e0..ddc825b4d4 100644 --- a/KeywordSearch/nbproject/project.properties +++ b/KeywordSearch/nbproject/project.properties @@ -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 diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index 357c2178e2..db9ada1b1b 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -141,6 +141,10 @@ ext/commons-validator-1.5.1-sources.jar release/modules/ext/commons-validator-1.5.1-sources.jar + + ext/apache-mime4j-dom-0.8.1.jar + release/modules/ext/apache-mime4j-dom-0.8.1.jar + ext/commons-digester-1.8.1.jar release/modules/ext/commons-digester-1.8.1.jar @@ -149,14 +153,14 @@ ext/jwnl-1.3.3.jar release/modules/ext/jwnl-1.3.3.jar - - ext/tika-core-1.14.jar - release/modules/ext/tika-core-1.14.jar - ext/lucene-queryparser-4.0.0.jar release/modules/ext/lucene-queryparser-4.0.0.jar + + ext/httpclient-4.5.4.jar + release/modules/ext/httpclient-4.5.4.jar + ext/uimaj-examples-2.4.0.jar release/modules/ext/uimaj-examples-2.4.0.jar @@ -165,10 +169,6 @@ ext/cdm-4.5.5.jar release/modules/ext/cdm-4.5.5.jar - - ext/gson-2.2.4.jar - release/modules/ext/gson-2.2.4.jar - ext/org.osgi.compendium-4.0.0.jar release/modules/ext/org.osgi.compendium-4.0.0.jar @@ -177,6 +177,10 @@ ext/geoapi-3.0.0.jar release/modules/ext/geoapi-3.0.0.jar + + ext/commons-compress-1.14.jar + release/modules/ext/commons-compress-1.14.jar + ext/hamcrest-core-1.3.jar release/modules/ext/hamcrest-core-1.3.jar @@ -197,30 +201,34 @@ ext/xmlbeans-2.6.0.jar release/modules/ext/xmlbeans-2.6.0.jar - - ext/maven-scm-api-1.4.jar - release/modules/ext/maven-scm-api-1.4.jar - ext/quartz-2.2.0.jar release/modules/ext/quartz-2.2.0.jar - ext/jackcess-2.1.4.jar - release/modules/ext/jackcess-2.1.4.jar - - - ext/slf4j-api-1.7.12.jar - release/modules/ext/slf4j-api-1.7.12.jar + ext/sqlite-jdbc-3.19.3.jar + release/modules/ext/sqlite-jdbc-3.19.3.jar ext/guava-17.0.jar release/modules/ext/guava-17.0.jar + + ext/metadata-extractor-2.10.1.jar + release/modules/ext/metadata-extractor-2.10.1.jar + + + ext/apache-mime4j-core-0.8.1.jar + release/modules/ext/apache-mime4j-core-0.8.1.jar + ext/opennlp-maxent-3.0.3.jar release/modules/ext/opennlp-maxent-3.0.3.jar + + ext/pdfbox-tools-2.0.8.jar + release/modules/ext/pdfbox-tools-2.0.8.jar + ext/jVinci-2.6.0.jar release/modules/ext/jVinci-2.6.0.jar @@ -229,18 +237,14 @@ ext/json-simple-1.1.1.jar release/modules/ext/json-simple-1.1.1.jar + + ext/tika-parsers-1.17.jar + release/modules/ext/tika-parsers-1.17.jar + ext/sis-utility-0.6.jar release/modules/ext/sis-utility-0.6.jar - - ext/jj2000-5.2.jar - release/modules/ext/jj2000-5.2.jar - - - ext/httpclient-4.3.1.jar - release/modules/ext/httpclient-4.3.1.jar - ext/jhighlight-1.0.2.jar release/modules/ext/jhighlight-1.0.2.jar @@ -258,12 +262,12 @@ release/modules/ext/ctakes-utils-3.2.2.jar - ext/apache-mime4j-dom-0.7.2.jar - release/modules/ext/apache-mime4j-dom-0.7.2.jar + ext/cxf-rt-rs-client-3.0.16.jar + release/modules/ext/cxf-rt-rs-client-3.0.16.jar - ext/commons-compress-1.12.jar - release/modules/ext/commons-compress-1.12.jar + ext/jempbox-1.8.13.jar + release/modules/ext/jempbox-1.8.13.jar ext/openaifsm-0.0.1.jar @@ -277,14 +281,18 @@ ext/commons-collections4-4.1.jar release/modules/ext/commons-collections4-4.1.jar - - ext/cxf-rt-rs-client-3.0.3.jar - release/modules/ext/cxf-rt-rs-client-3.0.3.jar - ext/solr-solrj-4.9.1.jar release/modules/ext/solr-solrj-4.9.1.jar + + ext/xmpcore-5.1.3.jar + release/modules/ext/xmpcore-5.1.3.jar + + + ext/jackcess-2.1.8.jar + release/modules/ext/jackcess-2.1.8.jar + ext/findstructapi-0.0.1.jar release/modules/ext/findstructapi-0.0.1.jar @@ -317,6 +325,22 @@ ext/commons-codec-1.10.jar release/modules/ext/commons-codec-1.10.jar + + ext/gson-2.8.1.jar + release/modules/ext/gson-2.8.1.jar + + + ext/poi-ooxml-schemas-3.17.jar + release/modules/ext/poi-ooxml-schemas-3.17.jar + + + ext/poi-scratchpad-3.17.jar + release/modules/ext/poi-scratchpad-3.17.jar + + + ext/poi-3.17.jar + release/modules/ext/poi-3.17.jar + ext/lucene-queries-4.0.0.jar release/modules/ext/lucene-queries-4.0.0.jar @@ -326,45 +350,25 @@ release/modules/ext/bcprov-jdk15on-1.54.jar - ext/poi-ooxml-schemas-3.15.jar - release/modules/ext/poi-ooxml-schemas-3.15.jar - - - ext/poi-scratchpad-3.15.jar - release/modules/ext/poi-scratchpad-3.15.jar + ext/fontbox-2.0.8.jar + release/modules/ext/fontbox-2.0.8.jar ext/solr-solrj-4.9.1-sources.jar release/modules/ext/solr-solrj-4.9.1-sources.jar - - ext/commons-vfs2-2.0.jar - release/modules/ext/commons-vfs2-2.0.jar - - - ext/tika-parsers-1.14.jar - release/modules/ext/tika-parsers-1.14.jar - - - ext/jackcess-encrypt-2.1.1.jar - release/modules/ext/jackcess-encrypt-2.1.1.jar - - - ext/spring-expression-3.1.2.RELEASE.jar - release/modules/ext/spring-expression-3.1.2.RELEASE.jar - ext/lucene-analyzers-common-4.0.0.jar release/modules/ext/lucene-analyzers-common-4.0.0.jar - - ext/tika-parsers-1.14-sources.jar - release/modules/ext/tika-parsers-1.14-sources.jar - ext/javax.ws.rs-api-2.0.1.jar release/modules/ext/javax.ws.rs-api-2.0.1.jar + + ext/httpmime-4.5.4.jar + release/modules/ext/httpmime-4.5.4.jar + ext/junrar-0.7.jar release/modules/ext/junrar-0.7.jar @@ -378,21 +382,13 @@ release/modules/ext/noggit-0.5.jar - ext/xmlschema-core-2.1.0.jar - release/modules/ext/xmlschema-core-2.1.0.jar - - - ext/httpmime-4.3.1.jar - release/modules/ext/httpmime-4.3.1.jar + ext/poi-ooxml-3.17.jar + release/modules/ext/poi-ooxml-3.17.jar ext/jna-4.1.0.jar release/modules/ext/jna-4.1.0.jar - - ext/xz-1.5.jar - release/modules/ext/xz-1.5.jar - ext/qdox-1.12.jar release/modules/ext/qdox-1.12.jar @@ -410,37 +406,17 @@ release/modules/ext/grib-4.5.5.jar - ext/maven-scm-provider-svn-commons-1.4.jar - release/modules/ext/maven-scm-provider-svn-commons-1.4.jar - - - ext/poi-3.15.jar - release/modules/ext/poi-3.15.jar - - - ext/spring-aop-3.1.2.RELEASE.jar - release/modules/ext/spring-aop-3.1.2.RELEASE.jar - - - ext/json-20140107.jar - release/modules/ext/json-20140107.jar + ext/jackson-core-2.9.2.jar + release/modules/ext/jackson-core-2.9.2.jar ext/uimaj-core-2.5.0.jar release/modules/ext/uimaj-core-2.5.0.jar - - ext/pdfbox-2.0.3.jar - release/modules/ext/pdfbox-2.0.3.jar - ext/jmatio-1.2.jar release/modules/ext/jmatio-1.2.jar - - ext/metadata-extractor-2.9.1.jar - release/modules/ext/metadata-extractor-2.9.1.jar - ext/commons-csv-1.0.jar release/modules/ext/commons-csv-1.0.jar @@ -466,21 +442,13 @@ release/modules/ext/httpservices-4.5.5.jar - ext/plexus-utils-1.5.6.jar - release/modules/ext/plexus-utils-1.5.6.jar - - - ext/fontbox-2.0.3.jar - release/modules/ext/fontbox-2.0.3.jar + ext/httpcore-4.4.7.jar + release/modules/ext/httpcore-4.4.7.jar ext/bcmail-jdk15on-1.54.jar release/modules/ext/bcmail-jdk15on-1.54.jar - - ext/spring-beans-3.1.2.RELEASE.jar - release/modules/ext/spring-beans-3.1.2.RELEASE.jar - ext/solr-solrj-4.9.1-javadoc.jar release/modules/ext/solr-solrj-4.9.1-javadoc.jar @@ -490,8 +458,8 @@ release/modules/ext/asm-all-3.1.jar - ext/tika-parsers-1.14-javadoc.jar - release/modules/ext/tika-parsers-1.14-javadoc.jar + ext/tika-parsers-1.17-javadoc.jar + release/modules/ext/tika-parsers-1.17-javadoc.jar ext/icu4j-3.8.jar @@ -501,10 +469,6 @@ ext/curvesapi-1.04.jar release/modules/ext/curvesapi-1.04.jar - - ext/xmpcore-5.1.2.jar - release/modules/ext/xmpcore-5.1.2.jar - ext/sis-referencing-0.6.jar release/modules/ext/sis-referencing-0.6.jar @@ -521,6 +485,10 @@ ext/tagsoup-1.2.1.jar release/modules/ext/tagsoup-1.2.1.jar + + ext/tika-core-1.17.jar + release/modules/ext/tika-core-1.17.jar + ext/lucene-core-4.0.0.jar release/modules/ext/lucene-core-4.0.0.jar @@ -533,10 +501,6 @@ ext/commons-logging-1.2.jar release/modules/ext/commons-logging-1.2.jar - - ext/jackson-core-2.8.1.jar - release/modules/ext/jackson-core-2.8.1.jar - ext/org.osgi.core-4.0.0.jar release/modules/ext/org.osgi.core-4.0.0.jar @@ -545,10 +509,18 @@ ext/c3p0-0.9.1.1.jar release/modules/ext/c3p0-0.9.1.1.jar + + ext/tika-parsers-1.17-sources.jar + release/modules/ext/tika-parsers-1.17-sources.jar + ext/sqlwrapper-0.0.1.jar release/modules/ext/sqlwrapper-0.0.1.jar + + ext/jackcess-encrypt-2.1.2.jar + release/modules/ext/jackcess-encrypt-2.1.2.jar + ext/jericho-html-3.3-javadoc.jar release/modules/ext/jericho-html-3.3-javadoc.jar @@ -557,18 +529,10 @@ ext/udunits-4.5.5.jar release/modules/ext/udunits-4.5.5.jar - - ext/aopalliance-1.0.jar - release/modules/ext/aopalliance-1.0.jar - ext/commons-collections-3.2.2.jar release/modules/ext/commons-collections-3.2.2.jar - - ext/cxf-rt-frontend-jaxrs-3.0.3.jar - release/modules/ext/cxf-rt-frontend-jaxrs-3.0.3.jar - ext/uimaj-document-annotation-2.5.0.jar release/modules/ext/uimaj-document-annotation-2.5.0.jar @@ -577,41 +541,29 @@ ext/woodstox-core-asl-4.4.1.jar release/modules/ext/woodstox-core-asl-4.4.1.jar - - ext/poi-ooxml-3.15.jar - release/modules/ext/poi-ooxml-3.15.jar - ext/org.apache.felix.scr.generator-1.1.2.jar release/modules/ext/org.apache.felix.scr.generator-1.1.2.jar + + ext/pdfbox-2.0.8.jar + release/modules/ext/pdfbox-2.0.8.jar + ext/zookeeper-3.4.6.jar release/modules/ext/zookeeper-3.4.6.jar - ext/cxf-rt-transports-http-3.0.3.jar - release/modules/ext/cxf-rt-transports-http-3.0.3.jar - - - ext/pdfbox-debugger-2.0.3.jar - release/modules/ext/pdfbox-debugger-2.0.3.jar - - - ext/spring-core-3.1.2.RELEASE.jar - release/modules/ext/spring-core-3.1.2.RELEASE.jar + ext/cxf-rt-transports-http-3.0.16.jar + release/modules/ext/cxf-rt-transports-http-3.0.16.jar ext/netcdf4-4.5.5.jar release/modules/ext/netcdf4-4.5.5.jar - ext/spring-asm-3.1.2.RELEASE.jar - release/modules/ext/spring-asm-3.1.2.RELEASE.jar - - - ext/junit-4.11.jar - release/modules/ext/junit-4.11.jar + ext/slf4j-api-1.7.24.jar + release/modules/ext/slf4j-api-1.7.24.jar ext/protobuf-java-2.5.0.jar @@ -642,37 +594,17 @@ release/modules/ext/commons-lang-2.6.jar - ext/sqlite-jdbc-3.8.11.2.jar - release/modules/ext/sqlite-jdbc-3.8.11.2.jar - - - ext/jempbox-1.8.12.jar - release/modules/ext/jempbox-1.8.12.jar - - - ext/maven-scm-provider-svnexe-1.4.jar - release/modules/ext/maven-scm-provider-svnexe-1.4.jar + ext/cxf-core-3.0.16.jar + release/modules/ext/cxf-core-3.0.16.jar ext/opennlp-tools-1.5.3.jar release/modules/ext/opennlp-tools-1.5.3.jar - - ext/apache-mime4j-core-0.7.2.jar - release/modules/ext/apache-mime4j-core-0.7.2.jar - ext/rome-utils-1.5.1.jar release/modules/ext/rome-utils-1.5.1.jar - - ext/httpcore-4.3.jar - release/modules/ext/httpcore-4.3.jar - - - ext/pdfbox-tools-2.0.3.jar - release/modules/ext/pdfbox-tools-2.0.3.jar - ext/sis-storage-0.6.jar release/modules/ext/sis-storage-0.6.jar @@ -689,6 +621,10 @@ ext/uimafit-core-2.1.0.jar release/modules/ext/uimafit-core-2.1.0.jar + + ext/cxf-rt-frontend-jaxrs-3.0.16.jar + release/modules/ext/cxf-rt-frontend-jaxrs-3.0.16.jar + ext/cleartk-util-2.0.0.jar release/modules/ext/cleartk-util-2.0.0.jar @@ -697,14 +633,6 @@ ext/jdom-1.0.jar release/modules/ext/jdom-1.0.jar - - ext/cxf-core-3.0.3.jar - release/modules/ext/cxf-core-3.0.3.jar - - - ext/regexp-1.3.jar - release/modules/ext/regexp-1.3.jar - ext/commons-beanutils-1.9.2.jar release/modules/ext/commons-beanutils-1.9.2.jar @@ -713,10 +641,6 @@ ext/ehcache-core-2.6.2.jar release/modules/ext/ehcache-core-2.6.2.jar - - ext/spring-context-3.1.2.RELEASE.jar - release/modules/ext/spring-context-3.1.2.RELEASE.jar - ext/ctakes-type-system-3.2.2.jar release/modules/ext/ctakes-type-system-3.2.2.jar diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java index a48b40e756..a8bc995eae 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit 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 { +class KeywordSearchResultFactory extends ChildFactory { - 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 COMMON_PROPERTIES = - Stream.concat( + static final List 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 queryRequests; @@ -93,7 +94,7 @@ class KeywordSearchResultFactory extends ChildFactory { * @param toPopulate property set map for a Node */ @Override - protected boolean createKeys(List toPopulate) { + protected boolean createKeys(List toPopulate) { for (QueryRequest queryRequest : queryRequests) { /** @@ -130,7 +131,7 @@ class KeywordSearchResultFactory extends ChildFactory { * @return */ @NbBundle.Messages({"KeywordSearchResultFactory.query.exception.msg=Could not perform the query "}) - private boolean createFlatKeys(KeywordSearchQuery queryRequest, List toPopulate) { + private boolean createFlatKeys(KeywordSearchQuery queryRequest, List toPopulate) { /** * Execute the requested query. @@ -139,15 +140,15 @@ class KeywordSearchResultFactory extends ChildFactory { 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 { * Get file properties. */ Map 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 { 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 { } - // 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 { 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 { */ static class BlackboardResultWriter extends SwingWorker { - private static final List writers = new ArrayList<>(); + private static final List WRITERS = new ArrayList<>(); private ProgressHandle progress; private final KeywordSearchQuery query; private final QueryResults hits; @@ -343,24 +358,24 @@ class KeywordSearchResultFactory extends ChildFactory { 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); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java index fcbace158d..4b9c3b17cb 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TikaTextExtractor.java @@ -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 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 future = tikaParseExecutor.submit(() -> new Tika().parse(stream, metadata)); + final Future future = tikaParseExecutor.submit(() -> new ParsingReader(parser, stream, metadata, parseContext)); try { final Reader tikaReader = future.get(getTimeout(sourceFile.getSize()), TimeUnit.SECONDS); diff --git a/test/script/regression.py b/test/script/regression.py index be6515f054..afe1ea4976 100644 --- a/test/script/regression.py +++ b/test/script/regression.py @@ -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.