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