Autopsy  4.9.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
CaseBrowser.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2017-2018 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  */
19 package org.sleuthkit.autopsy.casemodule;
20 
21 import java.lang.reflect.InvocationTargetException;
22 import javax.swing.ListSelectionModel;
23 import javax.swing.event.ListSelectionListener;
24 import javax.swing.table.TableColumnModel;
25 import org.netbeans.swing.etable.ETableColumn;
26 import org.netbeans.swing.etable.ETableColumnModel;
27 import org.netbeans.swing.outline.DefaultOutlineModel;
28 import org.netbeans.swing.outline.Outline;
29 import org.openide.nodes.Node;
30 import java.awt.EventQueue;
31 import java.io.File;
32 import java.io.IOException;
33 import java.nio.file.LinkOption;
34 import java.nio.file.Path;
35 import java.nio.file.Paths;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.logging.Level;
39 import javax.swing.SwingWorker;
40 import org.openide.explorer.ExplorerManager;
41 import org.openide.util.NbBundle;
45 
53 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
54 class CaseBrowser extends javax.swing.JPanel implements ExplorerManager.Provider {
55 
56  private static final long serialVersionUID = 1L;
57  private final Outline outline;
58  private ExplorerManager em;
59  private final org.openide.explorer.view.OutlineView outlineView;
60  private int originalPathColumnIndex = 0;
61  private static final Logger LOGGER = Logger.getLogger(CaseBrowser.class.getName());
62  private LoadCaseListWorker tableWorker;
63 
64  @Override
65  public ExplorerManager getExplorerManager() {
66  return em;
67  }
68 
72  CaseBrowser() {
73  outlineView = new org.openide.explorer.view.OutlineView();
74  initComponents();
75 
76  outline = outlineView.getOutline();
77  outlineView.setPropertyColumns(
78  Bundle.CaseNode_column_createdTime(), Bundle.CaseNode_column_createdTime(),
79  Bundle.CaseNode_column_metadataFilePath(), Bundle.CaseNode_column_metadataFilePath());
80  ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel(Bundle.CaseNode_column_name());
81  customize();
82 
83  }
84 
88  private void customize() {
89  outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
90  TableColumnModel columnModel = outline.getColumnModel();
91  int dateColumnIndex = 0;
92  for (int index = 0; index < columnModel.getColumnCount(); index++) {
93  //get indexes for created date column and path column
94  if (columnModel.getColumn(index).getHeaderValue().toString().equals(Bundle.CaseNode_column_metadataFilePath())) {
95  originalPathColumnIndex = index;
96  } else if (columnModel.getColumn(index).getHeaderValue().toString().equals(Bundle.CaseNode_column_createdTime())) {
97  dateColumnIndex = index;
98  }
99  }
100  //Hide path column by default (user can unhide it)
101  ETableColumn column = (ETableColumn) columnModel.getColumn(originalPathColumnIndex);
102  ((ETableColumnModel) columnModel).setColumnHidden(column, true);
103  outline.setRootVisible(false);
104 
105  //Sort on Created date column in descending order by default
106  outline.setColumnSorted(dateColumnIndex, false, 1);
107  if (null == em) {
108  em = new ExplorerManager();
109  }
110  caseTableScrollPane.setViewportView(outlineView);
111  this.setVisible(true);
112  outline.setRowSelectionAllowed(false);
113  }
114 
120  void addListSelectionListener(ListSelectionListener listener) {
121  outline.getSelectionModel().addListSelectionListener(listener);
122  }
123 
129  String getCasePath() {
130  int[] selectedRows = outline.getSelectedRows();
131  if (selectedRows.length == 1) {
132  try {
133  return ((Node.Property) outline.getModel().getValueAt(outline.convertRowIndexToModel(selectedRows[0]), originalPathColumnIndex)).getValue().toString();
134  } catch (IllegalAccessException | InvocationTargetException ex) {
135  LOGGER.log(Level.SEVERE, "Unable to get case path from table.", ex);
136  }
137  }
138  return null;
139  }
140 
146  boolean isRowSelected() {
147  return outline.getRowSelectionAllowed() && outline.getSelectedRows().length > 0;
148  }
149 
150  @NbBundle.Messages({"CaseBrowser.caseListLoading.message=Please Wait..."})
155  void refresh() {
156  if (tableWorker == null || tableWorker.isDone()) {
157  outline.setRowSelectionAllowed(false);
158  //create a new TableWorker to and execute it in a background thread if one is not currently working
159  //set the table to display text informing the user that the list is being retreived and disable case selection
160  EmptyNode emptyNode = new EmptyNode(Bundle.CaseBrowser_caseListLoading_message());
161  em.setRootContext(emptyNode);
162  tableWorker = new LoadCaseListWorker();
163  tableWorker.execute();
164  }
165 
166  }
167 
173  @SuppressWarnings("unchecked")
174  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
175  private void initComponents() {
176 
177  caseTableScrollPane = new javax.swing.JScrollPane();
178 
179  setMinimumSize(new java.awt.Dimension(0, 5));
180  setPreferredSize(new java.awt.Dimension(5, 5));
181  setLayout(new java.awt.BorderLayout());
182 
183  caseTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
184  caseTableScrollPane.setMinimumSize(new java.awt.Dimension(0, 5));
185  caseTableScrollPane.setOpaque(false);
186  caseTableScrollPane.setPreferredSize(new java.awt.Dimension(5, 5));
187  add(caseTableScrollPane, java.awt.BorderLayout.CENTER);
188  }// </editor-fold>//GEN-END:initComponents
189  // Variables declaration - do not modify//GEN-BEGIN:variables
190  private javax.swing.JScrollPane caseTableScrollPane;
191  // End of variables declaration//GEN-END:variables
192 
196  private class LoadCaseListWorker extends SwingWorker<Void, Void> {
197 
198  private List<CaseMetadata> cases;
199 
207  private List<CaseMetadata> getCases() throws CoordinationService.CoordinationServiceException {
208  List<CaseMetadata> caseList = new ArrayList<>();
210 
211  for (String node : nodeList) {
212  Path casePath;
213  try {
214  casePath = Paths.get(node).toRealPath(LinkOption.NOFOLLOW_LINKS);
215 
216  File caseFolder = casePath.toFile();
217  if (caseFolder.exists()) {
218  /*
219  * Search for '*.aut' files.
220  */
221  File[] fileArray = caseFolder.listFiles();
222  if (fileArray == null) {
223  continue;
224  }
225  String autFilePath = null;
226  for (File file : fileArray) {
227  String name = file.getName().toLowerCase();
228  if (autFilePath == null && name.endsWith(".aut")) {
229  try {
230  caseList.add(new CaseMetadata(Paths.get(file.getAbsolutePath())));
231  } catch (CaseMetadata.CaseMetadataException ex) {
232  LOGGER.log(Level.SEVERE, String.format("Error reading case metadata file '%s'.", autFilePath), ex);
233  }
234  break;
235  }
236  }
237  }
238  } catch (IOException ignore) {
239  //if a path could not be resolved to a real path do add it to the caseList
240  }
241  }
242  return caseList;
243  }
244 
245  @Override
246  protected Void doInBackground() throws Exception {
247 
248  try {
249  cases = getCases();
251  LOGGER.log(Level.SEVERE, "Unexpected exception while refreshing the table.", ex); //NON-NLS
252  }
253  return null;
254  }
255 
256  @Override
257  protected void done() {
258  EventQueue.invokeLater(() -> {
259  MultiUserNode caseListNode = new MultiUserNode(cases);
260  em.setRootContext(caseListNode);
261  outline.setRowSelectionAllowed(true);
262  });
263  }
264  }
265 }

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.