From d07e96359835ebb3c0d21e3dd96157f955efaf45 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 23 Jul 2020 08:42:48 -0400 Subject: [PATCH 1/2] remove folder for fix --- .../Bundle.properties-MERGED | 73 -- .../datasourceSummary/Bundle_ja.properties | 73 -- .../datasourcesummary/Bundle.properties | 38 - .../datasourcesummary/DataSourceBrowser.form | 18 - .../datasourcesummary/DataSourceBrowser.java | 251 ------- .../DataSourceInfoUtilities.java | 366 --------- .../DataSourceLabeledValueCallback.java | 71 -- .../DataSourceSingleValueCallback.java | 66 -- .../datasourcesummary/DataSourceSummary.java | 180 ----- .../DataSourceSummaryAction.java | 75 -- .../DataSourceSummaryCountsPanel.form | 139 ---- .../DataSourceSummaryCountsPanel.java | 395 ---------- .../DataSourceSummaryDetailsPanel.form | 495 ------------- .../DataSourceSummaryDetailsPanel.java | 698 ------------------ .../DataSourceSummaryDialog.form | 82 -- .../DataSourceSummaryDialog.java | 178 ----- .../DataSourceSummaryNode.java | 216 ------ .../RightAlignedTableCellRenderer.java | 61 -- .../ViewSummaryInformationAction.java | 67 -- 19 files changed, 3542 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties-MERGED delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle_ja.properties delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java delete mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties-MERGED deleted file mode 100755 index fe998b0e57..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle.properties-MERGED +++ /dev/null @@ -1,73 +0,0 @@ -CTL_DataSourceSummaryAction=Data Source Summary -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=Count -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos -DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case. -DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure -DataSourceSummaryDetailsPanel.units.bytes=\ bytes -DataSourceSummaryDetailsPanel.units.gigabytes=\ GB -DataSourceSummaryDetailsPanel.units.kilobytes=\ kB -DataSourceSummaryDetailsPanel.units.megabytes=\ MB -DataSourceSummaryDetailsPanel.units.petabytes=\ PB -DataSourceSummaryDetailsPanel.units.terabytes=\ TB -DataSourceSummaryDialog.closeButton.text=Close -DataSourceSummaryDetailsPanel.displayNameLabel.text=Display Name: -DataSourceSummaryDetailsPanel.originalNameLabel.text=Name: -DataSourceSummaryDetailsPanel.deviceIdLabel.text=Device ID: -DataSourceSummaryDetailsPanel.operatingSystemLabel.text=OS: -DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text=Usage: -DataSourceSummaryDetailsPanel.timeZoneLabel.text=Time Zone: -DataSourceSummaryDetailsPanel.imageTypeLabel.text=Image Type: -DataSourceSummaryDetailsPanel.sizeLabel.text=Size: -DataSourceSummaryDetailsPanel.sectorSizeLabel.text=Sector Size: -DataSourceSummaryDetailsPanel.md5HashLabel.text=MD5: -DataSourceSummaryDetailsPanel.sha1HashLabel.text=SHA1: -DataSourceSummaryDetailsPanel.sha256HashLabel.text=SHA256: -DataSourceSummaryDetailsPanel.filePathsLabel.text=File Paths: -DataSourceSummaryDetailsPanel.displayNameValue.text= -DataSourceSummaryDetailsPanel.originalNameValue.text= -DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText= -DataSourceSummaryDetailsPanel.deviceIdValue.text= -DataSourceSummaryDetailsPanel.dataSourceUsageValue.text= -DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText= -DataSourceSummaryDetailsPanel.operatingSystemValue.text= -DataSourceSummaryDetailsPanel.timeZoneValue.text= -DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText= -DataSourceSummaryDetailsPanel.imageTypeValue.text= -DataSourceSummaryDetailsPanel.sizeValue.text= -DataSourceSummaryDetailsPanel.sectorSizeValue.text= -DataSourceSummaryDetailsPanel.md5HashValue.toolTipText= -DataSourceSummaryDetailsPanel.md5HashValue.text= -DataSourceSummaryDetailsPanel.sha1HashValue.text= -DataSourceSummaryDetailsPanel.sha256HashValue.text= -DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0= -DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= -DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details: -DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: -DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= -DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type -DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category -DataSourceSummaryCountsPanel.jLabel1.text=Results by Type -DataSourceSummaryDialog.countsTab.title=Counts -DataSourceSummaryDialog.detailsTab.title=Details -DataSourceSummaryDialog.ingestHistoryTab.title=Ingest History -DataSourceSummaryDialog.window.title=Data Sources Summary -DataSourceSummaryNode.column.dataSourceName.header=Data Source Name -DataSourceSummaryNode.column.files.header=Files -DataSourceSummaryNode.column.results.header=Results -DataSourceSummaryNode.column.status.header=Ingest Status -DataSourceSummaryNode.column.tags.header=Tags -DataSourceSummaryNode.column.type.header=Type -DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source -ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle_ja.properties deleted file mode 100644 index 99fd24c7ef..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourceSummary/Bundle_ja.properties +++ /dev/null @@ -1,73 +0,0 @@ -CTL_DataSourceSummaryAction=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30b5\u30de\u30ea\u30fc -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=\u3059\u3079\u3066 -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=\u5272\u308a\u5f53\u3066\u6e08\u307f -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=\u30ab\u30a6\u30f3\u30c8 -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 -DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=\u672a\u4f7f\u7528 -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=\u97f3\u58f0 -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=\u30ab\u30a6\u30f3\u30c8 -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=\u6587\u66f8 -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=\u5b9f\u884c\u53ef\u80fd\u30d5\u30a1\u30a4\u30eb -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=\u30a4\u30e1\u30fc\u30b8 -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 -DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=\u52d5\u753b -DataSourceSummaryDetailsPanel.getDataSources.error.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30ea\u30b9\u30c8\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -DataSourceSummaryDetailsPanel.getDataSources.error.title=\u8aad\u307f\u8fbc\u307f\u5931\u6557 -DataSourceSummaryDetailsPanel.units.bytes=\ \u30d0\u30a4\u30c8 -DataSourceSummaryDetailsPanel.units.gigabytes=\ GB -DataSourceSummaryDetailsPanel.units.kilobytes=\ kB -DataSourceSummaryDetailsPanel.units.megabytes=\ MB -DataSourceSummaryDetailsPanel.units.petabytes=\ PB -DataSourceSummaryDetailsPanel.units.terabytes=\ TB -DataSourceSummaryDialog.closeButton.text=\u9589\u3058\u308b -DataSourceSummaryDetailsPanel.displayNameLabel.text=\u8868\u793a\u540d: -DataSourceSummaryDetailsPanel.originalNameLabel.text=\u540d\u524d: -DataSourceSummaryDetailsPanel.deviceIdLabel.text=\u30c7\u30d0\u30a4\u30b9ID: -DataSourceSummaryDetailsPanel.operatingSystemLabel.text=OS: -DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text=\u4f7f\u7528\u91cf: -DataSourceSummaryDetailsPanel.timeZoneLabel.text=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3: -DataSourceSummaryDetailsPanel.imageTypeLabel.text=\u30a4\u30e1\u30fc\u30b8\u30bf\u30a4\u30d7: -DataSourceSummaryDetailsPanel.sizeLabel.text=\u30b5\u30a4\u30ba: -DataSourceSummaryDetailsPanel.sectorSizeLabel.text=\u30bb\u30af\u30bf\u30fc\u30b5\u30a4\u30ba: -DataSourceSummaryDetailsPanel.md5HashLabel.text=MD5: -DataSourceSummaryDetailsPanel.sha1HashLabel.text=SHA1: -DataSourceSummaryDetailsPanel.sha256HashLabel.text=SHA256: -DataSourceSummaryDetailsPanel.filePathsLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9: -DataSourceSummaryDetailsPanel.displayNameValue.text= -DataSourceSummaryDetailsPanel.originalNameValue.text= -DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText= -DataSourceSummaryDetailsPanel.deviceIdValue.text= -DataSourceSummaryDetailsPanel.dataSourceUsageValue.text= -DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText= -DataSourceSummaryDetailsPanel.operatingSystemValue.text= -DataSourceSummaryDetailsPanel.timeZoneValue.text= -DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText= -DataSourceSummaryDetailsPanel.imageTypeValue.text= -DataSourceSummaryDetailsPanel.sizeValue.text= -DataSourceSummaryDetailsPanel.sectorSizeValue.text= -DataSourceSummaryDetailsPanel.md5HashValue.toolTipText= -DataSourceSummaryDetailsPanel.md5HashValue.text= -DataSourceSummaryDetailsPanel.sha1HashValue.text= -DataSourceSummaryDetailsPanel.sha256HashValue.text= -DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0= -DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= -DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=\u53d6\u5f97\u306e\u8a73\u7d30: -DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=\u672a\u4f7f\u7528\u9818\u57df: -DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= -DataSourceSummaryCountsPanel.byMimeTypeLabel.text=MIME\u30bf\u30a4\u30d7\u5225\u30d5\u30a1\u30a4\u30eb -DataSourceSummaryCountsPanel.byCategoryLabel.text=\u30ab\u30c6\u30b4\u30ea\u30fc\u5225\u30d5\u30a1\u30a4\u30eb -DataSourceSummaryCountsPanel.jLabel1.text=\u30bf\u30a4\u30d7\u5225\u7d50\u679c -DataSourceSummaryDialog.countsTab.title=\u30ab\u30a6\u30f3\u30c8 -DataSourceSummaryDialog.detailsTab.title=\u8a73\u7d30 -DataSourceSummaryDialog.ingestHistoryTab.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u5c65\u6b74 -DataSourceSummaryDialog.window.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30b5\u30de\u30ea\u30fc -DataSourceSummaryNode.column.dataSourceName.header=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d -DataSourceSummaryNode.column.files.header=\u30d5\u30a1\u30a4\u30eb -DataSourceSummaryNode.column.results.header=\u7d50\u679c -DataSourceSummaryNode.column.status.header=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b9\u30c6\u30fc\u30bf\u30b9 -DataSourceSummaryNode.column.tags.header=\u30bf\u30b0 -DataSourceSummaryNode.column.type.header=\u30bf\u30a4\u30d7 -DataSourceSummaryNode.viewDataSourceAction.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u79fb\u52d5 -ViewSummaryInformationAction.name.text=\u30b5\u30de\u30ea\u30fc\u60c5\u5831\u3092\u8868\u793a diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties deleted file mode 100644 index 2cb4756460..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties +++ /dev/null @@ -1,38 +0,0 @@ -DataSourceSummaryDialog.closeButton.text=Close -DataSourceSummaryDetailsPanel.displayNameLabel.text=Display Name: -DataSourceSummaryDetailsPanel.originalNameLabel.text=Name: -DataSourceSummaryDetailsPanel.deviceIdLabel.text=Device ID: -DataSourceSummaryDetailsPanel.operatingSystemLabel.text=OS: -DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text=Usage: -DataSourceSummaryDetailsPanel.timeZoneLabel.text=Time Zone: -DataSourceSummaryDetailsPanel.imageTypeLabel.text=Image Type: -DataSourceSummaryDetailsPanel.sizeLabel.text=Size: -DataSourceSummaryDetailsPanel.sectorSizeLabel.text=Sector Size: -DataSourceSummaryDetailsPanel.md5HashLabel.text=MD5: -DataSourceSummaryDetailsPanel.sha1HashLabel.text=SHA1: -DataSourceSummaryDetailsPanel.sha256HashLabel.text=SHA256: -DataSourceSummaryDetailsPanel.filePathsLabel.text=File Paths: -DataSourceSummaryDetailsPanel.displayNameValue.text= -DataSourceSummaryDetailsPanel.originalNameValue.text= -DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText= -DataSourceSummaryDetailsPanel.deviceIdValue.text= -DataSourceSummaryDetailsPanel.dataSourceUsageValue.text= -DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText= -DataSourceSummaryDetailsPanel.operatingSystemValue.text= -DataSourceSummaryDetailsPanel.timeZoneValue.text= -DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText= -DataSourceSummaryDetailsPanel.imageTypeValue.text= -DataSourceSummaryDetailsPanel.sizeValue.text= -DataSourceSummaryDetailsPanel.sectorSizeValue.text= -DataSourceSummaryDetailsPanel.md5HashValue.toolTipText= -DataSourceSummaryDetailsPanel.md5HashValue.text= -DataSourceSummaryDetailsPanel.sha1HashValue.text= -DataSourceSummaryDetailsPanel.sha256HashValue.text= -DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0= -DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= -DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details: -DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: -DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= -DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type -DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category -DataSourceSummaryCountsPanel.jLabel1.text=Results by Type diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form deleted file mode 100644 index bb3b76f532..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form +++ /dev/null @@ -1,18 +0,0 @@ - - -
- - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java deleted file mode 100644 index 92967738b0..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.awt.EventQueue; -import java.beans.PropertyVetoException; -import javax.swing.ListSelectionModel; -import org.netbeans.swing.outline.DefaultOutlineModel; -import org.netbeans.swing.outline.Outline; -import org.openide.explorer.ExplorerManager; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Observer; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; -import javax.swing.event.ListSelectionListener; -import org.openide.nodes.Node; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryNode.DataSourceSummaryEntryNode; -import static javax.swing.SwingConstants.RIGHT; -import javax.swing.SwingUtilities; -import javax.swing.table.TableColumn; -import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.IngestJobInfo; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Panel which allows viewing and selecting of Data Sources and some of their - * related information. - */ -final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { - - private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(DataSourceBrowser.class.getName()); - private static final int COUNT_COLUMN_WIDTH = 20; - private static final int INGEST_STATUS_WIDTH = 50; - private static final int USAGE_COLUMN_WIDTH = 110; - private static final int DATA_SOURCE_COLUMN_WIDTH = 280; - private final Outline outline; - private final org.openide.explorer.view.OutlineView outlineView; - private final ExplorerManager explorerManager; - private final List dataSourceSummaryList; - private final RightAlignedTableCellRenderer rightAlignedRenderer = new RightAlignedTableCellRenderer(); - - /** - * Creates new form DataSourceBrowser - */ - DataSourceBrowser(Map usageMap, Map fileCountsMap) { - initComponents(); - rightAlignedRenderer.setHorizontalAlignment(RIGHT); - explorerManager = new ExplorerManager(); - outlineView = new org.openide.explorer.view.OutlineView(); - this.setVisible(true); - outlineView.setPropertyColumns( - Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), - Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), - Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), - Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(), - Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header()); - outline = outlineView.getOutline(); - - outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - dataSourceSummaryList = getDataSourceSummaryList(usageMap, fileCountsMap); - outline.setRootVisible(false); - add(outlineView, java.awt.BorderLayout.CENTER); - explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList)); - ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.DataSourceSummaryNode_column_dataSourceName_header()); - for (TableColumn column : Collections.list(outline.getColumnModel().getColumns())) { - if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_files_header()) - || column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_results_header()) - || column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_tags_header())) { - column.setCellRenderer(rightAlignedRenderer); - column.setPreferredWidth(COUNT_COLUMN_WIDTH); - } else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_type_header())) { - column.setPreferredWidth(USAGE_COLUMN_WIDTH); - } else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_status_header())) { - column.setPreferredWidth(INGEST_STATUS_WIDTH); - } else { - column.setPreferredWidth(DATA_SOURCE_COLUMN_WIDTH); - } - } - this.setVisible(true); - } - - /** - * Select the datasource which matches the specified data source object id. - * If the specified id is null or no data source matches the id the first - * data source will be selected instead. - * - * @param dataSourceId the object id of the data source to select, null if - * the first data source should be selected - */ - void selectDataSource(Long dataSourceId) { - EventQueue.invokeLater(() -> { - if (dataSourceId != null) { - for (Node node : explorerManager.getRootContext().getChildren().getNodes()) { - if (node instanceof DataSourceSummaryEntryNode && ((DataSourceSummaryEntryNode) node).getDataSource().getId() == dataSourceId) { - try { - explorerManager.setExploredContextAndSelection(node, new Node[]{node}); - return; - } catch (PropertyVetoException ex) { - logger.log(Level.WARNING, "Failed to select the datasource in the explorer view", ex); //NON-NLS - } - } - } - } - //if no data source was selected and there are data sources to select select the first one - if (explorerManager.getRootContext().getChildren().getNodes().length > 0) { - outline.getSelectionModel().setSelectionInterval(0, 0); - } - }); - } - - /** - * Add the specified observer as an observer of the DataSourceSummaryNode's - * observable. - * - * @param observer the observer which should be added - */ - void addObserver(Observer observer) { - ((DataSourceSummaryNode) explorerManager.getRootContext()).addObserver(observer); - } - - /** - * Get a list of the DataSourceSummary objects representing the information - * to be displayed for each DataSource in this browser. - * - * @return list containing a DataSourceSummary object for each DataSource in - * the current case. - */ - private List getDataSourceSummaryList(Map usageMap, Map fileCountsMap) { - List summaryList = new ArrayList<>(); - - final Map artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts(); - final Map tagCountsMap = DataSourceInfoUtilities.getCountsOfTags(); - try { - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - for (DataSource dataSource : skCase.getDataSources()) { - summaryList.add(new DataSourceSummary(dataSource, usageMap.get(dataSource.getId()), - fileCountsMap.get(dataSource.getId()), artifactCountsMap.get(dataSource.getId()), tagCountsMap.get(dataSource.getId()))); - } - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to datasources or their counts, providing empty results", ex); - } - return summaryList; - } - - /** - * 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); - } - - /** - * Get the DataSource which is currently selected in the ExplorerManager - * - * @return the selected DataSource - */ - DataSource getSelectedDataSource() { - Node selectedNode[] = explorerManager.getSelectedNodes(); - if (selectedNode.length == 1 && selectedNode[0] instanceof DataSourceSummaryEntryNode) { - return ((DataSourceSummaryEntryNode) selectedNode[0]).getDataSource(); - } - return null; - } - - /** - * Update the DataSourceBrowser to display up to date status information for - * the data sources. - * - * @param dataSourceId the ID of the data source which should be updated - * @param newStatus the new status which the data source should have - */ - void refresh(long dataSourceId, IngestJobInfo.IngestJobStatusType newStatus) { - - //attempt to update the status of any datasources that had status which was STARTED - for (DataSourceSummary summary : dataSourceSummaryList) { - if (summary.getDataSource().getId() == dataSourceId) { - summary.setIngestStatus(newStatus); - } - } - //figure out which nodes were previously selected - Node[] selectedNodes = explorerManager.getSelectedNodes(); - SwingUtilities.invokeLater(() -> { - explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList)); - List nodesToSelect = new ArrayList<>(); - for (Node node : explorerManager.getRootContext().getChildren().getNodes()) { - if (node instanceof DataSourceSummaryEntryNode) { - //there should only be one selected node as multi-select is disabled - for (Node selectedNode : selectedNodes) { - if (((DataSourceSummaryEntryNode) node).getDataSource().equals(((DataSourceSummaryEntryNode) selectedNode).getDataSource())) { - nodesToSelect.add(node); - } - } - } - } - //reselect the previously selected Nodes - try { - explorerManager.setSelectedNodes(nodesToSelect.toArray(new Node[nodesToSelect.size()])); - } catch (PropertyVetoException ex) { - logger.log(Level.WARNING, "Error selecting previously selected nodes", ex); - } - - }); - - } - - /** - * 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() { - - setLayout(new java.awt.BorderLayout()); - }// //GEN-END:initComponents - - @Override - public ExplorerManager getExplorerManager() { - return explorerManager; - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java deleted file mode 100644 index c2d8263056..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Set; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.TskData; -import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.DataSource; - -/** - * Utilities for getting information about a data source or all data sources - * from the case database. - */ -final class DataSourceInfoUtilities { - - private static final Logger logger = Logger.getLogger(DataSourceInfoUtilities.class.getName()); - - /** - * Get a map containing the TSK_DATA_SOURCE_USAGE description attributes - * associated with each data source in the current case. - * - * @return Collection which maps datasource id to a String which displays a - * comma seperated list of values of data source usage types - * expected to be in the datasource - */ - static Map getDataSourceTypes() { - try { - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - List listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE); - Map typeMap = new HashMap<>(); - for (BlackboardArtifact typeArtifact : listOfArtifacts) { - BlackboardAttribute descriptionAttr = typeArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)); - if (typeArtifact.getDataSource() != null && descriptionAttr != null) { - long dsId = typeArtifact.getDataSource().getId(); - String type = typeMap.get(typeArtifact.getDataSource().getId()); - if (type == null) { - type = descriptionAttr.getValueString(); - } else { - type = type + ", " + descriptionAttr.getValueString(); - } - typeMap.put(dsId, type); - } - } - return typeMap; - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the number of files in each data source in the - * current case. - * - * @return Collection which maps datasource id to a count for the number of - * files in the datasource, will only contain entries for - * datasources which have at least 1 file - */ - static Map getCountsOfFiles() { - try { - final String countFilesQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() - + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() - + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS - return getValuesMap(countFilesQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the number of artifacts in each data source in the - * current case. - * - * @return Collection which maps datasource id to a count for the number of - * artifacts in the datasource, will only contain entries for - * datasources which have at least 1 artifact - */ - static Map getCountsOfArtifacts() { - try { - final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID() - + " GROUP BY data_source_obj_id"; //NON-NLS - return getValuesMap(countArtifactsQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the number of tags which have been applied in each - * data source in the current case. Not necessarily the same as the number - * of items tagged, as an item can have any number of tags. - * - * @return Collection which maps datasource id to a count for the number of - * tags which have been applied in the datasource, will only contain - * entries for datasources which have at least 1 item tagged. - */ - static Map getCountsOfTags() { - try { - final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM content_tags as content_tags, tsk_files as tsk_files" - + " WHERE content_tags.obj_id = tsk_files.obj_id" - + " GROUP BY data_source_obj_id"; //NON-NLS - //new hashmap so it can be modifiable - Map tagCountMap = new HashMap<>(getValuesMap(countFileTagsQuery)); - final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts" - + " WHERE artifact_tags.artifact_id = arts.artifact_id" - + " GROUP BY data_source_obj_id"; //NON-NLS - //combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query - getValuesMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2)); - return tagCountMap; - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the names of operating systems joined in a comma - * seperated list to the Data Source they exist on in the current case. No - * item will exist in the map for data sources which do not contain - * TS_OS_INFO artifacts which have a program name. - * - * @return Collection which maps datasource id to a String which is a comma - * seperated list of Operating system names found on the data - * source. - */ - static Map getOperatingSystems() { - Map osDetailMap = new HashMap<>(); - try { - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - ArrayList osInfoArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO); - for (BlackboardArtifact osInfo : osInfoArtifacts) { - BlackboardAttribute programName = osInfo.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)); - if (programName != null) { - String currentOsString = osDetailMap.get(osInfo.getDataSource().getId()); - if (currentOsString == null || currentOsString.isEmpty()) { - currentOsString = programName.getValueString(); - } else { - currentOsString = currentOsString + ", " + programName.getValueString(); - } - osDetailMap.put(osInfo.getDataSource().getId(), currentOsString); - } - } - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to load OS info artifacts.", ex); - } - return osDetailMap; - } - - /** - * Get the number of files in the case database for the current data source - * which have the specified mimetypes. - * - * @param currentDataSource the data source which we are finding a file - * count - * - * @param setOfMimeTypes the set of mime types which we are finding the - * number of occurences of - * - * @return a Long value which represents the number of occurrences of the - * specified mime types in the current case for the specified data - * source, null if no count was retrieved - */ - static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set setOfMimeTypes) { - if (currentDataSource != null) { - try { - String inClause = String.join("', '", setOfMimeTypes); - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - return skCase.countFilesWhere("data_source_obj_id=" + currentDataSource.getId() - + " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() - + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() - + " AND mime_type IN ('" + inClause + "')" - + " AND name<>''"); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get count of files for specified mime types", ex); - //unable to get count of files for the specified mimetypes cell will be displayed as empty - } - } - return null; - } - - /** - * Get a map containing the number of unallocated files in each data source - * in the current case. - * - * @return Collection which maps datasource id to a count for the number of - * unallocated files in the datasource, will only contain entries - * for datasources which have at least 1 unallocated file - */ - static Map getCountsOfUnallocatedFiles() { - try { - final String countUnallocatedFilesQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() - + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() - + " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue() - + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS - return getValuesMap(countUnallocatedFilesQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of unallocated files for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the total size of unallocated files in each data - * source in the current case. - * - * @return Collection which maps datasource id to a total size in bytes of - * unallocated files in the datasource, will only contain entries - * for datasources which have at least 1 unallocated file - */ - static Map getSizeOfUnallocatedFiles() { - try { - final String countUnallocatedFilesQuery = "data_source_obj_id, sum(size) AS value" - + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() - + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() - + " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue() - + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS - return getValuesMap(countUnallocatedFilesQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get size of unallocated files for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the number of directories in each data source in the - * current case. - * - * @return Collection which maps datasource id to a count for the number of - * directories in the datasource, will only contain entries for - * datasources which have at least 1 directory - */ - static Map getCountsOfDirectories() { - try { - final String countDirectoriesQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() - + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() - + " AND meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue() - + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS - return getValuesMap(countDirectoriesQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of directories for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing the number of slack files in each data source in the - * current case. - * - * @return Collection which maps datasource id to a count for the number of - * slack files in the datasource, will only contain entries for - * datasources which have at least 1 slack file - */ - static Map getCountsOfSlackFiles() { - try { - final String countSlackFilesQuery = "data_source_obj_id, COUNT(*) AS value" - + " FROM tsk_files WHERE type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() - + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() - + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS - return getValuesMap(countSlackFilesQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of slack files for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Get a map containing maps which map artifact type to the number of times - * it exosts in each data source in the current case. - * - * @return Collection which maps datasource id to maps of artifact display - * name to number of occurences in the datasource, will only contain - * entries for artifacts which have at least one occurence in the - * data source. - */ - static Map> getCountsOfArtifactsByType() { - try { - final String countArtifactsQuery = "blackboard_artifacts.data_source_obj_id, blackboard_artifact_types.display_name AS label, COUNT(*) AS value" - + " FROM blackboard_artifacts, blackboard_artifact_types" - + " WHERE blackboard_artifacts.artifact_type_id = blackboard_artifact_types.artifact_type_id" - + " GROUP BY blackboard_artifacts.data_source_obj_id, blackboard_artifact_types.display_name"; - return getLabeledValuesMap(countArtifactsQuery); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "Unable to get counts of all artifact types for all datasources, providing empty results", ex); - return Collections.emptyMap(); - } - } - - /** - * Helper method to execute a select query with a - * DataSourceLabeledValueCallback. - * - * @param query the portion of the query which should follow the SELECT - * - * @return a map of datasource object IDs to maps of String labels to the - * values associated with them. - * - * @throws TskCoreException - * @throws NoCurrentCaseException - */ - private static Map> getLabeledValuesMap(String query) throws TskCoreException, NoCurrentCaseException { - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - DataSourceLabeledValueCallback callback = new DataSourceLabeledValueCallback(); - skCase.getCaseDbAccessManager().select(query, callback); - return callback.getMapOfLabeledValues(); - } - - /** - * Helper method to execute a select query with a - * DataSourceSingleValueCallback. - * - * @param query the portion of the query which should follow the SELECT - * - * @return a map of datasource object ID to a value of type Long - * - * @throws TskCoreException - * @throws NoCurrentCaseException - */ - private static Map getValuesMap(String query) throws TskCoreException, NoCurrentCaseException { - SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); - DataSourceSingleValueCallback callback = new DataSourceSingleValueCallback(); - skCase.getCaseDbAccessManager().select(query, callback); - return callback.getMapOfValues(); - } - - /** - * Empty private constructor - */ - private DataSourceInfoUtilities() { - } -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java deleted file mode 100644 index 1a44e2a76b..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.CaseDbAccessManager; - -/** - * Callback which gets a map of datasource object IDs to maps of String labels - * to the values associated with them, given a query which should select a - * 'data_source_obj_id', a 'label', and a 'value'. - */ -class DataSourceLabeledValueCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - - private static final Logger logger = Logger.getLogger(DataSourceSingleValueCallback.class.getName()); - private final Map> dataSourceObjIdLabeledValues = new HashMap<>(); - - @Override - public void process(ResultSet rs) { - try { - while (rs.next()) { - try { - Long dataSourceObjId = rs.getLong("data_source_obj_id"); - String labelForValue = rs.getString("label"); - Long value = rs.getLong("value"); - Map labelsMap = dataSourceObjIdLabeledValues.get(dataSourceObjId) == null ? new HashMap<>() : dataSourceObjIdLabeledValues.get(dataSourceObjId); - labelsMap.put(labelForValue, value); - dataSourceObjIdLabeledValues.put(dataSourceObjId, labelsMap); - } catch (SQLException ex) { - logger.log(Level.WARNING, "Unable to get data_source_obj_id or value from result set", ex); - } - } - } catch (SQLException ex) { - logger.log(Level.WARNING, "Failed to get next result for valuess by datasource", ex); - } - } - - /** - * Get the processed results - * - * @return Collection which maps datasource object IDs to maps of String - * labels to the values associated with them only contains entries - * for data sources with at least 1 item found for any label. - */ - Map> getMapOfLabeledValues() { - return Collections.unmodifiableMap(dataSourceObjIdLabeledValues); - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java deleted file mode 100644 index fc7eea15e5..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.CaseDbAccessManager; - -/** - * Get the map of Data Source ID to a value found related to that data source - * query which selects data_source_obj_id and value which is grouped by that - * data source object id. - */ -class DataSourceSingleValueCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - - private static final Logger logger = Logger.getLogger(DataSourceSingleValueCallback.class.getName()); - private final Map dataSourceObjIdValues = new HashMap<>(); - - @Override - public void process(ResultSet rs) { - try { - while (rs.next()) { - try { - dataSourceObjIdValues.put(rs.getLong("data_source_obj_id"), rs.getLong("value")); - } catch (SQLException ex) { - logger.log(Level.WARNING, "Unable to get data_source_obj_id or value from result set", ex); - } - } - } catch (SQLException ex) { - logger.log(Level.WARNING, "Failed to get next result for valuess by datasource", ex); - } - } - - /** - * Get the processed results - * - * @return Collection which maps datasource id to a value related to the - * datasource id, only contains entries for datasources with at - * least 1 item found. - */ - Map getMapOfValues() { - return Collections.unmodifiableMap(dataSourceObjIdValues); - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java deleted file mode 100644 index b50c3596bd..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.datamodel.CaseDbAccessManager; -import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.IngestJobInfo.IngestJobStatusType; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Wrapper object for a DataSource and the information associated with it. - * - */ -class DataSourceSummary { - - private static final Logger logger = Logger.getLogger(DataSourceSummary.class.getName()); - private static final String INGEST_JOB_STATUS_QUERY = "status_id FROM ingest_jobs WHERE obj_id="; - private final DataSource dataSource; - private IngestJobStatusType status = null; - private final String type; - private final long filesCount; - private final long resultsCount; - private final long tagsCount; - - /** - * Construct a new DataSourceSummary object - * - * @param dSource the DataSource being wrapped by this object - * @param typeValue the Type sting to be associated with this - * DataSource - * @param numberOfFiles the number of files found in this DataSource - * @param numberOfResults the number of artifacts found in this DataSource - * @param numberOfTags the number of tagged content objects in this - * DataSource - */ - DataSourceSummary(DataSource dSource, String typeValue, Long numberOfFiles, Long numberOfResults, Long numberOfTags) { - dataSource = dSource; - getStatusFromDatabase(); - type = typeValue == null ? "" : typeValue; - filesCount = numberOfFiles == null ? 0 : numberOfFiles; - resultsCount = numberOfResults == null ? 0 : numberOfResults; - tagsCount = numberOfTags == null ? 0 : numberOfTags; - } - - /** - * Get the status of the ingest job from the case database - */ - private void getStatusFromDatabase() { - try { - IngestJobQueryCallback callback = new IngestJobQueryCallback(); - Case.getCurrentCaseThrows().getSleuthkitCase().getCaseDbAccessManager().select(INGEST_JOB_STATUS_QUERY + dataSource.getId(), callback); - status = callback.getStatus(); - } catch (NoCurrentCaseException | TskCoreException ex) { - logger.log(Level.WARNING, "Error getting status for data source from case database", ex); - } - } - - /** - * Get the DataSource - * - * @return the dataSource - */ - DataSource getDataSource() { - return dataSource; - } - - /** - * Manually set the ingest job status - * - * @param ingestStatus the status which the ingest job should have - * currently, null to display empty string - */ - void setIngestStatus(IngestJobStatusType ingestStatus) { - status = ingestStatus; - } - - /** - * Get the type of this DataSource - * - * @return the type - */ - String getType() { - return type; - } - - /** - * Get the number of files in this DataSource - * - * @return the filesCount - */ - long getFilesCount() { - return filesCount; - } - - /** - * Get the number of artifacts in this DataSource - * - * @return the resultsCount - */ - long getResultsCount() { - return resultsCount; - } - - /** - * Get the IngestJobStatusType associated with this data source. - * - * @return the IngestJobStatusType associated with this data source. Can be - * null if the IngestJobStatusType is not STARTED or COMPLETED. - */ - IngestJobStatusType getIngestStatus() { - return status; - } - - /** - * Get the number of tagged content objects in this DataSource - * - * @return the tagsCount - */ - long getTagsCount() { - return tagsCount; - } - - /** - * Callback to parse result set, getting the status to be associated with - * this data source - */ - class IngestJobQueryCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { - - private IngestJobStatusType jobStatus = null; - - @Override - public void process(ResultSet rs) { - try { - while (rs.next()) { - IngestJobStatusType currentStatus = IngestJobStatusType.fromID(rs.getInt("status_id")); - if (currentStatus == IngestJobStatusType.COMPLETED) { - jobStatus = currentStatus; - } else if (currentStatus == IngestJobStatusType.STARTED) { - jobStatus = currentStatus; - return; - } - } - } catch (SQLException ex) { - logger.log(Level.WARNING, "Error getting status for ingest job", ex); - } - } - - /** - * Get the status which was determined for this callback - * - * @return the status of the data source which was queried for - */ - IngestJobStatusType getStatus() { - return jobStatus; - } - - } -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java deleted file mode 100644 index 7514d61599..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.awt.event.ActionEvent; -import java.beans.PropertyChangeEvent; -import java.util.EnumSet; -import javax.swing.Action; -import org.openide.awt.ActionID; -import org.openide.awt.ActionRegistration; -import org.openide.util.HelpCtx; -import org.openide.util.NbBundle.Messages; -import org.openide.util.actions.CallableSystemAction; -import org.sleuthkit.autopsy.casemodule.Case; - -@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction") -@ActionRegistration(displayName = "#CTL_DataSourceSummaryAction", lazy = false) -@Messages({"CTL_DataSourceSummaryAction=Data Source Summary"}) -/** - * DataSourceSummaryAction action for the Case menu to activate a - * ViewSummaryInformationAction selecting the first data source. - */ -public class DataSourceSummaryAction extends CallableSystemAction { - - private static final long serialVersionUID = 1L; - - /** - * Create a datasource summary action which will be disabled when no case is - * open. - */ - DataSourceSummaryAction() { - putValue(Action.NAME, Bundle.CTL_DataSourceSummaryAction()); - this.setEnabled(false); - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { - setEnabled(null != evt.getNewValue()); - }); - } - - @Override - public void performAction() { - //perform the action of a ViewSummaryInformationAction with a ActionEvent which will not be used - new ViewSummaryInformationAction(null).actionPerformed(new ActionEvent(Boolean.TRUE, 0, "")); - } - - @Override - public String getName() { - return Bundle.CTL_DataSourceSummaryAction(); - } - - @Override - public HelpCtx getHelpCtx() { - return HelpCtx.DEFAULT_HELP; - } - - @Override - public boolean asynchronous() { - return false; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form deleted file mode 100644 index d3a17e0205..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form +++ /dev/null @@ -1,139 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java deleted file mode 100644 index 1d99f1c445..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import org.sleuthkit.autopsy.coreutils.Logger; -import javax.swing.JLabel; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.DefaultTableModel; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.coreutils.FileTypeUtils; -import org.sleuthkit.datamodel.DataSource; - -/** - * Panel for displaying summary information on the known files present in the - * specified DataSource - */ -class DataSourceSummaryCountsPanel extends javax.swing.JPanel { - - private static final long serialVersionUID = 1L; - private FilesByMimeTypeTableModel filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(null); - private FilesByCategoryTableModel filesByCategoryTableModel = new FilesByCategoryTableModel(null); - private static final Logger logger = Logger.getLogger(DataSourceSummaryCountsPanel.class.getName()); - private final Map allFilesCountsMap; - private final Map slackFilesCountsMap; - private final Map directoriesCountsMap; - private final Map unallocatedFilesCountsMap; - private final Map> artifactsByTypeCountsMap; - private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer(); - - /** - * Creates new form DataSourceSummaryCountsPanel - */ - DataSourceSummaryCountsPanel(Map fileCountsMap) { - this.allFilesCountsMap = fileCountsMap; - this.slackFilesCountsMap = DataSourceInfoUtilities.getCountsOfSlackFiles(); - this.directoriesCountsMap = DataSourceInfoUtilities.getCountsOfDirectories(); - this.unallocatedFilesCountsMap = DataSourceInfoUtilities.getCountsOfUnallocatedFiles(); - this.artifactsByTypeCountsMap = DataSourceInfoUtilities.getCountsOfArtifactsByType(); - rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT); - initComponents(); - fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false); - fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false); - } - - /** - * Specify the DataSource to display file information for - * - * @param selectedDataSource the DataSource to display file information for - */ - void updateCountsTableData(DataSource selectedDataSource) { - filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(selectedDataSource); - fileCountsByMimeTypeTable.setModel(filesByMimeTypeTableModel); - fileCountsByMimeTypeTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); - fileCountsByMimeTypeTable.getColumnModel().getColumn(0).setPreferredWidth(130); - filesByCategoryTableModel = new FilesByCategoryTableModel(selectedDataSource); - fileCountsByCategoryTable.setModel(filesByCategoryTableModel); - fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); - fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130); - updateArtifactCounts(selectedDataSource); - this.repaint(); - } - - /** - * Helper method to update the artifact specific counts by clearing the - * table and adding counts for the artifacts which exist in the selected - * data source. - * - * @param selectedDataSource the data source to display artifact counts for - */ - private void updateArtifactCounts(DataSource selectedDataSource) { - ((DefaultTableModel) artifactCountsTable.getModel()).setRowCount(0); - if (selectedDataSource != null && artifactsByTypeCountsMap.get(selectedDataSource.getId()) != null) { - Map artifactCounts = artifactsByTypeCountsMap.get(selectedDataSource.getId()); - for (String key : artifactCounts.keySet()) { - ((DefaultTableModel) artifactCountsTable.getModel()).addRow(new Object[]{key, artifactCounts.get(key)}); - } - } - artifactCountsTable.getColumnModel().getColumn(0).setPreferredWidth(230); - artifactCountsTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); - } - - /** - * 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() { - - fileCountsByMimeTypeScrollPane = new javax.swing.JScrollPane(); - fileCountsByMimeTypeTable = new javax.swing.JTable(); - byMimeTypeLabel = new javax.swing.JLabel(); - fileCountsByCategoryScrollPane = new javax.swing.JScrollPane(); - fileCountsByCategoryTable = new javax.swing.JTable(); - byCategoryLabel = new javax.swing.JLabel(); - jLabel1 = new javax.swing.JLabel(); - artifactCountsScrollPane = new javax.swing.JScrollPane(); - artifactCountsTable = new javax.swing.JTable(); - - fileCountsByMimeTypeTable.setModel(filesByMimeTypeTableModel); - fileCountsByMimeTypeScrollPane.setViewportView(fileCountsByMimeTypeTable); - - org.openide.awt.Mnemonics.setLocalizedText(byMimeTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byMimeTypeLabel.text")); // NOI18N - - fileCountsByCategoryTable.setModel(filesByCategoryTableModel); - fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable); - - org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byCategoryLabel.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.jLabel1.text")); // NOI18N - - artifactCountsTable.setAutoCreateRowSorter(true); - artifactCountsTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - - }, - new String [] { - "Result Type", "Count" - } - ) { - boolean[] canEdit = new boolean [] { - false, false - }; - - public boolean isCellEditable(int rowIndex, int columnIndex) { - return canEdit [columnIndex]; - } - }); - artifactCountsScrollPane.setViewportView(artifactCountsTable); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE) - .addComponent(byMimeTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(byCategoryLabel) - .addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane}); - - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(byMimeTypeLabel) - .addComponent(byCategoryLabel) - .addComponent(jLabel1)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) - ); - - layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane}); - - }// //GEN-END:initComponents - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JScrollPane artifactCountsScrollPane; - private javax.swing.JTable artifactCountsTable; - private javax.swing.JLabel byCategoryLabel; - private javax.swing.JLabel byMimeTypeLabel; - private javax.swing.JScrollPane fileCountsByCategoryScrollPane; - private javax.swing.JTable fileCountsByCategoryTable; - private javax.swing.JScrollPane fileCountsByMimeTypeScrollPane; - private javax.swing.JTable fileCountsByMimeTypeTable; - private javax.swing.JLabel jLabel1; - // End of variables declaration//GEN-END:variables - - /** - * Table model for the files table model to display counts of specific file - * types by mime type found in the currently selected data source. - */ - @Messages({"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type", - "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=Count"}) - private class FilesByMimeTypeTableModel extends AbstractTableModel { - - private static final long serialVersionUID = 1L; - private final DataSource currentDataSource; - private final List columnHeaders = new ArrayList<>(); - private static final int IMAGES_ROW_INDEX = 0; - private static final int VIDEOS_ROW_INDEX = 1; - private static final int AUDIO_ROW_INDEX = 2; - private static final int DOCUMENTS_ROW_INDEX = 3; - private static final int EXECUTABLES_ROW_INDEX = 4; - - /** - * Create a FilesByMimeTypeTableModel for the speicified datasource. - * - * @param selectedDataSource the datasource which this - * FilesByMimeTypeTablemodel will represent - */ - FilesByMimeTypeTableModel(DataSource selectedDataSource) { - columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_type_header()); - columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_count_header()); - currentDataSource = selectedDataSource; - } - - @Override - public int getRowCount() { - //should be kept equal to the number of types we are displaying in the tables - return 5; - } - - @Override - public int getColumnCount() { - return columnHeaders.size(); - } - - @Messages({ - "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images", - "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos", - "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio", - "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents", - "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables" - }) - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - if (columnIndex == 0) { - switch (rowIndex) { - case IMAGES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_images_row(); - case VIDEOS_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_videos_row(); - case AUDIO_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_audio_row(); - case DOCUMENTS_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_documents_row(); - case EXECUTABLES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_executables_row(); - default: - break; - } - } else if (columnIndex == 1) { - switch (rowIndex) { - case 0: - return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes()); - case 1: - return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes()); - case 2: - return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes()); - case 3: - return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes()); - case 4: - return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes()); - default: - break; - } - } - return null; - } - - @Override - public String getColumnName(int column) { - return columnHeaders.get(column); - } - } - - /** - * Table model for the files table model to display counts of specific file - * types by category found in the currently selected data source. - */ - @Messages({"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count"}) - private class FilesByCategoryTableModel extends AbstractTableModel { - - private static final long serialVersionUID = 1L; - private final DataSource currentDataSource; - private final List columnHeaders = new ArrayList<>(); - private static final int ALL_FILES_ROW_INDEX = 0; - private static final int ALLOCATED_FILES_ROW_INDEX = 1; - private static final int UNALLOCATED_FILES_ROW_INDEX = 2; - private static final int SLACK_FILES_ROW_INDEX = 3; - private static final int DIRECTORIES_ROW_INDEX = 4; - /** - * Create a FilesByCategoryTableModel for the speicified datasource. - * - * @param selectedDataSource the datasource which this - * FilesByCategoryTablemodel will represent - */ - FilesByCategoryTableModel(DataSource selectedDataSource) { - columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_type_header()); - columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_count_header()); - currentDataSource = selectedDataSource; - } - - @Override - public int getRowCount() { - //should be kept equal to the number of types we are displaying in the tables - return 5; - } - - @Override - public int getColumnCount() { - return columnHeaders.size(); - } - - @Messages({ - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack", - "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory" - }) - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - if (columnIndex == 0) { - switch (rowIndex) { - case ALL_FILES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(); - case ALLOCATED_FILES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row(); - case UNALLOCATED_FILES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row(); - case SLACK_FILES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row(); - case DIRECTORIES_ROW_INDEX: - return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row(); - default: - break; - } - } else if (columnIndex == 1 && currentDataSource != null) { - switch (rowIndex) { - case 0: - return allFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : allFilesCountsMap.get(currentDataSource.getId()); - case 1: - //All files should be either allocated or unallocated as dir_flags only has two values so any file that isn't unallocated is allocated - Long unallocatedFilesCount = unallocatedFilesCountsMap.get(currentDataSource.getId()); - Long allFilesCount = allFilesCountsMap.get(currentDataSource.getId()); - if (allFilesCount == null) { - return 0; - } else if (unallocatedFilesCount == null) { - return allFilesCount; - } else { - return allFilesCount - unallocatedFilesCount; - } - case 2: - return unallocatedFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : unallocatedFilesCountsMap.get(currentDataSource.getId()); - case 3: - return slackFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : slackFilesCountsMap.get(currentDataSource.getId()); - case 4: - return directoriesCountsMap.get(currentDataSource.getId()) == null ? 0 : directoriesCountsMap.get(currentDataSource.getId()); - default: - break; - } - } - return null; - } - - @Override - public String getColumnName(int column) { - return columnHeaders.get(column); - } - } -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form deleted file mode 100644 index 9efc00faa0..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form +++ /dev/null @@ -1,495 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - <ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - - - - - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java deleted file mode 100644 index 1b898f4995..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.text.DecimalFormat; -import java.util.Map; -import java.util.HashMap; -import java.util.logging.Level; -import org.sleuthkit.autopsy.coreutils.Logger; -import javax.swing.table.DefaultTableModel; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.Image; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Panel to display additional details associated with a specific DataSource - */ -class DataSourceSummaryDetailsPanel extends javax.swing.JPanel { - - //Because this panel was made using the gridbaglayout and netbean's Customize Layout tool it will be best to continue to modify it through that - private static final long serialVersionUID = 1L; - private Map osDetailMap = new HashMap<>(); - private static final Integer SIZE_COVERSION_CONSTANT = 1000; - private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##"); - private final Map unallocatedFilesSizeMap; - private final Map usageMap; - private static final Logger logger = Logger.getLogger(DataSourceSummaryDetailsPanel.class.getName()); - - /** - * Creates new form DataSourceSummaryDetailsPanel - */ - @Messages({"DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.", - "DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure"}) - DataSourceSummaryDetailsPanel(Map usageMap) { - initComponents(); - this.usageMap = usageMap; - this.unallocatedFilesSizeMap = DataSourceInfoUtilities.getSizeOfUnallocatedFiles(); - osDetailMap = DataSourceInfoUtilities.getOperatingSystems(); - } - - /** - * Update which DataSource this panel should display details about - * - * @param selectedDataSource the DataSource to display details about. - */ - void updateDetailsPanelData(DataSource selectedDataSource) { - clearTableValues(); - if (selectedDataSource != null) { - String sizeString = ""; - String sectorSizeString = ""; - String md5String = ""; - String sha1String = ""; - String sha256String = ""; - String acquisitionDetailsString = ""; - String imageTypeString = ""; - String[] filePaths = new String[0]; - String osDetailString = osDetailMap.get(selectedDataSource.getId()) == null ? "" : osDetailMap.get(selectedDataSource.getId()); - String dataSourceTypeString = usageMap.get(selectedDataSource.getId()) == null ? "" : usageMap.get(selectedDataSource.getId()); - try { - acquisitionDetailsString = selectedDataSource.getAcquisitionDetails(); - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Unable to get aquisition details for selected data source", ex); - } - if (selectedDataSource instanceof Image) { - imageTypeString = ((Image) selectedDataSource).getType().getName(); - filePaths = ((Image) selectedDataSource).getPaths(); - sizeString = getSizeString(selectedDataSource.getSize()); - sectorSizeString = getSizeString(((Image) selectedDataSource).getSsize()); - try { - //older databases may have null as the hash values - md5String = ((Image) selectedDataSource).getMd5(); - if (md5String == null) { - md5String = ""; - } - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex); - } - try { - sha1String = ((Image) selectedDataSource).getSha1(); - if (sha1String == null) { - sha1String = ""; - } - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex); - } - try { - sha256String = ((Image) selectedDataSource).getSha256(); - if (sha256String == null) { - sha256String = ""; - } - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex); - } - } - displayNameValue.setText(selectedDataSource.getName()); - originalNameValue.setText(selectedDataSource.getName()); - deviceIdValue.setText(selectedDataSource.getDeviceId()); - dataSourceUsageValue.setText(dataSourceTypeString); - operatingSystemValue.setText(osDetailString); - timeZoneValue.setText(selectedDataSource.getTimeZone()); - acquisitionDetailsTextArea.setText(acquisitionDetailsString); - imageTypeValue.setText(imageTypeString); - sizeValue.setText(sizeString); - unallocatedSizeValue.setText(getSizeString(unallocatedFilesSizeMap.get(selectedDataSource.getId()))); - sectorSizeValue.setText(sectorSizeString); - md5HashValue.setText(md5String); - sha1HashValue.setText(sha1String); - sha256HashValue.setText(sha256String); - for (String path : filePaths) { - ((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path}); - } - } - updateFieldVisibility(); - this.repaint(); - } - - /** - * Get a long size in bytes as a string formated to be read by users. - * - * @param size Long value representing a size in bytes - * - * @return return a string formated with a user friendly version of the size - * as a string, returns empty String when provided empty size - */ - @Messages({ - "DataSourceSummaryDetailsPanel.units.bytes= bytes", - "DataSourceSummaryDetailsPanel.units.kilobytes= kB", - "DataSourceSummaryDetailsPanel.units.megabytes= MB", - "DataSourceSummaryDetailsPanel.units.gigabytes= GB", - "DataSourceSummaryDetailsPanel.units.terabytes= TB", - "DataSourceSummaryDetailsPanel.units.petabytes= PB" - }) - private String getSizeString(Long size) { - if (size == null) { - return ""; - } - double approximateSize = size; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes(); - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_kilobytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_megabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_gigabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - if (approximateSize < SIZE_COVERSION_CONSTANT) { - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_terabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - approximateSize /= SIZE_COVERSION_CONSTANT; - return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_petabytes() - + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; - } - - /** - * Update the visibility of all fields and their labels based on whether - * they have contents. Empty fields have them and their contents hidden. - */ - private void updateFieldVisibility() { - displayNameValue.setVisible(!displayNameValue.getText().isEmpty()); - displayNameLabel.setVisible(!displayNameValue.getText().isEmpty()); - originalNameValue.setVisible(!originalNameValue.getText().isEmpty()); - originalNameLabel.setVisible(!originalNameValue.getText().isEmpty()); - deviceIdValue.setVisible(!deviceIdValue.getText().isEmpty()); - deviceIdLabel.setVisible(!deviceIdValue.getText().isEmpty()); - dataSourceUsageValue.setVisible(!dataSourceUsageValue.getText().isEmpty()); - dataSourceUsageLabel.setVisible(!dataSourceUsageValue.getText().isEmpty()); - operatingSystemValue.setVisible(!operatingSystemValue.getText().isEmpty()); - operatingSystemLabel.setVisible(!operatingSystemValue.getText().isEmpty()); - timeZoneValue.setVisible(!timeZoneValue.getText().isEmpty()); - timeZoneLabel.setVisible(!timeZoneValue.getText().isEmpty()); - acquisitionDetailsTextArea.setVisible(!acquisitionDetailsTextArea.getText().isEmpty()); - acquisitionDetailsLabel.setVisible(!acquisitionDetailsTextArea.getText().isEmpty()); - acquisitionDetailsScrollPane.setVisible(!acquisitionDetailsTextArea.getText().isEmpty()); - imageTypeValue.setVisible(!imageTypeValue.getText().isEmpty()); - imageTypeLabel.setVisible(!imageTypeValue.getText().isEmpty()); - sizeValue.setVisible(!sizeValue.getText().isEmpty()); - sizeLabel.setVisible(!sizeValue.getText().isEmpty()); - sectorSizeValue.setVisible(!sectorSizeValue.getText().isEmpty()); - sectorSizeLabel.setVisible(!sectorSizeValue.getText().isEmpty()); - md5HashValue.setVisible(!md5HashValue.getText().isEmpty()); - md5HashLabel.setVisible(!md5HashValue.getText().isEmpty()); - sha1HashValue.setVisible(!sha1HashValue.getText().isEmpty()); - sha1HashLabel.setVisible(!sha1HashValue.getText().isEmpty()); - sha256HashValue.setVisible(!sha256HashValue.getText().isEmpty()); - sha256HashLabel.setVisible(!sha256HashValue.getText().isEmpty()); - unallocatedSizeValue.setVisible(!unallocatedSizeValue.getText().isEmpty()); - unallocatedSizeLabel.setVisible(!unallocatedSizeValue.getText().isEmpty()); - filePathsTable.setVisible(filePathsTable.getRowCount() > 0); - filePathsLabel.setVisible(filePathsTable.getRowCount() > 0); - filePathsScrollPane.setVisible(filePathsTable.getRowCount() > 0); - } - - /** - * Set the contents of all fields to be empty. - */ - private void clearTableValues() { - displayNameValue.setText(""); - originalNameValue.setText(""); - deviceIdValue.setText(""); - dataSourceUsageValue.setText(""); - operatingSystemValue.setText(""); - timeZoneValue.setText(""); - acquisitionDetailsTextArea.setText(""); - imageTypeValue.setText(""); - sizeValue.setText(""); - sectorSizeValue.setText(""); - md5HashValue.setText(""); - sha1HashValue.setText(""); - sha256HashValue.setText(""); - unallocatedSizeValue.setText(""); - ((DefaultTableModel) filePathsTable.getModel()).setRowCount(0); - } - - /** - * 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() { - java.awt.GridBagConstraints gridBagConstraints; - - jScrollPane1 = new javax.swing.JScrollPane(); - jPanel1 = new javax.swing.JPanel(); - operatingSystemLabel = new javax.swing.JLabel(); - displayNameLabel = new javax.swing.JLabel(); - originalNameLabel = new javax.swing.JLabel(); - sha1HashValue = new javax.swing.JLabel(); - operatingSystemValue = new javax.swing.JLabel(); - displayNameValue = new javax.swing.JLabel(); - sha256HashValue = new javax.swing.JLabel(); - originalNameValue = new javax.swing.JLabel(); - deviceIdValue = new javax.swing.JLabel(); - filePathsScrollPane = new javax.swing.JScrollPane(); - filePathsTable = new javax.swing.JTable(); - dataSourceUsageValue = new javax.swing.JLabel(); - timeZoneValue = new javax.swing.JLabel(); - imageTypeValue = new javax.swing.JLabel(); - md5HashValue = new javax.swing.JLabel(); - sectorSizeValue = new javax.swing.JLabel(); - sizeValue = new javax.swing.JLabel(); - filePathsLabel = new javax.swing.JLabel(); - sha256HashLabel = new javax.swing.JLabel(); - sha1HashLabel = new javax.swing.JLabel(); - md5HashLabel = new javax.swing.JLabel(); - sectorSizeLabel = new javax.swing.JLabel(); - sizeLabel = new javax.swing.JLabel(); - imageTypeLabel = new javax.swing.JLabel(); - acquisitionDetailsLabel = new javax.swing.JLabel(); - timeZoneLabel = new javax.swing.JLabel(); - dataSourceUsageLabel = new javax.swing.JLabel(); - deviceIdLabel = new javax.swing.JLabel(); - acquisitionDetailsScrollPane = new javax.swing.JScrollPane(); - acquisitionDetailsTextArea = new javax.swing.JTextArea(); - filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); - filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); - unallocatedSizeLabel = new javax.swing.JLabel(); - unallocatedSizeValue = new javax.swing.JLabel(); - - jPanel1.setLayout(new java.awt.GridBagLayout()); - - org.openide.awt.Mnemonics.setLocalizedText(operatingSystemLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.operatingSystemLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(operatingSystemLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(displayNameLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.displayNameLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 4); - jPanel1.add(displayNameLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(originalNameLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.originalNameLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 1; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(originalNameLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sha1HashValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha1HashValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 12; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(sha1HashValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(operatingSystemValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.operatingSystemValue.text")); // NOI18N - operatingSystemValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 4; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(operatingSystemValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(displayNameValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.displayNameValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 10); - jPanel1.add(displayNameValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sha256HashValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha256HashValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 13; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 10); - jPanel1.add(sha256HashValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(originalNameValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.originalNameValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 1; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(originalNameValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(deviceIdValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.deviceIdValue.text")); // NOI18N - deviceIdValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 2; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 10); - jPanel1.add(deviceIdValue, gridBagConstraints); - - filePathsScrollPane.setPreferredSize(new java.awt.Dimension(80, 50)); - - filePathsTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - - }, - new String [] { - "" - } - ) { - boolean[] canEdit = new boolean [] { - false - }; - - public boolean isCellEditable(int rowIndex, int columnIndex) { - return canEdit [columnIndex]; - } - }); - filePathsTable.setTableHeader(null); - filePathsScrollPane.setViewportView(filePathsTable); - if (filePathsTable.getColumnModel().getColumnCount() > 0) { - filePathsTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0")); // NOI18N - } - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 14; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.weighty = 1.2; - gridBagConstraints.insets = new java.awt.Insets(6, 0, 10, 10); - jPanel1.add(filePathsScrollPane, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(dataSourceUsageValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.dataSourceUsageValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 3; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 10); - jPanel1.add(dataSourceUsageValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(timeZoneValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.timeZoneValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 5; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 10); - jPanel1.add(timeZoneValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(imageTypeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.imageTypeValue.text")); // NOI18N - imageTypeValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 7; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 10); - jPanel1.add(imageTypeValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(md5HashValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.md5HashValue.text")); // NOI18N - md5HashValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.md5HashValue.toolTipText")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 11; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(md5HashValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sectorSizeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sectorSizeValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 10; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(sectorSizeValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sizeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sizeValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 8; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(sizeValue, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(filePathsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.filePathsLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 14; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weighty = 1.2; - gridBagConstraints.insets = new java.awt.Insets(6, 10, 10, 4); - jPanel1.add(filePathsLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sha256HashLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha256HashLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 13; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 6, 4); - jPanel1.add(sha256HashLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sha1HashLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha1HashLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 12; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(sha1HashLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(md5HashLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.md5HashLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 11; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(md5HashLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sectorSizeLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 10; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(sectorSizeLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(sizeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sizeLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 8; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(sizeLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(imageTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.imageTypeLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 7; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(6, 10, 0, 4); - jPanel1.add(imageTypeLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(acquisitionDetailsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 6; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weighty = 0.6; - gridBagConstraints.insets = new java.awt.Insets(6, 10, 6, 4); - jPanel1.add(acquisitionDetailsLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.timeZoneLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 5; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 6, 4); - jPanel1.add(timeZoneLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(dataSourceUsageLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 3; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(6, 10, 0, 4); - jPanel1.add(dataSourceUsageLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(deviceIdLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.deviceIdLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 2; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 6, 4); - jPanel1.add(deviceIdLabel, gridBagConstraints); - - acquisitionDetailsTextArea.setEditable(false); - acquisitionDetailsTextArea.setBackground(javax.swing.UIManager.getDefaults().getColor("TextArea.disabledBackground")); - acquisitionDetailsTextArea.setColumns(20); - acquisitionDetailsTextArea.setRows(4); - acquisitionDetailsTextArea.setText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text")); // NOI18N - acquisitionDetailsTextArea.setBorder(null); - acquisitionDetailsScrollPane.setViewportView(acquisitionDetailsTextArea); - - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 6; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.weighty = 0.6; - gridBagConstraints.insets = new java.awt.Insets(6, 0, 6, 10); - jPanel1.add(acquisitionDetailsScrollPane, gridBagConstraints); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 15; - gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; - gridBagConstraints.weighty = 0.1; - jPanel1.add(filler1, gridBagConstraints); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 15; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; - gridBagConstraints.weighty = 0.1; - jPanel1.add(filler2, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(unallocatedSizeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 9; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); - jPanel1.add(unallocatedSizeLabel, gridBagConstraints); - - org.openide.awt.Mnemonics.setLocalizedText(unallocatedSizeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.unallocatedSizeValue.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 9; - gridBagConstraints.gridwidth = 4; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; - gridBagConstraints.weightx = 0.5; - gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); - jPanel1.add(unallocatedSizeValue, gridBagConstraints); - - jScrollPane1.setViewportView(jPanel1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) - .addGap(0, 0, 0)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE) - ); - }// //GEN-END:initComponents - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel acquisitionDetailsLabel; - private javax.swing.JScrollPane acquisitionDetailsScrollPane; - private javax.swing.JTextArea acquisitionDetailsTextArea; - private javax.swing.JLabel dataSourceUsageLabel; - private javax.swing.JLabel dataSourceUsageValue; - private javax.swing.JLabel deviceIdLabel; - private javax.swing.JLabel deviceIdValue; - private javax.swing.JLabel displayNameLabel; - private javax.swing.JLabel displayNameValue; - private javax.swing.JLabel filePathsLabel; - private javax.swing.JScrollPane filePathsScrollPane; - private javax.swing.JTable filePathsTable; - private javax.swing.Box.Filler filler1; - private javax.swing.Box.Filler filler2; - private javax.swing.JLabel imageTypeLabel; - private javax.swing.JLabel imageTypeValue; - private javax.swing.JPanel jPanel1; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JLabel md5HashLabel; - private javax.swing.JLabel md5HashValue; - private javax.swing.JLabel operatingSystemLabel; - private javax.swing.JLabel operatingSystemValue; - private javax.swing.JLabel originalNameLabel; - private javax.swing.JLabel originalNameValue; - private javax.swing.JLabel sectorSizeLabel; - private javax.swing.JLabel sectorSizeValue; - private javax.swing.JLabel sha1HashLabel; - private javax.swing.JLabel sha1HashValue; - private javax.swing.JLabel sha256HashLabel; - private javax.swing.JLabel sha256HashValue; - private javax.swing.JLabel sizeLabel; - private javax.swing.JLabel sizeValue; - private javax.swing.JLabel timeZoneLabel; - private javax.swing.JLabel timeZoneValue; - private javax.swing.JLabel unallocatedSizeLabel; - private javax.swing.JLabel unallocatedSizeValue; - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form deleted file mode 100644 index 72c45cb5a7..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form +++ /dev/null @@ -1,82 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java deleted file mode 100644 index 3c68b7b3ed..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.awt.Frame; -import java.beans.PropertyChangeEvent; -import java.util.EnumSet; -import java.util.Map; -import java.util.Observable; -import java.util.Observer; -import java.util.Set; -import javax.swing.event.ListSelectionEvent; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel; -import org.sleuthkit.autopsy.ingest.IngestManager; -import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent; -import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason; -import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.IngestJobInfo; - -/** - * Dialog for displaying the Data Sources Summary information - */ -final class DataSourceSummaryDialog extends javax.swing.JDialog implements Observer { - - private static final long serialVersionUID = 1L; - private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED); - private final DataSourceSummaryCountsPanel countsPanel; - private final DataSourceSummaryDetailsPanel detailsPanel; - private final DataSourceBrowser dataSourcesPanel; - private final IngestJobInfoPanel ingestHistoryPanel; - - /** - * Creates new form DataSourceSummaryDialog for displaying a summary of the - * data sources for the fcurrent case and the contents found for each - * datasource. - */ - @Messages({ - "DataSourceSummaryDialog.window.title=Data Sources Summary", - "DataSourceSummaryDialog.countsTab.title=Counts", - "DataSourceSummaryDialog.detailsTab.title=Details", - "DataSourceSummaryDialog.ingestHistoryTab.title=Ingest History" - }) - DataSourceSummaryDialog(Frame owner) { - super(owner, Bundle.DataSourceSummaryDialog_window_title(), true); - Map usageMap = DataSourceInfoUtilities.getDataSourceTypes(); - Map fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles(); - countsPanel = new DataSourceSummaryCountsPanel(fileCountsMap); - detailsPanel = new DataSourceSummaryDetailsPanel(usageMap); - dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap); - ingestHistoryPanel = new IngestJobInfoPanel(); - initComponents(); - dataSourceSummarySplitPane.setLeftComponent(dataSourcesPanel); - dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_detailsTab_title(), detailsPanel); - dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_countsTab_title(), countsPanel); - dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_ingestHistoryTab_title(), ingestHistoryPanel); - dataSourcesPanel.addListSelectionListener((ListSelectionEvent e) -> { - if (!e.getValueIsAdjusting()) { - DataSource selectedDataSource = dataSourcesPanel.getSelectedDataSource(); - countsPanel.updateCountsTableData(selectedDataSource); - detailsPanel.updateDetailsPanelData(selectedDataSource); - ingestHistoryPanel.setDataSource(selectedDataSource); - this.repaint(); - } - }); - //add listener to refresh jobs with Started status when they complete - IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> { - if (evt instanceof DataSourceAnalysisCompletedEvent) { - DataSourceAnalysisCompletedEvent dsEvent = (DataSourceAnalysisCompletedEvent) evt; - if (dsEvent.getResult() == Reason.ANALYSIS_COMPLETED) { - dataSourcesPanel.refresh(dsEvent.getDataSource().getId(), IngestJobInfo.IngestJobStatusType.COMPLETED); - } else if (dsEvent.getResult() == Reason.ANALYSIS_CANCELLED) { - dataSourcesPanel.refresh(dsEvent.getDataSource().getId(), null); - } - } - }); - this.pack(); - } - - /** - * Make this dialog an observer of the DataSourcesPanel. - */ - void enableObserver() { - dataSourcesPanel.addObserver(this); - } - - @Override - public void update(Observable o, Object arg) { - this.dispose(); - } - - /** - * 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() { - - closeButton = new javax.swing.JButton(); - dataSourceSummarySplitPane = new javax.swing.JSplitPane(); - dataSourceTabbedPane = new javax.swing.JTabbedPane(); - - org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(DataSourceSummaryDialog.class, "DataSourceSummaryDialog.closeButton.text")); // NOI18N - closeButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - closeButtonActionPerformed(evt); - } - }); - - dataSourceSummarySplitPane.setDividerLocation(130); - dataSourceSummarySplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - dataSourceSummarySplitPane.setRightComponent(dataSourceTabbedPane); - - dataSourceSummarySplitPane.setLeftComponent(dataSourcesPanel); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 668, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(closeButton))) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(closeButton) - .addContainerGap()) - ); - }// //GEN-END:initComponents - - private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed - this.dispose(); - }//GEN-LAST:event_closeButtonActionPerformed - - /** - * Select the data source with the specicied data source id. If no data - * source matches the dataSourceID it will select the first datasource. - * - * @param dataSourceID the ID of the datasource to select, null will cause - * the first datasource to be selected - */ - void selectDataSource(Long dataSourceId) { - dataSourcesPanel.selectDataSource(dataSourceId); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton closeButton; - private javax.swing.JSplitPane dataSourceSummarySplitPane; - private javax.swing.JTabbedPane dataSourceTabbedPane; - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java deleted file mode 100644 index 0411d94bb2..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.awt.event.ActionEvent; -import java.util.ArrayList; -import java.util.List; -import java.util.Observable; -import java.util.Observer; -import javax.swing.Action; -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.datamodel.NodeProperty; -import org.sleuthkit.autopsy.directorytree.ViewContextAction; -import org.sleuthkit.datamodel.DataSource; - -/** - * Root node for displaying DataSourceSummary information in the - * DataSourceBrowser - * - */ -final class DataSourceSummaryNode extends AbstractNode { - - private final static Observable closeDialogObservable = new Observable() { - @Override - public void notifyObservers() { - //set changed before notify observers - //we want this observerable to always cause the observer to update when notified - this.setChanged(); - super.notifyObservers(); - } - }; - - /** - * Construct a new DataSourceSummaryNode - * - * @param dataSourceList the list of DataSourceSummary objects representing - * DataSources which are this nodes children - */ - DataSourceSummaryNode(List dataSourceList) { - super(Children.create(new DataSourceSummaryChildren(dataSourceList), false)); - } - - /** - * Add an observer to the closeDialogObservable - * - * @param observer the observer to add - */ - void addObserver(Observer observer) { - closeDialogObservable.addObserver(observer); - } - - /** - * ChildFactory to create children of the DataSourceSummaryNode for each - * DataSourceSummary - */ - static final class DataSourceSummaryChildren extends ChildFactory { - - private final List dataSourceList; - - /** - * Construct a new DataSourceSummaryChildren object to create children - * for each DataSourceSummary object in the list - * - * @param dataSourceList the DataSourceSummary objects to create - * children for - */ - DataSourceSummaryChildren(List dataSourceList) { - this.dataSourceList = dataSourceList; - } - - @Override - protected boolean createKeys(List list) { - if (dataSourceList != null && !dataSourceList.isEmpty()) { - list.addAll(dataSourceList); - } - return true; - } - - @Override - protected Node createNodeForKey(DataSourceSummary key) { - return new DataSourceSummaryEntryNode(key); - } - } - - /** - * A node which represents a single DataSource. - */ - static final class DataSourceSummaryEntryNode extends AbstractNode { - - private final DataSource dataSource; - private final String status; - private final String type; - private final long filesCount; - private final long resultsCount; - private final long tagsCount; - - /** - * Constrcut a new DataSourceSummaryEntryNode - * - * @param dataSourceSummary the DataSourceSummary which is wrapping the - * DataSource which will be represented by this - * node. - */ - DataSourceSummaryEntryNode(DataSourceSummary dataSourceSummary) { - super(Children.LEAF); - dataSource = dataSourceSummary.getDataSource(); - status = dataSourceSummary.getIngestStatus() == null ? "" : dataSourceSummary.getIngestStatus().getDisplayName(); - type = dataSourceSummary.getType(); - filesCount = dataSourceSummary.getFilesCount(); - resultsCount = dataSourceSummary.getResultsCount(); - tagsCount = dataSourceSummary.getTagsCount(); - super.setName(dataSource.getName()); - setName(dataSource.getName()); - setDisplayName(dataSource.getName()); - } - - /** - * Get the DataSource being represented by this node. - * - * @return the DataSource which is represented by this node. - */ - DataSource getDataSource() { - return dataSource; - } - - @Messages({"DataSourceSummaryNode.column.dataSourceName.header=Data Source Name", - "DataSourceSummaryNode.column.status.header=Ingest Status", - "DataSourceSummaryNode.column.type.header=Type", - "DataSourceSummaryNode.column.files.header=Files", - "DataSourceSummaryNode.column.results.header=Results", - "DataSourceSummaryNode.column.tags.header=Tags"}) - @Override - protected Sheet createSheet() { - Sheet sheet = super.createSheet(); - Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); - if (sheetSet == null) { - sheetSet = Sheet.createPropertiesSet(); - sheet.put(sheetSet); - } - sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(), - dataSource)); - sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), status)); - sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), - type)); - sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), - filesCount)); - sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(), - resultsCount)); - sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header(), - tagsCount)); - return sheet; - } - - /** - * 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 ViewDataSourceInContextAction(); - } - - @Override - public Action[] getActions(boolean context) { - List actions = new ArrayList<>(); - actions.add(new ViewDataSourceInContextAction()); - return actions.toArray(new Action[actions.size()]); - } - - /** - * Action to navigate to this node's Data Source in the Results Viewer - * and close the DataSourceSummaryDialog. - */ - private class ViewDataSourceInContextAction extends ViewContextAction { - - private static final long serialVersionUID = 1L; - - /** - * Construct a new ViewDataSourceInCOntextAction - */ - @Messages({"DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source"}) - ViewDataSourceInContextAction() { - super(Bundle.DataSourceSummaryNode_viewDataSourceAction_text(), dataSource); - } - - @Override - public void actionPerformed(ActionEvent e) { - closeDialogObservable.notifyObservers(); - super.actionPerformed(e); - } - } - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java deleted file mode 100644 index 12f111bba2..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.awt.Component; -import java.lang.reflect.InvocationTargetException; -import javax.swing.JTable; -import org.openide.nodes.Node; -import org.sleuthkit.autopsy.datamodel.NodeProperty; -import org.sleuthkit.autopsy.guiutils.GrayableCellRenderer; - -/** - * Cell Renderer which extends grayable cell renderer to inherit highlighting - * but right aligns the contents will display the value of the cell or if the - * cell contains a NodeProperty the value of that NodeProperty sets text to - * empty string if null. - */ -final class RightAlignedTableCellRenderer extends GrayableCellRenderer { - - private static final long serialVersionUID = 1L; - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - setHorizontalAlignment(RIGHT); - Object cellContents = null; - if ((value instanceof NodeProperty)) { - //The Outline view has properties in the cell, the value contained in the property is what we want - try { - cellContents = ((Node.Property) value).getValue(); - } catch (IllegalAccessException | InvocationTargetException ex) { - //Unable to get the value from the NodeProperty cell will appear empty - } - } else { - //JTables contain the value we want directly in the cell - cellContents = value; - } - if (null != cellContents) { - setText(cellContents.toString()); - } else { - setText(""); - } - grayCellIfTableNotEnabled(table, isSelected); - return this; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java deleted file mode 100644 index babe2197a1..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 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.datasourcesummary; - -import java.awt.Frame; -import java.awt.event.ActionEvent; -import javax.swing.AbstractAction; -import javax.swing.SwingUtilities; -import org.openide.util.NbBundle.Messages; -import org.openide.windows.WindowManager; - -/** - * ViewSummaryInformationAction action for opening a Data Sources Summary Dialog - * with the specified data source selected if it is present. - */ -public final class ViewSummaryInformationAction extends AbstractAction { - - private static DataSourceSummaryDialog dataSourceSummaryDialog; - private static Long selectDataSource; - private static final long serialVersionUID = 1L; - - /** - * Create a ViewSummaryInformationAction for the selected datasource. - * - * @param selectedDataSource - the data source which is currently selected - and will be selected initially when the - DataSourceSummaryDialog opens. - */ - @Messages({"ViewSummaryInformationAction.name.text=View Summary Information"}) - public ViewSummaryInformationAction(Long selectedDataSource) { - super(Bundle.ViewSummaryInformationAction_name_text()); - selectDataSource = selectedDataSource; - } - - @Override - public void actionPerformed(ActionEvent actionEvent) { - SwingUtilities.invokeLater(() -> { - Frame mainWindow = WindowManager.getDefault().getMainWindow(); - dataSourceSummaryDialog = new DataSourceSummaryDialog(mainWindow); - //allow dialog to be closed when actions performed - dataSourceSummaryDialog.enableObserver(); - //select the specifed data source - dataSourceSummaryDialog.selectDataSource(selectDataSource); - dataSourceSummaryDialog.setResizable(true); - dataSourceSummaryDialog.setLocationRelativeTo(mainWindow); - dataSourceSummaryDialog.setVisible(true); - dataSourceSummaryDialog.toFront(); - }); - } - -} From 44610b25e99d6f9bf53baae80f0422d6ce08f896 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 23 Jul 2020 08:44:15 -0400 Subject: [PATCH 2/2] add the folder back in all lower case --- .../datasourcesummary/Bundle.properties | 38 + .../Bundle.properties-MERGED | 73 ++ .../datasourcesummary/Bundle_ja.properties | 73 ++ .../datasourcesummary/DataSourceBrowser.form | 18 + .../datasourcesummary/DataSourceBrowser.java | 251 +++++++ .../DataSourceInfoUtilities.java | 366 +++++++++ .../DataSourceLabeledValueCallback.java | 71 ++ .../DataSourceSingleValueCallback.java | 66 ++ .../datasourcesummary/DataSourceSummary.java | 180 +++++ .../DataSourceSummaryAction.java | 75 ++ .../DataSourceSummaryCountsPanel.form | 139 ++++ .../DataSourceSummaryCountsPanel.java | 395 ++++++++++ .../DataSourceSummaryDetailsPanel.form | 495 +++++++++++++ .../DataSourceSummaryDetailsPanel.java | 698 ++++++++++++++++++ .../DataSourceSummaryDialog.form | 82 ++ .../DataSourceSummaryDialog.java | 178 +++++ .../DataSourceSummaryNode.java | 216 ++++++ .../RightAlignedTableCellRenderer.java | 61 ++ .../ViewSummaryInformationAction.java | 67 ++ 19 files changed, 3542 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties-MERGED create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle_ja.properties create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties new file mode 100644 index 0000000000..2cb4756460 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties @@ -0,0 +1,38 @@ +DataSourceSummaryDialog.closeButton.text=Close +DataSourceSummaryDetailsPanel.displayNameLabel.text=Display Name: +DataSourceSummaryDetailsPanel.originalNameLabel.text=Name: +DataSourceSummaryDetailsPanel.deviceIdLabel.text=Device ID: +DataSourceSummaryDetailsPanel.operatingSystemLabel.text=OS: +DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text=Usage: +DataSourceSummaryDetailsPanel.timeZoneLabel.text=Time Zone: +DataSourceSummaryDetailsPanel.imageTypeLabel.text=Image Type: +DataSourceSummaryDetailsPanel.sizeLabel.text=Size: +DataSourceSummaryDetailsPanel.sectorSizeLabel.text=Sector Size: +DataSourceSummaryDetailsPanel.md5HashLabel.text=MD5: +DataSourceSummaryDetailsPanel.sha1HashLabel.text=SHA1: +DataSourceSummaryDetailsPanel.sha256HashLabel.text=SHA256: +DataSourceSummaryDetailsPanel.filePathsLabel.text=File Paths: +DataSourceSummaryDetailsPanel.displayNameValue.text= +DataSourceSummaryDetailsPanel.originalNameValue.text= +DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText= +DataSourceSummaryDetailsPanel.deviceIdValue.text= +DataSourceSummaryDetailsPanel.dataSourceUsageValue.text= +DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText= +DataSourceSummaryDetailsPanel.operatingSystemValue.text= +DataSourceSummaryDetailsPanel.timeZoneValue.text= +DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText= +DataSourceSummaryDetailsPanel.imageTypeValue.text= +DataSourceSummaryDetailsPanel.sizeValue.text= +DataSourceSummaryDetailsPanel.sectorSizeValue.text= +DataSourceSummaryDetailsPanel.md5HashValue.toolTipText= +DataSourceSummaryDetailsPanel.md5HashValue.text= +DataSourceSummaryDetailsPanel.sha1HashValue.text= +DataSourceSummaryDetailsPanel.sha256HashValue.text= +DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0= +DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= +DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details: +DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: +DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= +DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type +DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category +DataSourceSummaryCountsPanel.jLabel1.text=Results by Type diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties-MERGED new file mode 100644 index 0000000000..fe998b0e57 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties-MERGED @@ -0,0 +1,73 @@ +CTL_DataSourceSummaryAction=Data Source Summary +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=Count +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos +DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case. +DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure +DataSourceSummaryDetailsPanel.units.bytes=\ bytes +DataSourceSummaryDetailsPanel.units.gigabytes=\ GB +DataSourceSummaryDetailsPanel.units.kilobytes=\ kB +DataSourceSummaryDetailsPanel.units.megabytes=\ MB +DataSourceSummaryDetailsPanel.units.petabytes=\ PB +DataSourceSummaryDetailsPanel.units.terabytes=\ TB +DataSourceSummaryDialog.closeButton.text=Close +DataSourceSummaryDetailsPanel.displayNameLabel.text=Display Name: +DataSourceSummaryDetailsPanel.originalNameLabel.text=Name: +DataSourceSummaryDetailsPanel.deviceIdLabel.text=Device ID: +DataSourceSummaryDetailsPanel.operatingSystemLabel.text=OS: +DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text=Usage: +DataSourceSummaryDetailsPanel.timeZoneLabel.text=Time Zone: +DataSourceSummaryDetailsPanel.imageTypeLabel.text=Image Type: +DataSourceSummaryDetailsPanel.sizeLabel.text=Size: +DataSourceSummaryDetailsPanel.sectorSizeLabel.text=Sector Size: +DataSourceSummaryDetailsPanel.md5HashLabel.text=MD5: +DataSourceSummaryDetailsPanel.sha1HashLabel.text=SHA1: +DataSourceSummaryDetailsPanel.sha256HashLabel.text=SHA256: +DataSourceSummaryDetailsPanel.filePathsLabel.text=File Paths: +DataSourceSummaryDetailsPanel.displayNameValue.text= +DataSourceSummaryDetailsPanel.originalNameValue.text= +DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText= +DataSourceSummaryDetailsPanel.deviceIdValue.text= +DataSourceSummaryDetailsPanel.dataSourceUsageValue.text= +DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText= +DataSourceSummaryDetailsPanel.operatingSystemValue.text= +DataSourceSummaryDetailsPanel.timeZoneValue.text= +DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText= +DataSourceSummaryDetailsPanel.imageTypeValue.text= +DataSourceSummaryDetailsPanel.sizeValue.text= +DataSourceSummaryDetailsPanel.sectorSizeValue.text= +DataSourceSummaryDetailsPanel.md5HashValue.toolTipText= +DataSourceSummaryDetailsPanel.md5HashValue.text= +DataSourceSummaryDetailsPanel.sha1HashValue.text= +DataSourceSummaryDetailsPanel.sha256HashValue.text= +DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0= +DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= +DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=Acquisition Details: +DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: +DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= +DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type +DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category +DataSourceSummaryCountsPanel.jLabel1.text=Results by Type +DataSourceSummaryDialog.countsTab.title=Counts +DataSourceSummaryDialog.detailsTab.title=Details +DataSourceSummaryDialog.ingestHistoryTab.title=Ingest History +DataSourceSummaryDialog.window.title=Data Sources Summary +DataSourceSummaryNode.column.dataSourceName.header=Data Source Name +DataSourceSummaryNode.column.files.header=Files +DataSourceSummaryNode.column.results.header=Results +DataSourceSummaryNode.column.status.header=Ingest Status +DataSourceSummaryNode.column.tags.header=Tags +DataSourceSummaryNode.column.type.header=Type +DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source +ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle_ja.properties new file mode 100644 index 0000000000..99fd24c7ef --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle_ja.properties @@ -0,0 +1,73 @@ +CTL_DataSourceSummaryAction=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30b5\u30de\u30ea\u30fc +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=\u3059\u3079\u3066 +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=\u5272\u308a\u5f53\u3066\u6e08\u307f +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=\u30ab\u30a6\u30f3\u30c8 +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 +DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=\u672a\u4f7f\u7528 +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=\u97f3\u58f0 +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=\u30ab\u30a6\u30f3\u30c8 +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=\u6587\u66f8 +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=\u5b9f\u884c\u53ef\u80fd\u30d5\u30a1\u30a4\u30eb +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=\u30a4\u30e1\u30fc\u30b8 +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7 +DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=\u52d5\u753b +DataSourceSummaryDetailsPanel.getDataSources.error.text=\u73fe\u5728\u306e\u30b1\u30fc\u30b9\u306e\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30ea\u30b9\u30c8\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 +DataSourceSummaryDetailsPanel.getDataSources.error.title=\u8aad\u307f\u8fbc\u307f\u5931\u6557 +DataSourceSummaryDetailsPanel.units.bytes=\ \u30d0\u30a4\u30c8 +DataSourceSummaryDetailsPanel.units.gigabytes=\ GB +DataSourceSummaryDetailsPanel.units.kilobytes=\ kB +DataSourceSummaryDetailsPanel.units.megabytes=\ MB +DataSourceSummaryDetailsPanel.units.petabytes=\ PB +DataSourceSummaryDetailsPanel.units.terabytes=\ TB +DataSourceSummaryDialog.closeButton.text=\u9589\u3058\u308b +DataSourceSummaryDetailsPanel.displayNameLabel.text=\u8868\u793a\u540d: +DataSourceSummaryDetailsPanel.originalNameLabel.text=\u540d\u524d: +DataSourceSummaryDetailsPanel.deviceIdLabel.text=\u30c7\u30d0\u30a4\u30b9ID: +DataSourceSummaryDetailsPanel.operatingSystemLabel.text=OS: +DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text=\u4f7f\u7528\u91cf: +DataSourceSummaryDetailsPanel.timeZoneLabel.text=\u30bf\u30a4\u30e0\u30be\u30fc\u30f3: +DataSourceSummaryDetailsPanel.imageTypeLabel.text=\u30a4\u30e1\u30fc\u30b8\u30bf\u30a4\u30d7: +DataSourceSummaryDetailsPanel.sizeLabel.text=\u30b5\u30a4\u30ba: +DataSourceSummaryDetailsPanel.sectorSizeLabel.text=\u30bb\u30af\u30bf\u30fc\u30b5\u30a4\u30ba: +DataSourceSummaryDetailsPanel.md5HashLabel.text=MD5: +DataSourceSummaryDetailsPanel.sha1HashLabel.text=SHA1: +DataSourceSummaryDetailsPanel.sha256HashLabel.text=SHA256: +DataSourceSummaryDetailsPanel.filePathsLabel.text=\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9: +DataSourceSummaryDetailsPanel.displayNameValue.text= +DataSourceSummaryDetailsPanel.originalNameValue.text= +DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText= +DataSourceSummaryDetailsPanel.deviceIdValue.text= +DataSourceSummaryDetailsPanel.dataSourceUsageValue.text= +DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText= +DataSourceSummaryDetailsPanel.operatingSystemValue.text= +DataSourceSummaryDetailsPanel.timeZoneValue.text= +DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText= +DataSourceSummaryDetailsPanel.imageTypeValue.text= +DataSourceSummaryDetailsPanel.sizeValue.text= +DataSourceSummaryDetailsPanel.sectorSizeValue.text= +DataSourceSummaryDetailsPanel.md5HashValue.toolTipText= +DataSourceSummaryDetailsPanel.md5HashValue.text= +DataSourceSummaryDetailsPanel.sha1HashValue.text= +DataSourceSummaryDetailsPanel.sha256HashValue.text= +DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0= +DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text= +DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text=\u53d6\u5f97\u306e\u8a73\u7d30: +DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=\u672a\u4f7f\u7528\u9818\u57df: +DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= +DataSourceSummaryCountsPanel.byMimeTypeLabel.text=MIME\u30bf\u30a4\u30d7\u5225\u30d5\u30a1\u30a4\u30eb +DataSourceSummaryCountsPanel.byCategoryLabel.text=\u30ab\u30c6\u30b4\u30ea\u30fc\u5225\u30d5\u30a1\u30a4\u30eb +DataSourceSummaryCountsPanel.jLabel1.text=\u30bf\u30a4\u30d7\u5225\u7d50\u679c +DataSourceSummaryDialog.countsTab.title=\u30ab\u30a6\u30f3\u30c8 +DataSourceSummaryDialog.detailsTab.title=\u8a73\u7d30 +DataSourceSummaryDialog.ingestHistoryTab.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u5c65\u6b74 +DataSourceSummaryDialog.window.title=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30b5\u30de\u30ea\u30fc +DataSourceSummaryNode.column.dataSourceName.header=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u540d +DataSourceSummaryNode.column.files.header=\u30d5\u30a1\u30a4\u30eb +DataSourceSummaryNode.column.results.header=\u7d50\u679c +DataSourceSummaryNode.column.status.header=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b9\u30c6\u30fc\u30bf\u30b9 +DataSourceSummaryNode.column.tags.header=\u30bf\u30b0 +DataSourceSummaryNode.column.type.header=\u30bf\u30a4\u30d7 +DataSourceSummaryNode.viewDataSourceAction.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u79fb\u52d5 +ViewSummaryInformationAction.name.text=\u30b5\u30de\u30ea\u30fc\u60c5\u5831\u3092\u8868\u793a diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form new file mode 100644 index 0000000000..bb3b76f532 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.form @@ -0,0 +1,18 @@ + + +
+ + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java new file mode 100644 index 0000000000..92967738b0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceBrowser.java @@ -0,0 +1,251 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.awt.EventQueue; +import java.beans.PropertyVetoException; +import javax.swing.ListSelectionModel; +import org.netbeans.swing.outline.DefaultOutlineModel; +import org.netbeans.swing.outline.Outline; +import org.openide.explorer.ExplorerManager; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Observer; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import javax.swing.event.ListSelectionListener; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryNode.DataSourceSummaryEntryNode; +import static javax.swing.SwingConstants.RIGHT; +import javax.swing.SwingUtilities; +import javax.swing.table.TableColumn; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.IngestJobInfo; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Panel which allows viewing and selecting of Data Sources and some of their + * related information. + */ +final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { + + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(DataSourceBrowser.class.getName()); + private static final int COUNT_COLUMN_WIDTH = 20; + private static final int INGEST_STATUS_WIDTH = 50; + private static final int USAGE_COLUMN_WIDTH = 110; + private static final int DATA_SOURCE_COLUMN_WIDTH = 280; + private final Outline outline; + private final org.openide.explorer.view.OutlineView outlineView; + private final ExplorerManager explorerManager; + private final List dataSourceSummaryList; + private final RightAlignedTableCellRenderer rightAlignedRenderer = new RightAlignedTableCellRenderer(); + + /** + * Creates new form DataSourceBrowser + */ + DataSourceBrowser(Map usageMap, Map fileCountsMap) { + initComponents(); + rightAlignedRenderer.setHorizontalAlignment(RIGHT); + explorerManager = new ExplorerManager(); + outlineView = new org.openide.explorer.view.OutlineView(); + this.setVisible(true); + outlineView.setPropertyColumns( + Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), + Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), + Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), + Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(), + Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header()); + outline = outlineView.getOutline(); + + outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + dataSourceSummaryList = getDataSourceSummaryList(usageMap, fileCountsMap); + outline.setRootVisible(false); + add(outlineView, java.awt.BorderLayout.CENTER); + explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList)); + ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.DataSourceSummaryNode_column_dataSourceName_header()); + for (TableColumn column : Collections.list(outline.getColumnModel().getColumns())) { + if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_files_header()) + || column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_results_header()) + || column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_tags_header())) { + column.setCellRenderer(rightAlignedRenderer); + column.setPreferredWidth(COUNT_COLUMN_WIDTH); + } else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_type_header())) { + column.setPreferredWidth(USAGE_COLUMN_WIDTH); + } else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_status_header())) { + column.setPreferredWidth(INGEST_STATUS_WIDTH); + } else { + column.setPreferredWidth(DATA_SOURCE_COLUMN_WIDTH); + } + } + this.setVisible(true); + } + + /** + * Select the datasource which matches the specified data source object id. + * If the specified id is null or no data source matches the id the first + * data source will be selected instead. + * + * @param dataSourceId the object id of the data source to select, null if + * the first data source should be selected + */ + void selectDataSource(Long dataSourceId) { + EventQueue.invokeLater(() -> { + if (dataSourceId != null) { + for (Node node : explorerManager.getRootContext().getChildren().getNodes()) { + if (node instanceof DataSourceSummaryEntryNode && ((DataSourceSummaryEntryNode) node).getDataSource().getId() == dataSourceId) { + try { + explorerManager.setExploredContextAndSelection(node, new Node[]{node}); + return; + } catch (PropertyVetoException ex) { + logger.log(Level.WARNING, "Failed to select the datasource in the explorer view", ex); //NON-NLS + } + } + } + } + //if no data source was selected and there are data sources to select select the first one + if (explorerManager.getRootContext().getChildren().getNodes().length > 0) { + outline.getSelectionModel().setSelectionInterval(0, 0); + } + }); + } + + /** + * Add the specified observer as an observer of the DataSourceSummaryNode's + * observable. + * + * @param observer the observer which should be added + */ + void addObserver(Observer observer) { + ((DataSourceSummaryNode) explorerManager.getRootContext()).addObserver(observer); + } + + /** + * Get a list of the DataSourceSummary objects representing the information + * to be displayed for each DataSource in this browser. + * + * @return list containing a DataSourceSummary object for each DataSource in + * the current case. + */ + private List getDataSourceSummaryList(Map usageMap, Map fileCountsMap) { + List summaryList = new ArrayList<>(); + + final Map artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts(); + final Map tagCountsMap = DataSourceInfoUtilities.getCountsOfTags(); + try { + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + for (DataSource dataSource : skCase.getDataSources()) { + summaryList.add(new DataSourceSummary(dataSource, usageMap.get(dataSource.getId()), + fileCountsMap.get(dataSource.getId()), artifactCountsMap.get(dataSource.getId()), tagCountsMap.get(dataSource.getId()))); + } + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to datasources or their counts, providing empty results", ex); + } + return summaryList; + } + + /** + * 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); + } + + /** + * Get the DataSource which is currently selected in the ExplorerManager + * + * @return the selected DataSource + */ + DataSource getSelectedDataSource() { + Node selectedNode[] = explorerManager.getSelectedNodes(); + if (selectedNode.length == 1 && selectedNode[0] instanceof DataSourceSummaryEntryNode) { + return ((DataSourceSummaryEntryNode) selectedNode[0]).getDataSource(); + } + return null; + } + + /** + * Update the DataSourceBrowser to display up to date status information for + * the data sources. + * + * @param dataSourceId the ID of the data source which should be updated + * @param newStatus the new status which the data source should have + */ + void refresh(long dataSourceId, IngestJobInfo.IngestJobStatusType newStatus) { + + //attempt to update the status of any datasources that had status which was STARTED + for (DataSourceSummary summary : dataSourceSummaryList) { + if (summary.getDataSource().getId() == dataSourceId) { + summary.setIngestStatus(newStatus); + } + } + //figure out which nodes were previously selected + Node[] selectedNodes = explorerManager.getSelectedNodes(); + SwingUtilities.invokeLater(() -> { + explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList)); + List nodesToSelect = new ArrayList<>(); + for (Node node : explorerManager.getRootContext().getChildren().getNodes()) { + if (node instanceof DataSourceSummaryEntryNode) { + //there should only be one selected node as multi-select is disabled + for (Node selectedNode : selectedNodes) { + if (((DataSourceSummaryEntryNode) node).getDataSource().equals(((DataSourceSummaryEntryNode) selectedNode).getDataSource())) { + nodesToSelect.add(node); + } + } + } + } + //reselect the previously selected Nodes + try { + explorerManager.setSelectedNodes(nodesToSelect.toArray(new Node[nodesToSelect.size()])); + } catch (PropertyVetoException ex) { + logger.log(Level.WARNING, "Error selecting previously selected nodes", ex); + } + + }); + + } + + /** + * 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() { + + setLayout(new java.awt.BorderLayout()); + }// //GEN-END:initComponents + + @Override + public ExplorerManager getExplorerManager() { + return explorerManager; + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java new file mode 100644 index 0000000000..c2d8263056 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceInfoUtilities.java @@ -0,0 +1,366 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskCoreException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Set; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.DataSource; + +/** + * Utilities for getting information about a data source or all data sources + * from the case database. + */ +final class DataSourceInfoUtilities { + + private static final Logger logger = Logger.getLogger(DataSourceInfoUtilities.class.getName()); + + /** + * Get a map containing the TSK_DATA_SOURCE_USAGE description attributes + * associated with each data source in the current case. + * + * @return Collection which maps datasource id to a String which displays a + * comma seperated list of values of data source usage types + * expected to be in the datasource + */ + static Map getDataSourceTypes() { + try { + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + List listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE); + Map typeMap = new HashMap<>(); + for (BlackboardArtifact typeArtifact : listOfArtifacts) { + BlackboardAttribute descriptionAttr = typeArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)); + if (typeArtifact.getDataSource() != null && descriptionAttr != null) { + long dsId = typeArtifact.getDataSource().getId(); + String type = typeMap.get(typeArtifact.getDataSource().getId()); + if (type == null) { + type = descriptionAttr.getValueString(); + } else { + type = type + ", " + descriptionAttr.getValueString(); + } + typeMap.put(dsId, type); + } + } + return typeMap; + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the number of files in each data source in the + * current case. + * + * @return Collection which maps datasource id to a count for the number of + * files in the datasource, will only contain entries for + * datasources which have at least 1 file + */ + static Map getCountsOfFiles() { + try { + final String countFilesQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() + + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS + return getValuesMap(countFilesQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the number of artifacts in each data source in the + * current case. + * + * @return Collection which maps datasource id to a count for the number of + * artifacts in the datasource, will only contain entries for + * datasources which have at least 1 artifact + */ + static Map getCountsOfArtifacts() { + try { + final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID() + + " GROUP BY data_source_obj_id"; //NON-NLS + return getValuesMap(countArtifactsQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the number of tags which have been applied in each + * data source in the current case. Not necessarily the same as the number + * of items tagged, as an item can have any number of tags. + * + * @return Collection which maps datasource id to a count for the number of + * tags which have been applied in the datasource, will only contain + * entries for datasources which have at least 1 item tagged. + */ + static Map getCountsOfTags() { + try { + final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM content_tags as content_tags, tsk_files as tsk_files" + + " WHERE content_tags.obj_id = tsk_files.obj_id" + + " GROUP BY data_source_obj_id"; //NON-NLS + //new hashmap so it can be modifiable + Map tagCountMap = new HashMap<>(getValuesMap(countFileTagsQuery)); + final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts" + + " WHERE artifact_tags.artifact_id = arts.artifact_id" + + " GROUP BY data_source_obj_id"; //NON-NLS + //combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query + getValuesMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2)); + return tagCountMap; + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the names of operating systems joined in a comma + * seperated list to the Data Source they exist on in the current case. No + * item will exist in the map for data sources which do not contain + * TS_OS_INFO artifacts which have a program name. + * + * @return Collection which maps datasource id to a String which is a comma + * seperated list of Operating system names found on the data + * source. + */ + static Map getOperatingSystems() { + Map osDetailMap = new HashMap<>(); + try { + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + ArrayList osInfoArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO); + for (BlackboardArtifact osInfo : osInfoArtifacts) { + BlackboardAttribute programName = osInfo.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)); + if (programName != null) { + String currentOsString = osDetailMap.get(osInfo.getDataSource().getId()); + if (currentOsString == null || currentOsString.isEmpty()) { + currentOsString = programName.getValueString(); + } else { + currentOsString = currentOsString + ", " + programName.getValueString(); + } + osDetailMap.put(osInfo.getDataSource().getId(), currentOsString); + } + } + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "Failed to load OS info artifacts.", ex); + } + return osDetailMap; + } + + /** + * Get the number of files in the case database for the current data source + * which have the specified mimetypes. + * + * @param currentDataSource the data source which we are finding a file + * count + * + * @param setOfMimeTypes the set of mime types which we are finding the + * number of occurences of + * + * @return a Long value which represents the number of occurrences of the + * specified mime types in the current case for the specified data + * source, null if no count was retrieved + */ + static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set setOfMimeTypes) { + if (currentDataSource != null) { + try { + String inClause = String.join("', '", setOfMimeTypes); + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + return skCase.countFilesWhere("data_source_obj_id=" + currentDataSource.getId() + + " AND type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() + + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + + " AND mime_type IN ('" + inClause + "')" + + " AND name<>''"); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get count of files for specified mime types", ex); + //unable to get count of files for the specified mimetypes cell will be displayed as empty + } + } + return null; + } + + /** + * Get a map containing the number of unallocated files in each data source + * in the current case. + * + * @return Collection which maps datasource id to a count for the number of + * unallocated files in the datasource, will only contain entries + * for datasources which have at least 1 unallocated file + */ + static Map getCountsOfUnallocatedFiles() { + try { + final String countUnallocatedFilesQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() + + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + + " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue() + + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS + return getValuesMap(countUnallocatedFilesQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of unallocated files for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the total size of unallocated files in each data + * source in the current case. + * + * @return Collection which maps datasource id to a total size in bytes of + * unallocated files in the datasource, will only contain entries + * for datasources which have at least 1 unallocated file + */ + static Map getSizeOfUnallocatedFiles() { + try { + final String countUnallocatedFilesQuery = "data_source_obj_id, sum(size) AS value" + + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() + + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + + " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue() + + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS + return getValuesMap(countUnallocatedFilesQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get size of unallocated files for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the number of directories in each data source in the + * current case. + * + * @return Collection which maps datasource id to a count for the number of + * directories in the datasource, will only contain entries for + * datasources which have at least 1 directory + */ + static Map getCountsOfDirectories() { + try { + final String countDirectoriesQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() + + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + + " AND meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue() + + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS + return getValuesMap(countDirectoriesQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of directories for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing the number of slack files in each data source in the + * current case. + * + * @return Collection which maps datasource id to a count for the number of + * slack files in the datasource, will only contain entries for + * datasources which have at least 1 slack file + */ + static Map getCountsOfSlackFiles() { + try { + final String countSlackFilesQuery = "data_source_obj_id, COUNT(*) AS value" + + " FROM tsk_files WHERE type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() + + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS + return getValuesMap(countSlackFilesQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of slack files for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Get a map containing maps which map artifact type to the number of times + * it exosts in each data source in the current case. + * + * @return Collection which maps datasource id to maps of artifact display + * name to number of occurences in the datasource, will only contain + * entries for artifacts which have at least one occurence in the + * data source. + */ + static Map> getCountsOfArtifactsByType() { + try { + final String countArtifactsQuery = "blackboard_artifacts.data_source_obj_id, blackboard_artifact_types.display_name AS label, COUNT(*) AS value" + + " FROM blackboard_artifacts, blackboard_artifact_types" + + " WHERE blackboard_artifacts.artifact_type_id = blackboard_artifact_types.artifact_type_id" + + " GROUP BY blackboard_artifacts.data_source_obj_id, blackboard_artifact_types.display_name"; + return getLabeledValuesMap(countArtifactsQuery); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to get counts of all artifact types for all datasources, providing empty results", ex); + return Collections.emptyMap(); + } + } + + /** + * Helper method to execute a select query with a + * DataSourceLabeledValueCallback. + * + * @param query the portion of the query which should follow the SELECT + * + * @return a map of datasource object IDs to maps of String labels to the + * values associated with them. + * + * @throws TskCoreException + * @throws NoCurrentCaseException + */ + private static Map> getLabeledValuesMap(String query) throws TskCoreException, NoCurrentCaseException { + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + DataSourceLabeledValueCallback callback = new DataSourceLabeledValueCallback(); + skCase.getCaseDbAccessManager().select(query, callback); + return callback.getMapOfLabeledValues(); + } + + /** + * Helper method to execute a select query with a + * DataSourceSingleValueCallback. + * + * @param query the portion of the query which should follow the SELECT + * + * @return a map of datasource object ID to a value of type Long + * + * @throws TskCoreException + * @throws NoCurrentCaseException + */ + private static Map getValuesMap(String query) throws TskCoreException, NoCurrentCaseException { + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + DataSourceSingleValueCallback callback = new DataSourceSingleValueCallback(); + skCase.getCaseDbAccessManager().select(query, callback); + return callback.getMapOfValues(); + } + + /** + * Empty private constructor + */ + private DataSourceInfoUtilities() { + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java new file mode 100644 index 0000000000..1a44e2a76b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceLabeledValueCallback.java @@ -0,0 +1,71 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.CaseDbAccessManager; + +/** + * Callback which gets a map of datasource object IDs to maps of String labels + * to the values associated with them, given a query which should select a + * 'data_source_obj_id', a 'label', and a 'value'. + */ +class DataSourceLabeledValueCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { + + private static final Logger logger = Logger.getLogger(DataSourceSingleValueCallback.class.getName()); + private final Map> dataSourceObjIdLabeledValues = new HashMap<>(); + + @Override + public void process(ResultSet rs) { + try { + while (rs.next()) { + try { + Long dataSourceObjId = rs.getLong("data_source_obj_id"); + String labelForValue = rs.getString("label"); + Long value = rs.getLong("value"); + Map labelsMap = dataSourceObjIdLabeledValues.get(dataSourceObjId) == null ? new HashMap<>() : dataSourceObjIdLabeledValues.get(dataSourceObjId); + labelsMap.put(labelForValue, value); + dataSourceObjIdLabeledValues.put(dataSourceObjId, labelsMap); + } catch (SQLException ex) { + logger.log(Level.WARNING, "Unable to get data_source_obj_id or value from result set", ex); + } + } + } catch (SQLException ex) { + logger.log(Level.WARNING, "Failed to get next result for valuess by datasource", ex); + } + } + + /** + * Get the processed results + * + * @return Collection which maps datasource object IDs to maps of String + * labels to the values associated with them only contains entries + * for data sources with at least 1 item found for any label. + */ + Map> getMapOfLabeledValues() { + return Collections.unmodifiableMap(dataSourceObjIdLabeledValues); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java new file mode 100644 index 0000000000..fc7eea15e5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSingleValueCallback.java @@ -0,0 +1,66 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.CaseDbAccessManager; + +/** + * Get the map of Data Source ID to a value found related to that data source + * query which selects data_source_obj_id and value which is grouped by that + * data source object id. + */ +class DataSourceSingleValueCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { + + private static final Logger logger = Logger.getLogger(DataSourceSingleValueCallback.class.getName()); + private final Map dataSourceObjIdValues = new HashMap<>(); + + @Override + public void process(ResultSet rs) { + try { + while (rs.next()) { + try { + dataSourceObjIdValues.put(rs.getLong("data_source_obj_id"), rs.getLong("value")); + } catch (SQLException ex) { + logger.log(Level.WARNING, "Unable to get data_source_obj_id or value from result set", ex); + } + } + } catch (SQLException ex) { + logger.log(Level.WARNING, "Failed to get next result for valuess by datasource", ex); + } + } + + /** + * Get the processed results + * + * @return Collection which maps datasource id to a value related to the + * datasource id, only contains entries for datasources with at + * least 1 item found. + */ + Map getMapOfValues() { + return Collections.unmodifiableMap(dataSourceObjIdValues); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java new file mode 100644 index 0000000000..b50c3596bd --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummary.java @@ -0,0 +1,180 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.datamodel.CaseDbAccessManager; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.IngestJobInfo.IngestJobStatusType; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Wrapper object for a DataSource and the information associated with it. + * + */ +class DataSourceSummary { + + private static final Logger logger = Logger.getLogger(DataSourceSummary.class.getName()); + private static final String INGEST_JOB_STATUS_QUERY = "status_id FROM ingest_jobs WHERE obj_id="; + private final DataSource dataSource; + private IngestJobStatusType status = null; + private final String type; + private final long filesCount; + private final long resultsCount; + private final long tagsCount; + + /** + * Construct a new DataSourceSummary object + * + * @param dSource the DataSource being wrapped by this object + * @param typeValue the Type sting to be associated with this + * DataSource + * @param numberOfFiles the number of files found in this DataSource + * @param numberOfResults the number of artifacts found in this DataSource + * @param numberOfTags the number of tagged content objects in this + * DataSource + */ + DataSourceSummary(DataSource dSource, String typeValue, Long numberOfFiles, Long numberOfResults, Long numberOfTags) { + dataSource = dSource; + getStatusFromDatabase(); + type = typeValue == null ? "" : typeValue; + filesCount = numberOfFiles == null ? 0 : numberOfFiles; + resultsCount = numberOfResults == null ? 0 : numberOfResults; + tagsCount = numberOfTags == null ? 0 : numberOfTags; + } + + /** + * Get the status of the ingest job from the case database + */ + private void getStatusFromDatabase() { + try { + IngestJobQueryCallback callback = new IngestJobQueryCallback(); + Case.getCurrentCaseThrows().getSleuthkitCase().getCaseDbAccessManager().select(INGEST_JOB_STATUS_QUERY + dataSource.getId(), callback); + status = callback.getStatus(); + } catch (NoCurrentCaseException | TskCoreException ex) { + logger.log(Level.WARNING, "Error getting status for data source from case database", ex); + } + } + + /** + * Get the DataSource + * + * @return the dataSource + */ + DataSource getDataSource() { + return dataSource; + } + + /** + * Manually set the ingest job status + * + * @param ingestStatus the status which the ingest job should have + * currently, null to display empty string + */ + void setIngestStatus(IngestJobStatusType ingestStatus) { + status = ingestStatus; + } + + /** + * Get the type of this DataSource + * + * @return the type + */ + String getType() { + return type; + } + + /** + * Get the number of files in this DataSource + * + * @return the filesCount + */ + long getFilesCount() { + return filesCount; + } + + /** + * Get the number of artifacts in this DataSource + * + * @return the resultsCount + */ + long getResultsCount() { + return resultsCount; + } + + /** + * Get the IngestJobStatusType associated with this data source. + * + * @return the IngestJobStatusType associated with this data source. Can be + * null if the IngestJobStatusType is not STARTED or COMPLETED. + */ + IngestJobStatusType getIngestStatus() { + return status; + } + + /** + * Get the number of tagged content objects in this DataSource + * + * @return the tagsCount + */ + long getTagsCount() { + return tagsCount; + } + + /** + * Callback to parse result set, getting the status to be associated with + * this data source + */ + class IngestJobQueryCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { + + private IngestJobStatusType jobStatus = null; + + @Override + public void process(ResultSet rs) { + try { + while (rs.next()) { + IngestJobStatusType currentStatus = IngestJobStatusType.fromID(rs.getInt("status_id")); + if (currentStatus == IngestJobStatusType.COMPLETED) { + jobStatus = currentStatus; + } else if (currentStatus == IngestJobStatusType.STARTED) { + jobStatus = currentStatus; + return; + } + } + } catch (SQLException ex) { + logger.log(Level.WARNING, "Error getting status for ingest job", ex); + } + } + + /** + * Get the status which was determined for this callback + * + * @return the status of the data source which was queried for + */ + IngestJobStatusType getStatus() { + return jobStatus; + } + + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java new file mode 100644 index 0000000000..7514d61599 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryAction.java @@ -0,0 +1,75 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.util.EnumSet; +import javax.swing.Action; +import org.openide.awt.ActionID; +import org.openide.awt.ActionRegistration; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle.Messages; +import org.openide.util.actions.CallableSystemAction; +import org.sleuthkit.autopsy.casemodule.Case; + +@ActionID(category = "Case", id = "org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryAction") +@ActionRegistration(displayName = "#CTL_DataSourceSummaryAction", lazy = false) +@Messages({"CTL_DataSourceSummaryAction=Data Source Summary"}) +/** + * DataSourceSummaryAction action for the Case menu to activate a + * ViewSummaryInformationAction selecting the first data source. + */ +public class DataSourceSummaryAction extends CallableSystemAction { + + private static final long serialVersionUID = 1L; + + /** + * Create a datasource summary action which will be disabled when no case is + * open. + */ + DataSourceSummaryAction() { + putValue(Action.NAME, Bundle.CTL_DataSourceSummaryAction()); + this.setEnabled(false); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + setEnabled(null != evt.getNewValue()); + }); + } + + @Override + public void performAction() { + //perform the action of a ViewSummaryInformationAction with a ActionEvent which will not be used + new ViewSummaryInformationAction(null).actionPerformed(new ActionEvent(Boolean.TRUE, 0, "")); + } + + @Override + public String getName() { + return Bundle.CTL_DataSourceSummaryAction(); + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + public boolean asynchronous() { + return false; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form new file mode 100644 index 0000000000..d3a17e0205 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.form @@ -0,0 +1,139 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java new file mode 100644 index 0000000000..1d99f1c445 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryCountsPanel.java @@ -0,0 +1,395 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.sleuthkit.autopsy.coreutils.Logger; +import javax.swing.JLabel; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.coreutils.FileTypeUtils; +import org.sleuthkit.datamodel.DataSource; + +/** + * Panel for displaying summary information on the known files present in the + * specified DataSource + */ +class DataSourceSummaryCountsPanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; + private FilesByMimeTypeTableModel filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(null); + private FilesByCategoryTableModel filesByCategoryTableModel = new FilesByCategoryTableModel(null); + private static final Logger logger = Logger.getLogger(DataSourceSummaryCountsPanel.class.getName()); + private final Map allFilesCountsMap; + private final Map slackFilesCountsMap; + private final Map directoriesCountsMap; + private final Map unallocatedFilesCountsMap; + private final Map> artifactsByTypeCountsMap; + private final DefaultTableCellRenderer rightAlignedRenderer = new DefaultTableCellRenderer(); + + /** + * Creates new form DataSourceSummaryCountsPanel + */ + DataSourceSummaryCountsPanel(Map fileCountsMap) { + this.allFilesCountsMap = fileCountsMap; + this.slackFilesCountsMap = DataSourceInfoUtilities.getCountsOfSlackFiles(); + this.directoriesCountsMap = DataSourceInfoUtilities.getCountsOfDirectories(); + this.unallocatedFilesCountsMap = DataSourceInfoUtilities.getCountsOfUnallocatedFiles(); + this.artifactsByTypeCountsMap = DataSourceInfoUtilities.getCountsOfArtifactsByType(); + rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT); + initComponents(); + fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false); + fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false); + } + + /** + * Specify the DataSource to display file information for + * + * @param selectedDataSource the DataSource to display file information for + */ + void updateCountsTableData(DataSource selectedDataSource) { + filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(selectedDataSource); + fileCountsByMimeTypeTable.setModel(filesByMimeTypeTableModel); + fileCountsByMimeTypeTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); + fileCountsByMimeTypeTable.getColumnModel().getColumn(0).setPreferredWidth(130); + filesByCategoryTableModel = new FilesByCategoryTableModel(selectedDataSource); + fileCountsByCategoryTable.setModel(filesByCategoryTableModel); + fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); + fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130); + updateArtifactCounts(selectedDataSource); + this.repaint(); + } + + /** + * Helper method to update the artifact specific counts by clearing the + * table and adding counts for the artifacts which exist in the selected + * data source. + * + * @param selectedDataSource the data source to display artifact counts for + */ + private void updateArtifactCounts(DataSource selectedDataSource) { + ((DefaultTableModel) artifactCountsTable.getModel()).setRowCount(0); + if (selectedDataSource != null && artifactsByTypeCountsMap.get(selectedDataSource.getId()) != null) { + Map artifactCounts = artifactsByTypeCountsMap.get(selectedDataSource.getId()); + for (String key : artifactCounts.keySet()) { + ((DefaultTableModel) artifactCountsTable.getModel()).addRow(new Object[]{key, artifactCounts.get(key)}); + } + } + artifactCountsTable.getColumnModel().getColumn(0).setPreferredWidth(230); + artifactCountsTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer); + } + + /** + * 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() { + + fileCountsByMimeTypeScrollPane = new javax.swing.JScrollPane(); + fileCountsByMimeTypeTable = new javax.swing.JTable(); + byMimeTypeLabel = new javax.swing.JLabel(); + fileCountsByCategoryScrollPane = new javax.swing.JScrollPane(); + fileCountsByCategoryTable = new javax.swing.JTable(); + byCategoryLabel = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + artifactCountsScrollPane = new javax.swing.JScrollPane(); + artifactCountsTable = new javax.swing.JTable(); + + fileCountsByMimeTypeTable.setModel(filesByMimeTypeTableModel); + fileCountsByMimeTypeScrollPane.setViewportView(fileCountsByMimeTypeTable); + + org.openide.awt.Mnemonics.setLocalizedText(byMimeTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byMimeTypeLabel.text")); // NOI18N + + fileCountsByCategoryTable.setModel(filesByCategoryTableModel); + fileCountsByCategoryScrollPane.setViewportView(fileCountsByCategoryTable); + + org.openide.awt.Mnemonics.setLocalizedText(byCategoryLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.byCategoryLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.jLabel1.text")); // NOI18N + + artifactCountsTable.setAutoCreateRowSorter(true); + artifactCountsTable.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Result Type", "Count" + } + ) { + boolean[] canEdit = new boolean [] { + false, false + }; + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + artifactCountsScrollPane.setViewportView(artifactCountsTable); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE) + .addComponent(byMimeTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(byCategoryLabel) + .addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane}); + + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(byMimeTypeLabel) + .addComponent(byCategoryLabel) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(artifactCountsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(fileCountsByMimeTypeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(fileCountsByCategoryScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + + layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {fileCountsByCategoryScrollPane, fileCountsByMimeTypeScrollPane}); + + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane artifactCountsScrollPane; + private javax.swing.JTable artifactCountsTable; + private javax.swing.JLabel byCategoryLabel; + private javax.swing.JLabel byMimeTypeLabel; + private javax.swing.JScrollPane fileCountsByCategoryScrollPane; + private javax.swing.JTable fileCountsByCategoryTable; + private javax.swing.JScrollPane fileCountsByMimeTypeScrollPane; + private javax.swing.JTable fileCountsByMimeTypeTable; + private javax.swing.JLabel jLabel1; + // End of variables declaration//GEN-END:variables + + /** + * Table model for the files table model to display counts of specific file + * types by mime type found in the currently selected data source. + */ + @Messages({"DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.type.header=File Type", + "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.count.header=Count"}) + private class FilesByMimeTypeTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + private final DataSource currentDataSource; + private final List columnHeaders = new ArrayList<>(); + private static final int IMAGES_ROW_INDEX = 0; + private static final int VIDEOS_ROW_INDEX = 1; + private static final int AUDIO_ROW_INDEX = 2; + private static final int DOCUMENTS_ROW_INDEX = 3; + private static final int EXECUTABLES_ROW_INDEX = 4; + + /** + * Create a FilesByMimeTypeTableModel for the speicified datasource. + * + * @param selectedDataSource the datasource which this + * FilesByMimeTypeTablemodel will represent + */ + FilesByMimeTypeTableModel(DataSource selectedDataSource) { + columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_type_header()); + columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_count_header()); + currentDataSource = selectedDataSource; + } + + @Override + public int getRowCount() { + //should be kept equal to the number of types we are displaying in the tables + return 5; + } + + @Override + public int getColumnCount() { + return columnHeaders.size(); + } + + @Messages({ + "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.images.row=Images", + "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.videos.row=Videos", + "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.audio.row=Audio", + "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.documents.row=Documents", + "DataSourceSummaryCountsPanel.FilesByMimeTypeTableModel.executables.row=Executables" + }) + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (columnIndex == 0) { + switch (rowIndex) { + case IMAGES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_images_row(); + case VIDEOS_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_videos_row(); + case AUDIO_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_audio_row(); + case DOCUMENTS_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_documents_row(); + case EXECUTABLES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByMimeTypeTableModel_executables_row(); + default: + break; + } + } else if (columnIndex == 1) { + switch (rowIndex) { + case 0: + return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes()); + case 1: + return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes()); + case 2: + return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes()); + case 3: + return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes()); + case 4: + return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes()); + default: + break; + } + } + return null; + } + + @Override + public String getColumnName(int column) { + return columnHeaders.get(column); + } + } + + /** + * Table model for the files table model to display counts of specific file + * types by category found in the currently selected data source. + */ + @Messages({"DataSourceSummaryCountsPanel.FilesByCategoryTableModel.type.header=File Type", + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.count.header=Count"}) + private class FilesByCategoryTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + private final DataSource currentDataSource; + private final List columnHeaders = new ArrayList<>(); + private static final int ALL_FILES_ROW_INDEX = 0; + private static final int ALLOCATED_FILES_ROW_INDEX = 1; + private static final int UNALLOCATED_FILES_ROW_INDEX = 2; + private static final int SLACK_FILES_ROW_INDEX = 3; + private static final int DIRECTORIES_ROW_INDEX = 4; + /** + * Create a FilesByCategoryTableModel for the speicified datasource. + * + * @param selectedDataSource the datasource which this + * FilesByCategoryTablemodel will represent + */ + FilesByCategoryTableModel(DataSource selectedDataSource) { + columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_type_header()); + columnHeaders.add(Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_count_header()); + currentDataSource = selectedDataSource; + } + + @Override + public int getRowCount() { + //should be kept equal to the number of types we are displaying in the tables + return 5; + } + + @Override + public int getColumnCount() { + return columnHeaders.size(); + } + + @Messages({ + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.all.row=All", + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.allocated.row=Allocated", + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.unallocated.row=Unallocated", + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.slack.row=Slack", + "DataSourceSummaryCountsPanel.FilesByCategoryTableModel.directory.row=Directory" + }) + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (columnIndex == 0) { + switch (rowIndex) { + case ALL_FILES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_all_row(); + case ALLOCATED_FILES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_allocated_row(); + case UNALLOCATED_FILES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_unallocated_row(); + case SLACK_FILES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_slack_row(); + case DIRECTORIES_ROW_INDEX: + return Bundle.DataSourceSummaryCountsPanel_FilesByCategoryTableModel_directory_row(); + default: + break; + } + } else if (columnIndex == 1 && currentDataSource != null) { + switch (rowIndex) { + case 0: + return allFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : allFilesCountsMap.get(currentDataSource.getId()); + case 1: + //All files should be either allocated or unallocated as dir_flags only has two values so any file that isn't unallocated is allocated + Long unallocatedFilesCount = unallocatedFilesCountsMap.get(currentDataSource.getId()); + Long allFilesCount = allFilesCountsMap.get(currentDataSource.getId()); + if (allFilesCount == null) { + return 0; + } else if (unallocatedFilesCount == null) { + return allFilesCount; + } else { + return allFilesCount - unallocatedFilesCount; + } + case 2: + return unallocatedFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : unallocatedFilesCountsMap.get(currentDataSource.getId()); + case 3: + return slackFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : slackFilesCountsMap.get(currentDataSource.getId()); + case 4: + return directoriesCountsMap.get(currentDataSource.getId()) == null ? 0 : directoriesCountsMap.get(currentDataSource.getId()); + default: + break; + } + } + return null; + } + + @Override + public String getColumnName(int column) { + return columnHeaders.get(column); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form new file mode 100644 index 0000000000..9efc00faa0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.form @@ -0,0 +1,495 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + <ResourceString bundle="org/sleuthkit/autopsy/casemodule/datasourcesummary/Bundle.properties" key="DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java new file mode 100644 index 0000000000..1b898f4995 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDetailsPanel.java @@ -0,0 +1,698 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.text.DecimalFormat; +import java.util.Map; +import java.util.HashMap; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coreutils.Logger; +import javax.swing.table.DefaultTableModel; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.Image; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Panel to display additional details associated with a specific DataSource + */ +class DataSourceSummaryDetailsPanel extends javax.swing.JPanel { + + //Because this panel was made using the gridbaglayout and netbean's Customize Layout tool it will be best to continue to modify it through that + private static final long serialVersionUID = 1L; + private Map osDetailMap = new HashMap<>(); + private static final Integer SIZE_COVERSION_CONSTANT = 1000; + private static final DecimalFormat APPROXIMATE_SIZE_FORMAT = new DecimalFormat("#.##"); + private final Map unallocatedFilesSizeMap; + private final Map usageMap; + private static final Logger logger = Logger.getLogger(DataSourceSummaryDetailsPanel.class.getName()); + + /** + * Creates new form DataSourceSummaryDetailsPanel + */ + @Messages({"DataSourceSummaryDetailsPanel.getDataSources.error.text=Failed to get the list of datasources for the current case.", + "DataSourceSummaryDetailsPanel.getDataSources.error.title=Load Failure"}) + DataSourceSummaryDetailsPanel(Map usageMap) { + initComponents(); + this.usageMap = usageMap; + this.unallocatedFilesSizeMap = DataSourceInfoUtilities.getSizeOfUnallocatedFiles(); + osDetailMap = DataSourceInfoUtilities.getOperatingSystems(); + } + + /** + * Update which DataSource this panel should display details about + * + * @param selectedDataSource the DataSource to display details about. + */ + void updateDetailsPanelData(DataSource selectedDataSource) { + clearTableValues(); + if (selectedDataSource != null) { + String sizeString = ""; + String sectorSizeString = ""; + String md5String = ""; + String sha1String = ""; + String sha256String = ""; + String acquisitionDetailsString = ""; + String imageTypeString = ""; + String[] filePaths = new String[0]; + String osDetailString = osDetailMap.get(selectedDataSource.getId()) == null ? "" : osDetailMap.get(selectedDataSource.getId()); + String dataSourceTypeString = usageMap.get(selectedDataSource.getId()) == null ? "" : usageMap.get(selectedDataSource.getId()); + try { + acquisitionDetailsString = selectedDataSource.getAcquisitionDetails(); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to get aquisition details for selected data source", ex); + } + if (selectedDataSource instanceof Image) { + imageTypeString = ((Image) selectedDataSource).getType().getName(); + filePaths = ((Image) selectedDataSource).getPaths(); + sizeString = getSizeString(selectedDataSource.getSize()); + sectorSizeString = getSizeString(((Image) selectedDataSource).getSsize()); + try { + //older databases may have null as the hash values + md5String = ((Image) selectedDataSource).getMd5(); + if (md5String == null) { + md5String = ""; + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to get MD5 for selected data source", ex); + } + try { + sha1String = ((Image) selectedDataSource).getSha1(); + if (sha1String == null) { + sha1String = ""; + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to get SHA1 for selected data source", ex); + } + try { + sha256String = ((Image) selectedDataSource).getSha256(); + if (sha256String == null) { + sha256String = ""; + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Unable to get SHA256 for selected data source", ex); + } + } + displayNameValue.setText(selectedDataSource.getName()); + originalNameValue.setText(selectedDataSource.getName()); + deviceIdValue.setText(selectedDataSource.getDeviceId()); + dataSourceUsageValue.setText(dataSourceTypeString); + operatingSystemValue.setText(osDetailString); + timeZoneValue.setText(selectedDataSource.getTimeZone()); + acquisitionDetailsTextArea.setText(acquisitionDetailsString); + imageTypeValue.setText(imageTypeString); + sizeValue.setText(sizeString); + unallocatedSizeValue.setText(getSizeString(unallocatedFilesSizeMap.get(selectedDataSource.getId()))); + sectorSizeValue.setText(sectorSizeString); + md5HashValue.setText(md5String); + sha1HashValue.setText(sha1String); + sha256HashValue.setText(sha256String); + for (String path : filePaths) { + ((DefaultTableModel) filePathsTable.getModel()).addRow(new Object[]{path}); + } + } + updateFieldVisibility(); + this.repaint(); + } + + /** + * Get a long size in bytes as a string formated to be read by users. + * + * @param size Long value representing a size in bytes + * + * @return return a string formated with a user friendly version of the size + * as a string, returns empty String when provided empty size + */ + @Messages({ + "DataSourceSummaryDetailsPanel.units.bytes= bytes", + "DataSourceSummaryDetailsPanel.units.kilobytes= kB", + "DataSourceSummaryDetailsPanel.units.megabytes= MB", + "DataSourceSummaryDetailsPanel.units.gigabytes= GB", + "DataSourceSummaryDetailsPanel.units.terabytes= TB", + "DataSourceSummaryDetailsPanel.units.petabytes= PB" + }) + private String getSizeString(Long size) { + if (size == null) { + return ""; + } + double approximateSize = size; + if (approximateSize < SIZE_COVERSION_CONSTANT) { + return String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes(); + } + approximateSize /= SIZE_COVERSION_CONSTANT; + if (approximateSize < SIZE_COVERSION_CONSTANT) { + return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_kilobytes() + + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; + } + approximateSize /= SIZE_COVERSION_CONSTANT; + if (approximateSize < SIZE_COVERSION_CONSTANT) { + return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_megabytes() + + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; + } + approximateSize /= SIZE_COVERSION_CONSTANT; + if (approximateSize < SIZE_COVERSION_CONSTANT) { + return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_gigabytes() + + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; + } + approximateSize /= SIZE_COVERSION_CONSTANT; + if (approximateSize < SIZE_COVERSION_CONSTANT) { + return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_terabytes() + + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; + } + approximateSize /= SIZE_COVERSION_CONSTANT; + return APPROXIMATE_SIZE_FORMAT.format(approximateSize) + Bundle.DataSourceSummaryDetailsPanel_units_petabytes() + + " (" + String.valueOf(size) + Bundle.DataSourceSummaryDetailsPanel_units_bytes() + ")"; + } + + /** + * Update the visibility of all fields and their labels based on whether + * they have contents. Empty fields have them and their contents hidden. + */ + private void updateFieldVisibility() { + displayNameValue.setVisible(!displayNameValue.getText().isEmpty()); + displayNameLabel.setVisible(!displayNameValue.getText().isEmpty()); + originalNameValue.setVisible(!originalNameValue.getText().isEmpty()); + originalNameLabel.setVisible(!originalNameValue.getText().isEmpty()); + deviceIdValue.setVisible(!deviceIdValue.getText().isEmpty()); + deviceIdLabel.setVisible(!deviceIdValue.getText().isEmpty()); + dataSourceUsageValue.setVisible(!dataSourceUsageValue.getText().isEmpty()); + dataSourceUsageLabel.setVisible(!dataSourceUsageValue.getText().isEmpty()); + operatingSystemValue.setVisible(!operatingSystemValue.getText().isEmpty()); + operatingSystemLabel.setVisible(!operatingSystemValue.getText().isEmpty()); + timeZoneValue.setVisible(!timeZoneValue.getText().isEmpty()); + timeZoneLabel.setVisible(!timeZoneValue.getText().isEmpty()); + acquisitionDetailsTextArea.setVisible(!acquisitionDetailsTextArea.getText().isEmpty()); + acquisitionDetailsLabel.setVisible(!acquisitionDetailsTextArea.getText().isEmpty()); + acquisitionDetailsScrollPane.setVisible(!acquisitionDetailsTextArea.getText().isEmpty()); + imageTypeValue.setVisible(!imageTypeValue.getText().isEmpty()); + imageTypeLabel.setVisible(!imageTypeValue.getText().isEmpty()); + sizeValue.setVisible(!sizeValue.getText().isEmpty()); + sizeLabel.setVisible(!sizeValue.getText().isEmpty()); + sectorSizeValue.setVisible(!sectorSizeValue.getText().isEmpty()); + sectorSizeLabel.setVisible(!sectorSizeValue.getText().isEmpty()); + md5HashValue.setVisible(!md5HashValue.getText().isEmpty()); + md5HashLabel.setVisible(!md5HashValue.getText().isEmpty()); + sha1HashValue.setVisible(!sha1HashValue.getText().isEmpty()); + sha1HashLabel.setVisible(!sha1HashValue.getText().isEmpty()); + sha256HashValue.setVisible(!sha256HashValue.getText().isEmpty()); + sha256HashLabel.setVisible(!sha256HashValue.getText().isEmpty()); + unallocatedSizeValue.setVisible(!unallocatedSizeValue.getText().isEmpty()); + unallocatedSizeLabel.setVisible(!unallocatedSizeValue.getText().isEmpty()); + filePathsTable.setVisible(filePathsTable.getRowCount() > 0); + filePathsLabel.setVisible(filePathsTable.getRowCount() > 0); + filePathsScrollPane.setVisible(filePathsTable.getRowCount() > 0); + } + + /** + * Set the contents of all fields to be empty. + */ + private void clearTableValues() { + displayNameValue.setText(""); + originalNameValue.setText(""); + deviceIdValue.setText(""); + dataSourceUsageValue.setText(""); + operatingSystemValue.setText(""); + timeZoneValue.setText(""); + acquisitionDetailsTextArea.setText(""); + imageTypeValue.setText(""); + sizeValue.setText(""); + sectorSizeValue.setText(""); + md5HashValue.setText(""); + sha1HashValue.setText(""); + sha256HashValue.setText(""); + unallocatedSizeValue.setText(""); + ((DefaultTableModel) filePathsTable.getModel()).setRowCount(0); + } + + /** + * 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() { + java.awt.GridBagConstraints gridBagConstraints; + + jScrollPane1 = new javax.swing.JScrollPane(); + jPanel1 = new javax.swing.JPanel(); + operatingSystemLabel = new javax.swing.JLabel(); + displayNameLabel = new javax.swing.JLabel(); + originalNameLabel = new javax.swing.JLabel(); + sha1HashValue = new javax.swing.JLabel(); + operatingSystemValue = new javax.swing.JLabel(); + displayNameValue = new javax.swing.JLabel(); + sha256HashValue = new javax.swing.JLabel(); + originalNameValue = new javax.swing.JLabel(); + deviceIdValue = new javax.swing.JLabel(); + filePathsScrollPane = new javax.swing.JScrollPane(); + filePathsTable = new javax.swing.JTable(); + dataSourceUsageValue = new javax.swing.JLabel(); + timeZoneValue = new javax.swing.JLabel(); + imageTypeValue = new javax.swing.JLabel(); + md5HashValue = new javax.swing.JLabel(); + sectorSizeValue = new javax.swing.JLabel(); + sizeValue = new javax.swing.JLabel(); + filePathsLabel = new javax.swing.JLabel(); + sha256HashLabel = new javax.swing.JLabel(); + sha1HashLabel = new javax.swing.JLabel(); + md5HashLabel = new javax.swing.JLabel(); + sectorSizeLabel = new javax.swing.JLabel(); + sizeLabel = new javax.swing.JLabel(); + imageTypeLabel = new javax.swing.JLabel(); + acquisitionDetailsLabel = new javax.swing.JLabel(); + timeZoneLabel = new javax.swing.JLabel(); + dataSourceUsageLabel = new javax.swing.JLabel(); + deviceIdLabel = new javax.swing.JLabel(); + acquisitionDetailsScrollPane = new javax.swing.JScrollPane(); + acquisitionDetailsTextArea = new javax.swing.JTextArea(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); + filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); + unallocatedSizeLabel = new javax.swing.JLabel(); + unallocatedSizeValue = new javax.swing.JLabel(); + + jPanel1.setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(operatingSystemLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.operatingSystemLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(operatingSystemLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(displayNameLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.displayNameLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 4); + jPanel1.add(displayNameLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(originalNameLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.originalNameLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(originalNameLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sha1HashValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha1HashValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 12; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(sha1HashValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(operatingSystemValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.operatingSystemValue.text")); // NOI18N + operatingSystemValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.operatingSystemValue.toolTipText")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(operatingSystemValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(displayNameValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.displayNameValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 10); + jPanel1.add(displayNameValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sha256HashValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha256HashValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 13; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 10); + jPanel1.add(sha256HashValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(originalNameValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.originalNameValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(originalNameValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(deviceIdValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.deviceIdValue.text")); // NOI18N + deviceIdValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.deviceIdValue.toolTipText")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 10); + jPanel1.add(deviceIdValue, gridBagConstraints); + + filePathsScrollPane.setPreferredSize(new java.awt.Dimension(80, 50)); + + filePathsTable.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "" + } + ) { + boolean[] canEdit = new boolean [] { + false + }; + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + filePathsTable.setTableHeader(null); + filePathsScrollPane.setViewportView(filePathsTable); + if (filePathsTable.getColumnModel().getColumnCount() > 0) { + filePathsTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.filePathsTable.columnModel.title0")); // NOI18N + } + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 14; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.weighty = 1.2; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 10, 10); + jPanel1.add(filePathsScrollPane, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(dataSourceUsageValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.dataSourceUsageValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 10); + jPanel1.add(dataSourceUsageValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(timeZoneValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.timeZoneValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 6, 10); + jPanel1.add(timeZoneValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(imageTypeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.imageTypeValue.text")); // NOI18N + imageTypeValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.imageTypeValue.toolTipText")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 10); + jPanel1.add(imageTypeValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(md5HashValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.md5HashValue.text")); // NOI18N + md5HashValue.setToolTipText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.md5HashValue.toolTipText")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 11; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(md5HashValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sectorSizeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sectorSizeValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(sectorSizeValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sizeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sizeValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(sizeValue, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(filePathsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.filePathsLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weighty = 1.2; + gridBagConstraints.insets = new java.awt.Insets(6, 10, 10, 4); + jPanel1.add(filePathsLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sha256HashLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha256HashLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 6, 4); + jPanel1.add(sha256HashLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sha1HashLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sha1HashLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(sha1HashLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(md5HashLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.md5HashLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(md5HashLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sectorSizeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sectorSizeLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(sectorSizeLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(sizeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.sizeLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 8; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(sizeLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(imageTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.imageTypeLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(6, 10, 0, 4); + jPanel1.add(imageTypeLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(acquisitionDetailsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.acquisitionDetailsLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weighty = 0.6; + gridBagConstraints.insets = new java.awt.Insets(6, 10, 6, 4); + jPanel1.add(acquisitionDetailsLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.timeZoneLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 6, 4); + jPanel1.add(timeZoneLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(dataSourceUsageLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.dataSourceUsageLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(6, 10, 0, 4); + jPanel1.add(dataSourceUsageLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(deviceIdLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.deviceIdLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 6, 4); + jPanel1.add(deviceIdLabel, gridBagConstraints); + + acquisitionDetailsTextArea.setEditable(false); + acquisitionDetailsTextArea.setBackground(javax.swing.UIManager.getDefaults().getColor("TextArea.disabledBackground")); + acquisitionDetailsTextArea.setColumns(20); + acquisitionDetailsTextArea.setRows(4); + acquisitionDetailsTextArea.setText(org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.acquisitionDetailsTextArea.text")); // NOI18N + acquisitionDetailsTextArea.setBorder(null); + acquisitionDetailsScrollPane.setViewportView(acquisitionDetailsTextArea); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.weighty = 0.6; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 6, 10); + jPanel1.add(acquisitionDetailsScrollPane, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weighty = 0.1; + jPanel1.add(filler1, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 15; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weighty = 0.1; + jPanel1.add(filler2, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(unallocatedSizeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 9; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 4); + jPanel1.add(unallocatedSizeLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(unallocatedSizeValue, org.openide.util.NbBundle.getMessage(DataSourceSummaryDetailsPanel.class, "DataSourceSummaryDetailsPanel.unallocatedSizeValue.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 9; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + jPanel1.add(unallocatedSizeValue, gridBagConstraints); + + jScrollPane1.setViewportView(jPanel1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel acquisitionDetailsLabel; + private javax.swing.JScrollPane acquisitionDetailsScrollPane; + private javax.swing.JTextArea acquisitionDetailsTextArea; + private javax.swing.JLabel dataSourceUsageLabel; + private javax.swing.JLabel dataSourceUsageValue; + private javax.swing.JLabel deviceIdLabel; + private javax.swing.JLabel deviceIdValue; + private javax.swing.JLabel displayNameLabel; + private javax.swing.JLabel displayNameValue; + private javax.swing.JLabel filePathsLabel; + private javax.swing.JScrollPane filePathsScrollPane; + private javax.swing.JTable filePathsTable; + private javax.swing.Box.Filler filler1; + private javax.swing.Box.Filler filler2; + private javax.swing.JLabel imageTypeLabel; + private javax.swing.JLabel imageTypeValue; + private javax.swing.JPanel jPanel1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel md5HashLabel; + private javax.swing.JLabel md5HashValue; + private javax.swing.JLabel operatingSystemLabel; + private javax.swing.JLabel operatingSystemValue; + private javax.swing.JLabel originalNameLabel; + private javax.swing.JLabel originalNameValue; + private javax.swing.JLabel sectorSizeLabel; + private javax.swing.JLabel sectorSizeValue; + private javax.swing.JLabel sha1HashLabel; + private javax.swing.JLabel sha1HashValue; + private javax.swing.JLabel sha256HashLabel; + private javax.swing.JLabel sha256HashValue; + private javax.swing.JLabel sizeLabel; + private javax.swing.JLabel sizeValue; + private javax.swing.JLabel timeZoneLabel; + private javax.swing.JLabel timeZoneValue; + private javax.swing.JLabel unallocatedSizeLabel; + private javax.swing.JLabel unallocatedSizeValue; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form new file mode 100644 index 0000000000..72c45cb5a7 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.form @@ -0,0 +1,82 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java new file mode 100644 index 0000000000..3c68b7b3ed --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryDialog.java @@ -0,0 +1,178 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.awt.Frame; +import java.beans.PropertyChangeEvent; +import java.util.EnumSet; +import java.util.Map; +import java.util.Observable; +import java.util.Observer; +import java.util.Set; +import javax.swing.event.ListSelectionEvent; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel; +import org.sleuthkit.autopsy.ingest.IngestManager; +import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent; +import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.IngestJobInfo; + +/** + * Dialog for displaying the Data Sources Summary information + */ +final class DataSourceSummaryDialog extends javax.swing.JDialog implements Observer { + + private static final long serialVersionUID = 1L; + private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED); + private final DataSourceSummaryCountsPanel countsPanel; + private final DataSourceSummaryDetailsPanel detailsPanel; + private final DataSourceBrowser dataSourcesPanel; + private final IngestJobInfoPanel ingestHistoryPanel; + + /** + * Creates new form DataSourceSummaryDialog for displaying a summary of the + * data sources for the fcurrent case and the contents found for each + * datasource. + */ + @Messages({ + "DataSourceSummaryDialog.window.title=Data Sources Summary", + "DataSourceSummaryDialog.countsTab.title=Counts", + "DataSourceSummaryDialog.detailsTab.title=Details", + "DataSourceSummaryDialog.ingestHistoryTab.title=Ingest History" + }) + DataSourceSummaryDialog(Frame owner) { + super(owner, Bundle.DataSourceSummaryDialog_window_title(), true); + Map usageMap = DataSourceInfoUtilities.getDataSourceTypes(); + Map fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles(); + countsPanel = new DataSourceSummaryCountsPanel(fileCountsMap); + detailsPanel = new DataSourceSummaryDetailsPanel(usageMap); + dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap); + ingestHistoryPanel = new IngestJobInfoPanel(); + initComponents(); + dataSourceSummarySplitPane.setLeftComponent(dataSourcesPanel); + dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_detailsTab_title(), detailsPanel); + dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_countsTab_title(), countsPanel); + dataSourceTabbedPane.addTab(Bundle.DataSourceSummaryDialog_ingestHistoryTab_title(), ingestHistoryPanel); + dataSourcesPanel.addListSelectionListener((ListSelectionEvent e) -> { + if (!e.getValueIsAdjusting()) { + DataSource selectedDataSource = dataSourcesPanel.getSelectedDataSource(); + countsPanel.updateCountsTableData(selectedDataSource); + detailsPanel.updateDetailsPanelData(selectedDataSource); + ingestHistoryPanel.setDataSource(selectedDataSource); + this.repaint(); + } + }); + //add listener to refresh jobs with Started status when they complete + IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> { + if (evt instanceof DataSourceAnalysisCompletedEvent) { + DataSourceAnalysisCompletedEvent dsEvent = (DataSourceAnalysisCompletedEvent) evt; + if (dsEvent.getResult() == Reason.ANALYSIS_COMPLETED) { + dataSourcesPanel.refresh(dsEvent.getDataSource().getId(), IngestJobInfo.IngestJobStatusType.COMPLETED); + } else if (dsEvent.getResult() == Reason.ANALYSIS_CANCELLED) { + dataSourcesPanel.refresh(dsEvent.getDataSource().getId(), null); + } + } + }); + this.pack(); + } + + /** + * Make this dialog an observer of the DataSourcesPanel. + */ + void enableObserver() { + dataSourcesPanel.addObserver(this); + } + + @Override + public void update(Observable o, Object arg) { + this.dispose(); + } + + /** + * 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() { + + closeButton = new javax.swing.JButton(); + dataSourceSummarySplitPane = new javax.swing.JSplitPane(); + dataSourceTabbedPane = new javax.swing.JTabbedPane(); + + org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(DataSourceSummaryDialog.class, "DataSourceSummaryDialog.closeButton.text")); // NOI18N + closeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeButtonActionPerformed(evt); + } + }); + + dataSourceSummarySplitPane.setDividerLocation(130); + dataSourceSummarySplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + dataSourceSummarySplitPane.setRightComponent(dataSourceTabbedPane); + + dataSourceSummarySplitPane.setLeftComponent(dataSourcesPanel); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 668, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(closeButton))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(dataSourceSummarySplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(closeButton) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed + this.dispose(); + }//GEN-LAST:event_closeButtonActionPerformed + + /** + * Select the data source with the specicied data source id. If no data + * source matches the dataSourceID it will select the first datasource. + * + * @param dataSourceID the ID of the datasource to select, null will cause + * the first datasource to be selected + */ + void selectDataSource(Long dataSourceId) { + dataSourcesPanel.selectDataSource(dataSourceId); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton closeButton; + private javax.swing.JSplitPane dataSourceSummarySplitPane; + private javax.swing.JTabbedPane dataSourceTabbedPane; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java new file mode 100644 index 0000000000..0411d94bb2 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/DataSourceSummaryNode.java @@ -0,0 +1,216 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Observable; +import java.util.Observer; +import javax.swing.Action; +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.datamodel.NodeProperty; +import org.sleuthkit.autopsy.directorytree.ViewContextAction; +import org.sleuthkit.datamodel.DataSource; + +/** + * Root node for displaying DataSourceSummary information in the + * DataSourceBrowser + * + */ +final class DataSourceSummaryNode extends AbstractNode { + + private final static Observable closeDialogObservable = new Observable() { + @Override + public void notifyObservers() { + //set changed before notify observers + //we want this observerable to always cause the observer to update when notified + this.setChanged(); + super.notifyObservers(); + } + }; + + /** + * Construct a new DataSourceSummaryNode + * + * @param dataSourceList the list of DataSourceSummary objects representing + * DataSources which are this nodes children + */ + DataSourceSummaryNode(List dataSourceList) { + super(Children.create(new DataSourceSummaryChildren(dataSourceList), false)); + } + + /** + * Add an observer to the closeDialogObservable + * + * @param observer the observer to add + */ + void addObserver(Observer observer) { + closeDialogObservable.addObserver(observer); + } + + /** + * ChildFactory to create children of the DataSourceSummaryNode for each + * DataSourceSummary + */ + static final class DataSourceSummaryChildren extends ChildFactory { + + private final List dataSourceList; + + /** + * Construct a new DataSourceSummaryChildren object to create children + * for each DataSourceSummary object in the list + * + * @param dataSourceList the DataSourceSummary objects to create + * children for + */ + DataSourceSummaryChildren(List dataSourceList) { + this.dataSourceList = dataSourceList; + } + + @Override + protected boolean createKeys(List list) { + if (dataSourceList != null && !dataSourceList.isEmpty()) { + list.addAll(dataSourceList); + } + return true; + } + + @Override + protected Node createNodeForKey(DataSourceSummary key) { + return new DataSourceSummaryEntryNode(key); + } + } + + /** + * A node which represents a single DataSource. + */ + static final class DataSourceSummaryEntryNode extends AbstractNode { + + private final DataSource dataSource; + private final String status; + private final String type; + private final long filesCount; + private final long resultsCount; + private final long tagsCount; + + /** + * Constrcut a new DataSourceSummaryEntryNode + * + * @param dataSourceSummary the DataSourceSummary which is wrapping the + * DataSource which will be represented by this + * node. + */ + DataSourceSummaryEntryNode(DataSourceSummary dataSourceSummary) { + super(Children.LEAF); + dataSource = dataSourceSummary.getDataSource(); + status = dataSourceSummary.getIngestStatus() == null ? "" : dataSourceSummary.getIngestStatus().getDisplayName(); + type = dataSourceSummary.getType(); + filesCount = dataSourceSummary.getFilesCount(); + resultsCount = dataSourceSummary.getResultsCount(); + tagsCount = dataSourceSummary.getTagsCount(); + super.setName(dataSource.getName()); + setName(dataSource.getName()); + setDisplayName(dataSource.getName()); + } + + /** + * Get the DataSource being represented by this node. + * + * @return the DataSource which is represented by this node. + */ + DataSource getDataSource() { + return dataSource; + } + + @Messages({"DataSourceSummaryNode.column.dataSourceName.header=Data Source Name", + "DataSourceSummaryNode.column.status.header=Ingest Status", + "DataSourceSummaryNode.column.type.header=Type", + "DataSourceSummaryNode.column.files.header=Files", + "DataSourceSummaryNode.column.results.header=Results", + "DataSourceSummaryNode.column.tags.header=Tags"}) + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES); + if (sheetSet == null) { + sheetSet = Sheet.createPropertiesSet(); + sheet.put(sheetSet); + } + sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(), + dataSource)); + sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), status)); + sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), + type)); + sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), + filesCount)); + sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(), + resultsCount)); + sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header(), + tagsCount)); + return sheet; + } + + /** + * 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 ViewDataSourceInContextAction(); + } + + @Override + public Action[] getActions(boolean context) { + List actions = new ArrayList<>(); + actions.add(new ViewDataSourceInContextAction()); + return actions.toArray(new Action[actions.size()]); + } + + /** + * Action to navigate to this node's Data Source in the Results Viewer + * and close the DataSourceSummaryDialog. + */ + private class ViewDataSourceInContextAction extends ViewContextAction { + + private static final long serialVersionUID = 1L; + + /** + * Construct a new ViewDataSourceInCOntextAction + */ + @Messages({"DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source"}) + ViewDataSourceInContextAction() { + super(Bundle.DataSourceSummaryNode_viewDataSourceAction_text(), dataSource); + } + + @Override + public void actionPerformed(ActionEvent e) { + closeDialogObservable.notifyObservers(); + super.actionPerformed(e); + } + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java new file mode 100644 index 0000000000..12f111bba2 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/RightAlignedTableCellRenderer.java @@ -0,0 +1,61 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.awt.Component; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JTable; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.autopsy.guiutils.GrayableCellRenderer; + +/** + * Cell Renderer which extends grayable cell renderer to inherit highlighting + * but right aligns the contents will display the value of the cell or if the + * cell contains a NodeProperty the value of that NodeProperty sets text to + * empty string if null. + */ +final class RightAlignedTableCellRenderer extends GrayableCellRenderer { + + private static final long serialVersionUID = 1L; + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setHorizontalAlignment(RIGHT); + Object cellContents = null; + if ((value instanceof NodeProperty)) { + //The Outline view has properties in the cell, the value contained in the property is what we want + try { + cellContents = ((Node.Property) value).getValue(); + } catch (IllegalAccessException | InvocationTargetException ex) { + //Unable to get the value from the NodeProperty cell will appear empty + } + } else { + //JTables contain the value we want directly in the cell + cellContents = value; + } + if (null != cellContents) { + setText(cellContents.toString()); + } else { + setText(""); + } + grayCellIfTableNotEnabled(table, isSelected); + return this; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java new file mode 100644 index 0000000000..babe2197a1 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/datasourcesummary/ViewSummaryInformationAction.java @@ -0,0 +1,67 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 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.datasourcesummary; + +import java.awt.Frame; +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.SwingUtilities; +import org.openide.util.NbBundle.Messages; +import org.openide.windows.WindowManager; + +/** + * ViewSummaryInformationAction action for opening a Data Sources Summary Dialog + * with the specified data source selected if it is present. + */ +public final class ViewSummaryInformationAction extends AbstractAction { + + private static DataSourceSummaryDialog dataSourceSummaryDialog; + private static Long selectDataSource; + private static final long serialVersionUID = 1L; + + /** + * Create a ViewSummaryInformationAction for the selected datasource. + * + * @param selectedDataSource - the data source which is currently selected + and will be selected initially when the + DataSourceSummaryDialog opens. + */ + @Messages({"ViewSummaryInformationAction.name.text=View Summary Information"}) + public ViewSummaryInformationAction(Long selectedDataSource) { + super(Bundle.ViewSummaryInformationAction_name_text()); + selectDataSource = selectedDataSource; + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + SwingUtilities.invokeLater(() -> { + Frame mainWindow = WindowManager.getDefault().getMainWindow(); + dataSourceSummaryDialog = new DataSourceSummaryDialog(mainWindow); + //allow dialog to be closed when actions performed + dataSourceSummaryDialog.enableObserver(); + //select the specifed data source + dataSourceSummaryDialog.selectDataSource(selectDataSource); + dataSourceSummaryDialog.setResizable(true); + dataSourceSummaryDialog.setLocationRelativeTo(mainWindow); + dataSourceSummaryDialog.setVisible(true); + dataSourceSummaryDialog.toFront(); + }); + } + +}