Autopsy  4.16.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  if (CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName())) {
93  refresh();
94  }
95  });
96  }
97 
103  public void setDataSource(DataSource selectedDataSource) {
104  this.selectedDataSource = selectedDataSource;
105  ingestJobsForSelectedDataSource.clear();
106  if (selectedDataSource != null) {
107  for (IngestJobInfo jobInfo : ingestJobs) {
108  if (selectedDataSource.getId() == jobInfo.getObjectId()) {
109  ingestJobsForSelectedDataSource.add(jobInfo);
110  }
111  }
112  }
113  this.ingestJobTableModel = new IngestJobTableModel();
114  this.ingestJobTable.setModel(ingestJobTableModel);
115  //if there were ingest jobs select the first one by default
116  if (!ingestJobsForSelectedDataSource.isEmpty()) {
117  ingestJobTable.setRowSelectionInterval(0, 0);
118  }
119  this.repaint();
120  }
121 
125  private void refresh() {
126  try {
127  if (Case.isCaseOpen()) {
128  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
129  this.ingestJobs = skCase.getIngestJobs();
130  setDataSource(selectedDataSource);
131  } else {
132  this.ingestJobs = new ArrayList<>();
133  setDataSource(null);
134  }
135 
136  } catch (TskCoreException | NoCurrentCaseException ex) {
137  logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
138  JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
139  }
140  }
141 
142  @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",
143  "IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time",
144  "IngestJobInfoPanel.IngestJobTableModel.IngestStatus.header=Ingest Status"})
145  private class IngestJobTableModel extends AbstractTableModel {
146 
147  private final List<String> columnHeaders = new ArrayList<>();
148 
150  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_StartTime_header());
151  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_EndTime_header());
152  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_IngestStatus_header());
153  }
154 
155  @Override
156  public int getRowCount() {
157  return ingestJobsForSelectedDataSource.size();
158  }
159 
160  @Override
161  public int getColumnCount() {
162  return columnHeaders.size();
163  }
164 
165  @Override
166  public Object getValueAt(int rowIndex, int columnIndex) {
167  IngestJobInfo currIngestJob = ingestJobsForSelectedDataSource.get(rowIndex);
168  if (columnIndex == 0) {
169  return datetimeFormat.format(currIngestJob.getStartDateTime());
170  } else if (columnIndex == 1) {
171  Date endDate = currIngestJob.getEndDateTime();
172  if (endDate.getTime() == 0) {
173  return "N/A";
174  }
175  return datetimeFormat.format(currIngestJob.getEndDateTime());
176  } else if (columnIndex == 2) {
177  return currIngestJob.getStatus().getDisplayName();
178  }
179  return null;
180  }
181 
182  @Override
183  public String getColumnName(int column) {
184  return columnHeaders.get(column);
185  }
186 
187  }
188 
189  @Messages({"IngestJobInfoPanel.IngestModuleTableModel.ModuleName.header=Module Name",
190  "IngestJobInfoPanel.IngestModuleTableModel.ModuleVersion.header=Module Version"})
191  private class IngestModuleTableModel extends AbstractTableModel {
192 
193  private final List<String> columnHeaders = new ArrayList<>();
194  private final IngestJobInfo currJob;
195 
196  IngestModuleTableModel(IngestJobInfo currJob) {
197  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleName_header());
198  columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleVersion_header());
199  this.currJob = currJob;
200  }
201 
202  @Override
203  public int getRowCount() {
204  if (currJob == null) {
205  return 0;
206  }
207  return currJob.getIngestModuleInfo().size();
208  }
209 
210  @Override
211  public int getColumnCount() {
212  return columnHeaders.size();
213  }
214 
215  @Override
216  public Object getValueAt(int rowIndex, int columnIndex) {
217  if (currJob != null) {
218  IngestModuleInfo currIngestModule = currJob.getIngestModuleInfo().get(rowIndex);
219  if (columnIndex == 0) {
220  return currIngestModule.getDisplayName();
221  } else if (columnIndex == 1) {
222  return currIngestModule.getVersion();
223  }
224  return null;
225  }
226  return null;
227  }
228 
229  @Override
230  public String getColumnName(int column) {
231  return columnHeaders.get(column);
232  }
233 
234  }
235 
241  @SuppressWarnings("unchecked")
242  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
243  private void initComponents() {
244 
245  jScrollPane1 = new javax.swing.JScrollPane();
246  ingestJobTable = new javax.swing.JTable();
247  jLabel1 = new javax.swing.JLabel();
248  jLabel2 = new javax.swing.JLabel();
249  jScrollPane2 = new javax.swing.JScrollPane();
250  ingestModuleTable = new javax.swing.JTable();
251 
252  jScrollPane1.setBorder(null);
253 
254  ingestJobTable.setModel(ingestJobTableModel);
255  ingestJobTable.getTableHeader().setReorderingAllowed(false);
256  jScrollPane1.setViewportView(ingestJobTable);
257  ingestJobTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
258 
259  org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel1.text")); // NOI18N
260 
261  org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel2.text")); // NOI18N
262 
263  ingestModuleTable.setModel(ingestModuleTableModel);
264  jScrollPane2.setViewportView(ingestModuleTable);
265 
266  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
267  this.setLayout(layout);
268  layout.setHorizontalGroup(
269  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
270  .addGroup(layout.createSequentialGroup()
271  .addGap(15, 15, 15)
272  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
273  .addComponent(jLabel2)
274  .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE))
275  .addGap(8, 8, 8)
276  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
277  .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 254, javax.swing.GroupLayout.PREFERRED_SIZE)
278  .addComponent(jLabel1))
279  .addContainerGap())
280  );
281  layout.setVerticalGroup(
282  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
283  .addGroup(layout.createSequentialGroup()
284  .addGap(8, 8, 8)
285  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
286  .addComponent(jLabel1)
287  .addComponent(jLabel2))
288  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
289  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
290  .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
291  .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
292  .addGap(10, 10, 10))
293  );
294  }// </editor-fold>//GEN-END:initComponents
295 
296 
297  // Variables declaration - do not modify//GEN-BEGIN:variables
298  private javax.swing.JTable ingestJobTable;
299  private javax.swing.JTable ingestModuleTable;
300  private javax.swing.JLabel jLabel1;
301  private javax.swing.JLabel jLabel2;
302  private javax.swing.JScrollPane jScrollPane1;
303  private javax.swing.JScrollPane jScrollPane2;
304  // End of variables declaration//GEN-END:variables
305 }
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-2020 Basis Technology. Generated on: Tue Sep 22 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.