Autopsy  4.17.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-2019 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.logging.Level;
30 import javax.swing.JOptionPane;
31 import javax.swing.event.ListSelectionEvent;
32 import javax.swing.table.AbstractTableModel;
33 import org.openide.util.NbBundle.Messages;
38 import org.sleuthkit.datamodel.IngestJobInfo;
39 import org.sleuthkit.datamodel.IngestModuleInfo;
40 import org.sleuthkit.datamodel.SleuthkitCase;
41 import org.sleuthkit.datamodel.TskCoreException;
42 import org.sleuthkit.datamodel.DataSource;
43 
47 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
48 public final class IngestJobInfoPanel extends javax.swing.JPanel {
49 
50  private static final Logger logger = Logger.getLogger(IngestJobInfoPanel.class.getName());
52  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE);
53 
54  private List<IngestJobInfo> ingestJobs;
55  private final List<IngestJobInfo> ingestJobsForSelectedDataSource = new ArrayList<>();
56  private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
57  private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null);
58  private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
59  private DataSource selectedDataSource;
60 
64  public IngestJobInfoPanel() {
65  initComponents();
66  customizeComponents();
67  }
68 
69  @Messages({"IngestJobInfoPanel.loadIngestJob.error.text=Failed to load ingest jobs.",
70  "IngestJobInfoPanel.loadIngestJob.error.title=Load Failure"})
71  private void customizeComponents() {
72  refresh();
73  this.ingestJobTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
74  IngestJobInfo currJob = (ingestJobTable.getSelectedRow() < 0 ? null : this.ingestJobsForSelectedDataSource.get(ingestJobTable.getSelectedRow()));
75  this.ingestModuleTableModel = new IngestModuleTableModel(currJob);
76  this.ingestModuleTable.setModel(this.ingestModuleTableModel);
77  });
78 
79  IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST , (PropertyChangeEvent evt) -> {
80  if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString())
81  || evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString())
82  || evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) {
83  refresh();
84  }
85  });
86 
87  Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, (PropertyChangeEvent evt) -> {
88  if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
89  return;
90  }
91 
92  // Check whether we have a case open or case close event.
93  if ((CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName()))) {
94  if (evt.getNewValue() != null) {
95  // Case open
96  refresh();
97  } else {
98  // Case close
99  reset();
100  }
101  }
102  });
103  }
104 
110  public void setDataSource(DataSource selectedDataSource) {
111  this.selectedDataSource = selectedDataSource;
112  ingestJobsForSelectedDataSource.clear();
113  if (selectedDataSource != null) {
114  for (IngestJobInfo jobInfo : ingestJobs) {
115  if (selectedDataSource.getId() == jobInfo.getObjectId()) {
116  ingestJobsForSelectedDataSource.add(jobInfo);
117  }
118  }
119  }
120  this.ingestJobTableModel = new IngestJobTableModel();
121  this.ingestJobTable.setModel(ingestJobTableModel);
122  //if there were ingest jobs select the first one by default
123  if (!ingestJobsForSelectedDataSource.isEmpty()) {
124  ingestJobTable.setRowSelectionInterval(0, 0);
125  }
126  this.repaint();
127  }
128 
132  private void refresh() {
133  try {
134  if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
135  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
136  this.ingestJobs = skCase.getIngestJobs();
137  setDataSource(selectedDataSource);
138  } else {
139  this.ingestJobs = new ArrayList<>();
140  setDataSource(null);
141  }
142 
143  } catch (TskCoreException | NoCurrentCaseException ex) {
144  logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
145  JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
146  }
147  }
148 
152  private void reset() {
153  this.ingestJobs = new ArrayList<>();
154  setDataSource(null);
155  }
156 
157  @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",
158  "IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time",
159  "IngestJobInfoPanel.IngestJobTableModel.IngestStatus.header=Ingest Status"})
160  private class IngestJobTableModel extends AbstractTableModel {
161 
162  private final List<String> columnHeaders = new ArrayList<>();
163 
165  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_StartTime_header());
166  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_EndTime_header());
167  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_IngestStatus_header());
168  }
169 
170  @Override
171  public int getRowCount() {
172  return ingestJobsForSelectedDataSource.size();
173  }
174 
175  @Override
176  public int getColumnCount() {
177  return columnHeaders.size();
178  }
179 
180  @Override
181  public Object getValueAt(int rowIndex, int columnIndex) {
182  IngestJobInfo currIngestJob = ingestJobsForSelectedDataSource.get(rowIndex);
183  if (columnIndex == 0) {
184  return datetimeFormat.format(currIngestJob.getStartDateTime());
185  } else if (columnIndex == 1) {
186  Date endDate = currIngestJob.getEndDateTime();
187  if (endDate.getTime() == 0) {
188  return "N/A";
189  }
190  return datetimeFormat.format(currIngestJob.getEndDateTime());
191  } else if (columnIndex == 2) {
192  return currIngestJob.getStatus().getDisplayName();
193  }
194  return null;
195  }
196 
197  @Override
198  public String getColumnName(int column) {
199  return columnHeaders.get(column);
200  }
201 
202  }
203 
204  @Messages({"IngestJobInfoPanel.IngestModuleTableModel.ModuleName.header=Module Name",
205  "IngestJobInfoPanel.IngestModuleTableModel.ModuleVersion.header=Module Version"})
206  private class IngestModuleTableModel extends AbstractTableModel {
207 
208  private final List<String> columnHeaders = new ArrayList<>();
209  private final IngestJobInfo currJob;
210 
211  IngestModuleTableModel(IngestJobInfo currJob) {
212  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleName_header());
213  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleVersion_header());
214  this.currJob = currJob;
215  }
216 
217  @Override
218  public int getRowCount() {
219  if (currJob == null) {
220  return 0;
221  }
222  return currJob.getIngestModuleInfo().size();
223  }
224 
225  @Override
226  public int getColumnCount() {
227  return columnHeaders.size();
228  }
229 
230  @Override
231  public Object getValueAt(int rowIndex, int columnIndex) {
232  if (currJob != null) {
233  IngestModuleInfo currIngestModule = currJob.getIngestModuleInfo().get(rowIndex);
234  if (columnIndex == 0) {
235  return currIngestModule.getDisplayName();
236  } else if (columnIndex == 1) {
237  return currIngestModule.getVersion();
238  }
239  return null;
240  }
241  return null;
242  }
243 
244  @Override
245  public String getColumnName(int column) {
246  return columnHeaders.get(column);
247  }
248 
249  }
250 
256  @SuppressWarnings("unchecked")
257  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
258  private void initComponents() {
259  java.awt.GridBagConstraints gridBagConstraints;
260 
261  javax.swing.JScrollPane mainScrollPane = new javax.swing.JScrollPane();
262  javax.swing.JPanel contentPanel = new javax.swing.JPanel();
263  javax.swing.JScrollPane ingestJobsScrollPane = new javax.swing.JScrollPane();
264  ingestJobTable = new javax.swing.JTable();
265  javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
266  javax.swing.JLabel jLabel2 = new javax.swing.JLabel();
267  javax.swing.JScrollPane ingestModulesScrollPane = new javax.swing.JScrollPane();
268  ingestModuleTable = new javax.swing.JTable();
269 
270  setMaximumSize(new java.awt.Dimension(32767, 32767));
271  setLayout(new java.awt.BorderLayout());
272 
273  contentPanel.setMaximumSize(new java.awt.Dimension(32767, 32767));
274  contentPanel.setMinimumSize(new java.awt.Dimension(625, 150));
275  contentPanel.setPreferredSize(new java.awt.Dimension(625, 150));
276  contentPanel.setLayout(new java.awt.GridBagLayout());
277 
278  ingestJobsScrollPane.setBorder(null);
279  ingestJobsScrollPane.setMinimumSize(new java.awt.Dimension(16, 16));
280  ingestJobsScrollPane.setPreferredSize(null);
281 
282  ingestJobTable.setModel(ingestJobTableModel);
283  ingestJobTable.getTableHeader().setReorderingAllowed(false);
284  ingestJobsScrollPane.setViewportView(ingestJobTable);
285  ingestJobTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
286 
287  gridBagConstraints = new java.awt.GridBagConstraints();
288  gridBagConstraints.gridx = 0;
289  gridBagConstraints.gridy = 1;
290  gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
291  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
292  gridBagConstraints.weightx = 1.0;
293  gridBagConstraints.weighty = 1.0;
294  gridBagConstraints.insets = new java.awt.Insets(2, 10, 10, 0);
295  contentPanel.add(ingestJobsScrollPane, gridBagConstraints);
296 
297  org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel1.text")); // NOI18N
298  gridBagConstraints = new java.awt.GridBagConstraints();
299  gridBagConstraints.gridx = 1;
300  gridBagConstraints.gridy = 0;
301  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
302  gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
303  contentPanel.add(jLabel1, gridBagConstraints);
304 
305  org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel2.text")); // NOI18N
306  gridBagConstraints = new java.awt.GridBagConstraints();
307  gridBagConstraints.gridx = 0;
308  gridBagConstraints.gridy = 0;
309  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
310  gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
311  contentPanel.add(jLabel2, gridBagConstraints);
312 
313  ingestModulesScrollPane.setMaximumSize(new java.awt.Dimension(254, 32767));
314  ingestModulesScrollPane.setMinimumSize(new java.awt.Dimension(254, 16));
315  ingestModulesScrollPane.setPreferredSize(new java.awt.Dimension(254, 16));
316 
317  ingestModuleTable.setModel(ingestModuleTableModel);
318  ingestModulesScrollPane.setViewportView(ingestModuleTable);
319 
320  gridBagConstraints = new java.awt.GridBagConstraints();
321  gridBagConstraints.gridx = 1;
322  gridBagConstraints.gridy = 1;
323  gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
324  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
325  gridBagConstraints.weighty = 1.0;
326  gridBagConstraints.insets = new java.awt.Insets(2, 8, 10, 10);
327  contentPanel.add(ingestModulesScrollPane, gridBagConstraints);
328 
329  mainScrollPane.setViewportView(contentPanel);
330 
331  add(mainScrollPane, java.awt.BorderLayout.CENTER);
332  }// </editor-fold>//GEN-END:initComponents
333 
334 
335  // Variables declaration - do not modify//GEN-BEGIN:variables
336  private javax.swing.JTable ingestJobTable;
337  private javax.swing.JTable ingestModuleTable;
338  // End of variables declaration//GEN-END:variables
339 }
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:491

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