Autopsy  4.19.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
IngestJobInfoPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2016-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  */
19 package org.sleuthkit.autopsy.casemodule;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.text.DateFormat;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.EnumSet;
27 import java.util.List;
28 import java.util.Set;
29 import java.util.concurrent.CancellationException;
30 import java.util.concurrent.ExecutionException;
31 import java.util.logging.Level;
32 import javax.swing.JOptionPane;
33 import javax.swing.SwingWorker;
34 import javax.swing.event.ListSelectionEvent;
35 import javax.swing.table.AbstractTableModel;
36 import org.openide.util.NbBundle.Messages;
41 import org.sleuthkit.datamodel.IngestJobInfo;
42 import org.sleuthkit.datamodel.IngestModuleInfo;
43 import org.sleuthkit.datamodel.SleuthkitCase;
44 import org.sleuthkit.datamodel.TskCoreException;
45 import org.sleuthkit.datamodel.DataSource;
46 
50 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
51 public final class IngestJobInfoPanel extends javax.swing.JPanel {
52 
53  private static final Logger logger = Logger.getLogger(IngestJobInfoPanel.class.getName());
55  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE);
56  private static final int EXTRA_ROW_HEIGHT = 4;
57  private final List<IngestJobInfo> ingestJobs = new ArrayList<>();
58  private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>();
59  private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
60  private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null);
61  private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
62  private DataSource selectedDataSource;
63  private static SwingWorker<Boolean, Void> refreshWorker = null;
64 
68  public IngestJobInfoPanel() {
69  initComponents();
70  customizeComponents();
71  }
72 
73  @Messages({"IngestJobInfoPanel.loadIngestJob.error.text=Failed to load ingest jobs.",
74  "IngestJobInfoPanel.loadIngestJob.error.title=Load Failure"})
75  private void customizeComponents() {
76  refresh();
77  this.ingestJobTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
78  IngestJobInfo currJob = (ingestJobTable.getSelectedRow() < 0 ? null : this.ingestJobsForSelectedDataSource.get(ingestJobTable.getSelectedRow()));
79  this.ingestModuleTableModel = new IngestModuleTableModel(currJob);
80  this.ingestModuleTable.setModel(this.ingestModuleTableModel);
81  });
82 
83  IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
84  if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString())
85  || evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString())
86  || evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) {
87  refresh();
88  }
89  });
90 
91  Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
92  if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
93  return;
94  }
95 
96  // Check whether we have a case open or case close event.
97  if ((CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName()))) {
98  if (evt.getNewValue() != null) {
99  // Case open
100  refresh();
101  } else {
102  // Case close
103  reset();
104  }
105  }
106  });
107  ingestJobTable.setRowHeight(ingestJobTable.getRowHeight() + EXTRA_ROW_HEIGHT);
108  ingestModuleTable.setRowHeight(ingestModuleTable.getRowHeight() + EXTRA_ROW_HEIGHT);
109 
110  }
111 
117  public void setDataSource(DataSource selectedDataSource) {
118  this.selectedDataSource = selectedDataSource;
119  ingestJobsForSelectedDataSource.clear();
120  if (selectedDataSource != null) {
121  for (IngestJobInfo jobInfo : ingestJobs) {
122  if (selectedDataSource.getId() == jobInfo.getObjectId()) {
123  ingestJobsForSelectedDataSource.add(jobInfo);
124  }
125  }
126  }
127  this.ingestJobTableModel = new IngestJobTableModel();
128  this.ingestJobTable.setModel(ingestJobTableModel);
129  //if there were ingest jobs select the first one by default
130  if (!ingestJobsForSelectedDataSource.isEmpty()) {
131  ingestJobTable.setRowSelectionInterval(0, 0);
132  }
133  this.repaint();
134  }
135 
139  private void refresh() {
140  if (refreshWorker != null && !refreshWorker.isDone()) {
141  refreshWorker.cancel(true);
142  }
143  refreshWorker = new SwingWorker<Boolean, Void>() {
144 
145  @Override
146  protected Boolean doInBackground() throws Exception {
147  ingestJobs.clear();
148  try {
149  if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
150  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
151  ingestJobs.addAll(skCase.getIngestJobs());
152  setDataSource(selectedDataSource);
153  } else {
154  setDataSource(null);
155  }
156  return true;
157  } catch (TskCoreException | NoCurrentCaseException ex) {
158  logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
159  return false;
160  }
161  }
162 
163  @Override
164  protected void done() {
165  try {
166  if (!get()) {
167  JOptionPane.showMessageDialog(IngestJobInfoPanel.this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
168  }
169  } catch (InterruptedException | ExecutionException ex) {
170  logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex);
171  } catch (CancellationException ignored){
172  logger.log(Level.INFO, "The refreshing of the IngestJobInfoPanel was cancelled");
173  }
174  }
175  };
176  refreshWorker.execute();
177  }
178 
182  private void reset() {
183  if (refreshWorker != null) {
184  refreshWorker.cancel(true);
185  }
186  this.ingestJobs.clear();
187  setDataSource(null);
188  }
189 
190  @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",
191  "IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time",
192  "IngestJobInfoPanel.IngestJobTableModel.IngestStatus.header=Ingest Status"})
193  private class IngestJobTableModel extends AbstractTableModel {
194 
195  private final List<String> columnHeaders = new ArrayList<>();
196 
198  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_StartTime_header());
199  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_EndTime_header());
200  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_IngestStatus_header());
201  }
202 
203  @Override
204  public int getRowCount() {
205  return ingestJobsForSelectedDataSource.size();
206  }
207 
208  @Override
209  public int getColumnCount() {
210  return columnHeaders.size();
211  }
212 
213  @Override
214  public Object getValueAt(int rowIndex, int columnIndex) {
215  IngestJobInfo currIngestJob = ingestJobsForSelectedDataSource.get(rowIndex);
216  if (columnIndex == 0) {
217  return datetimeFormat.format(currIngestJob.getStartDateTime());
218  } else if (columnIndex == 1) {
219  Date endDate = currIngestJob.getEndDateTime();
220  if (endDate.getTime() == 0) {
221  return "N/A";
222  }
223  return datetimeFormat.format(currIngestJob.getEndDateTime());
224  } else if (columnIndex == 2) {
225  return currIngestJob.getStatus().getDisplayName();
226  }
227  return null;
228  }
229 
230  @Override
231  public String getColumnName(int column) {
232  return columnHeaders.get(column);
233  }
234 
235  }
236 
237  @Messages({"IngestJobInfoPanel.IngestModuleTableModel.ModuleName.header=Module Name",
238  "IngestJobInfoPanel.IngestModuleTableModel.ModuleVersion.header=Module Version"})
239  private class IngestModuleTableModel extends AbstractTableModel {
240 
241  private final List<String> columnHeaders = new ArrayList<>();
242  private final IngestJobInfo currJob;
243 
244  IngestModuleTableModel(IngestJobInfo currJob) {
245  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleName_header());
246  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleVersion_header());
247  this.currJob = currJob;
248  }
249 
250  @Override
251  public int getRowCount() {
252  if (currJob == null) {
253  return 0;
254  }
255  return currJob.getIngestModuleInfo().size();
256  }
257 
258  @Override
259  public int getColumnCount() {
260  return columnHeaders.size();
261  }
262 
263  @Override
264  public Object getValueAt(int rowIndex, int columnIndex) {
265  if (currJob != null) {
266  IngestModuleInfo currIngestModule = currJob.getIngestModuleInfo().get(rowIndex);
267  if (columnIndex == 0) {
268  return currIngestModule.getDisplayName();
269  } else if (columnIndex == 1) {
270  return currIngestModule.getVersion();
271  }
272  return null;
273  }
274  return null;
275  }
276 
277  @Override
278  public String getColumnName(int column) {
279  return columnHeaders.get(column);
280  }
281 
282  }
283 
289  @SuppressWarnings("unchecked")
290  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
291  private void initComponents() {
292  java.awt.GridBagConstraints gridBagConstraints;
293 
294  javax.swing.JScrollPane mainScrollPane = new javax.swing.JScrollPane();
295  javax.swing.JPanel contentPanel = new javax.swing.JPanel();
296  javax.swing.JScrollPane ingestJobsScrollPane = new javax.swing.JScrollPane();
297  ingestJobTable = new javax.swing.JTable();
298  javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
299  javax.swing.JLabel jLabel2 = new javax.swing.JLabel();
300  javax.swing.JScrollPane ingestModulesScrollPane = new javax.swing.JScrollPane();
301  ingestModuleTable = new javax.swing.JTable();
302 
303  setLayout(new java.awt.BorderLayout());
304 
305  contentPanel.setMinimumSize(new java.awt.Dimension(625, 150));
306  contentPanel.setPreferredSize(new java.awt.Dimension(625, 150));
307  contentPanel.setLayout(new java.awt.GridBagLayout());
308 
309  ingestJobsScrollPane.setBorder(null);
310  ingestJobsScrollPane.setMinimumSize(new java.awt.Dimension(16, 16));
311 
312  ingestJobTable.setModel(ingestJobTableModel);
313  ingestJobTable.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
314  ingestJobTable.setIntercellSpacing(new java.awt.Dimension(4, 2));
315  ingestJobTable.getTableHeader().setReorderingAllowed(false);
316  ingestJobsScrollPane.setViewportView(ingestJobTable);
317  ingestJobTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
318 
319  gridBagConstraints = new java.awt.GridBagConstraints();
320  gridBagConstraints.gridx = 0;
321  gridBagConstraints.gridy = 1;
322  gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
323  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
324  gridBagConstraints.weightx = 1.0;
325  gridBagConstraints.weighty = 1.0;
326  gridBagConstraints.insets = new java.awt.Insets(2, 10, 10, 0);
327  contentPanel.add(ingestJobsScrollPane, gridBagConstraints);
328 
329  org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel1.text")); // NOI18N
330  gridBagConstraints = new java.awt.GridBagConstraints();
331  gridBagConstraints.gridx = 1;
332  gridBagConstraints.gridy = 0;
333  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
334  gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
335  contentPanel.add(jLabel1, gridBagConstraints);
336 
337  org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel2.text")); // NOI18N
338  gridBagConstraints = new java.awt.GridBagConstraints();
339  gridBagConstraints.gridx = 0;
340  gridBagConstraints.gridy = 0;
341  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
342  gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
343  contentPanel.add(jLabel2, gridBagConstraints);
344 
345  ingestModulesScrollPane.setMaximumSize(new java.awt.Dimension(254, 32767));
346  ingestModulesScrollPane.setMinimumSize(new java.awt.Dimension(254, 16));
347  ingestModulesScrollPane.setPreferredSize(new java.awt.Dimension(254, 16));
348 
349  ingestModuleTable.setModel(ingestModuleTableModel);
350  ingestModuleTable.setGridColor(javax.swing.UIManager.getDefaults().getColor("InternalFrame.borderColor"));
351  ingestModuleTable.setIntercellSpacing(new java.awt.Dimension(4, 2));
352  ingestModulesScrollPane.setViewportView(ingestModuleTable);
353 
354  gridBagConstraints = new java.awt.GridBagConstraints();
355  gridBagConstraints.gridx = 1;
356  gridBagConstraints.gridy = 1;
357  gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
358  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
359  gridBagConstraints.weighty = 1.0;
360  gridBagConstraints.insets = new java.awt.Insets(2, 8, 10, 10);
361  contentPanel.add(ingestModulesScrollPane, gridBagConstraints);
362 
363  mainScrollPane.setViewportView(contentPanel);
364 
365  add(mainScrollPane, java.awt.BorderLayout.CENTER);
366  }// </editor-fold>//GEN-END:initComponents
367 
368 
369  // Variables declaration - do not modify//GEN-BEGIN:variables
370  private javax.swing.JTable ingestJobTable;
371  private javax.swing.JTable ingestModuleTable;
372  // End of variables declaration//GEN-END:variables
373 }
static synchronized IngestManager getInstance()
void addIngestJobEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:711

Copyright © 2012-2021 Basis Technology. Generated on: Fri Aug 6 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.