Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
DataSourceBrowser.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2019-2021 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.datasourcesummary.ui;
20
21import org.sleuthkit.autopsy.datasourcesummary.datamodel.CaseDataSourcesSummary;
22import java.awt.Cursor;
23import org.sleuthkit.autopsy.datasourcesummary.uiutils.RightAlignedTableCellRenderer;
24import java.awt.EventQueue;
25import java.beans.PropertyVetoException;
26import javax.swing.ListSelectionModel;
27import org.netbeans.swing.outline.DefaultOutlineModel;
28import org.netbeans.swing.outline.Outline;
29import org.openide.explorer.ExplorerManager;
30import java.util.ArrayList;
31import java.util.Collections;
32import java.util.List;
33import java.util.Map;
34import java.util.Observer;
35import java.util.logging.Level;
36import org.sleuthkit.autopsy.coreutils.Logger;
37import javax.swing.event.ListSelectionListener;
38import org.openide.nodes.Node;
39import org.sleuthkit.autopsy.casemodule.Case;
40import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
41import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryNode.DataSourceSummaryEntryNode;
42import static javax.swing.SwingConstants.RIGHT;
43import javax.swing.SwingUtilities;
44import javax.swing.SwingWorker;
45import javax.swing.table.TableColumn;
46import org.sleuthkit.datamodel.DataSource;
47import org.sleuthkit.datamodel.IngestJobInfo;
48import org.sleuthkit.datamodel.SleuthkitCase;
49import org.sleuthkit.datamodel.TskCoreException;
50
55final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerManager.Provider {
56
57 private static final long serialVersionUID = 1L;
58 private static final Logger logger = Logger.getLogger(DataSourceBrowser.class.getName());
59 private static final int COUNT_COLUMN_WIDTH = 20;
60 private static final int INGEST_STATUS_WIDTH = 50;
61 private static final int USAGE_COLUMN_WIDTH = 110;
62 private static final int DATA_SOURCE_COLUMN_WIDTH = 280;
63 private final Outline outline;
64 private final org.openide.explorer.view.OutlineView outlineView;
65 private final ExplorerManager explorerManager;
66 private final List<DataSourceSummary> dataSourceSummaryList;
67 private final RightAlignedTableCellRenderer rightAlignedRenderer = new RightAlignedTableCellRenderer();
68 private SwingWorker<Void, Void> rootNodeWorker = null;
69
73 DataSourceBrowser() {
74 initComponents();
75 rightAlignedRenderer.setHorizontalAlignment(RIGHT);
76 explorerManager = new ExplorerManager();
77 outlineView = new org.openide.explorer.view.OutlineView();
78 this.setVisible(true);
79 outlineView.setPropertyColumns(
80 Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(),
81 Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(),
82 Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(),
83 Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(),
84 Bundle.DataSourceSummaryNode_column_tags_header(), Bundle.DataSourceSummaryNode_column_tags_header());
85 outline = outlineView.getOutline();
86 outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
87 dataSourceSummaryList = new ArrayList<>();
88 outline.setRootVisible(false);
89 add(outlineView, java.awt.BorderLayout.CENTER);
90 ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.DataSourceSummaryNode_column_dataSourceName_header());
91 for (TableColumn column : Collections.list(outline.getColumnModel().getColumns())) {
92 if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_files_header())
93 || column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_results_header())
94 || column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_tags_header())) {
95 column.setCellRenderer(rightAlignedRenderer);
96 column.setPreferredWidth(COUNT_COLUMN_WIDTH);
97 } else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_type_header())) {
98 column.setPreferredWidth(USAGE_COLUMN_WIDTH);
99 } else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_status_header())) {
100 column.setPreferredWidth(INGEST_STATUS_WIDTH);
101 } else {
102 column.setPreferredWidth(DATA_SOURCE_COLUMN_WIDTH);
103 }
104 }
105 this.setVisible(true);
106 }
107
116 void selectDataSource(Long dataSourceId) {
117 EventQueue.invokeLater(() -> {
118 if (dataSourceId != null) {
119 for (Node node : explorerManager.getRootContext().getChildren().getNodes()) {
120 if (node instanceof DataSourceSummaryEntryNode && ((DataSourceSummaryEntryNode) node).getDataSource().getId() == dataSourceId) {
121 try {
122 explorerManager.setExploredContextAndSelection(node, new Node[]{node});
123 return;
124 } catch (PropertyVetoException ex) {
125 logger.log(Level.WARNING, "Failed to select the datasource in the explorer view", ex); //NON-NLS
126 }
127 }
128 }
129 }
130 //if no data source was selected and there are data sources to select select the first one
131 if (explorerManager.getRootContext().getChildren().getNodes().length > 0) {
132 outline.getSelectionModel().setSelectionInterval(0, 0);
133 }
134 });
135 }
136
143 void addObserver(Observer observer) {
144 ((DataSourceSummaryNode) explorerManager.getRootContext()).addObserver(observer);
145 }
146
154 private List<DataSourceSummary> getDataSourceSummaryList(Map<Long, String> usageMap, Map<Long, Long> fileCountsMap) {
155 List<DataSourceSummary> summaryList = new ArrayList<>();
156
157 final Map<Long, Long> artifactCountsMap = CaseDataSourcesSummary.getCountsOfArtifacts();
158 final Map<Long, Long> tagCountsMap = CaseDataSourcesSummary.getCountsOfTags();
159 try {
160 SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
161 for (DataSource dataSource : skCase.getDataSources()) {
162 summaryList.add(new DataSourceSummary(dataSource, usageMap.get(dataSource.getId()),
163 fileCountsMap.get(dataSource.getId()), artifactCountsMap.get(dataSource.getId()), tagCountsMap.get(dataSource.getId())));
164 }
165 } catch (TskCoreException | NoCurrentCaseException ex) {
166 logger.log(Level.WARNING, "Unable to datasources or their counts, providing empty results", ex);
167 }
168 return summaryList;
169 }
170
176 void addListSelectionListener(ListSelectionListener listener) {
177 outline.getSelectionModel().addListSelectionListener(listener);
178 }
179
185 DataSource getSelectedDataSource() {
186 Node selectedNode[] = explorerManager.getSelectedNodes();
187 if (selectedNode.length == 1 && selectedNode[0] instanceof DataSourceSummaryEntryNode) {
188 return ((DataSourceSummaryEntryNode) selectedNode[0]).getDataSource();
189 }
190 return null;
191 }
192
200 void refresh(long dataSourceId, IngestJobInfo.IngestJobStatusType newStatus) {
201
202 //attempt to update the status of any datasources that had status which was STARTED
203 for (DataSourceSummary summary : dataSourceSummaryList) {
204 if (summary.getDataSource().getId() == dataSourceId) {
205 summary.setIngestStatus(newStatus);
206 }
207 }
208 //figure out which nodes were previously selected
209 Node[] selectedNodes = explorerManager.getSelectedNodes();
210 SwingUtilities.invokeLater(() -> {
211 explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList));
212 List<Node> nodesToSelect = new ArrayList<>();
213 for (Node node : explorerManager.getRootContext().getChildren().getNodes()) {
214 if (node instanceof DataSourceSummaryEntryNode) {
215 //there should only be one selected node as multi-select is disabled
216 for (Node selectedNode : selectedNodes) {
217 if (((DataSourceSummaryEntryNode) node).getDataSource().equals(((DataSourceSummaryEntryNode) selectedNode).getDataSource())) {
218 nodesToSelect.add(node);
219 }
220 }
221 }
222 }
223 //reselect the previously selected Nodes
224 try {
225 explorerManager.setSelectedNodes(nodesToSelect.toArray(new Node[nodesToSelect.size()]));
226 } catch (PropertyVetoException ex) {
227 logger.log(Level.WARNING, "Error selecting previously selected nodes", ex);
228 }
229
230 });
231
232 }
233
239 @SuppressWarnings("unchecked")
240 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
241 private void initComponents() {
242
243 setLayout(new java.awt.BorderLayout());
244 }// </editor-fold>//GEN-END:initComponents
245
246 @Override
247 public ExplorerManager getExplorerManager() {
248 return explorerManager;
249 }
250
260 void populateBrowser(DataSourceSummaryDialog dsSummaryDialog, Long selectedDataSourceId) {
261 dsSummaryDialog.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
262 if (rootNodeWorker != null && !rootNodeWorker.isDone()) {
263 rootNodeWorker.cancel(true);
264 }
265
266 dataSourceSummaryList.clear();
267 rootNodeWorker = new SwingWorker<Void, Void>() {
268 @Override
269 protected Void doInBackground() throws Exception {
270 Map<Long, String> usageMap = CaseDataSourcesSummary.getDataSourceTypes();
271 Map<Long, Long> fileCountsMap = CaseDataSourcesSummary.getCountsOfFiles();
272 dataSourceSummaryList.addAll(getDataSourceSummaryList(usageMap, fileCountsMap));
273 return null;
274 }
275
276 @Override
277 protected void done() {
278 explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList));
279 selectDataSource(selectedDataSourceId);
280 addObserver(dsSummaryDialog);
281 dsSummaryDialog.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
282 }
283 };
284 rootNodeWorker.execute();
285 }
286
291 void cancel() {
292 if (rootNodeWorker != null && !rootNodeWorker.isDone()) {
293 rootNodeWorker.cancel(true);
294 }
295 }
296
297 // Variables declaration - do not modify//GEN-BEGIN:variables
298 // End of variables declaration//GEN-END:variables
299}

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.