Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.casemodule;
20
21import java.beans.PropertyChangeEvent;
22import java.text.DateFormat;
23import java.text.SimpleDateFormat;
24import java.util.ArrayList;
25import java.util.Date;
26import java.util.EnumSet;
27import java.util.List;
28import java.util.Set;
29import java.util.concurrent.CancellationException;
30import java.util.concurrent.ExecutionException;
31import java.util.logging.Level;
32import javax.swing.JOptionPane;
33import javax.swing.SwingUtilities;
34import javax.swing.SwingWorker;
35import javax.swing.event.ListSelectionEvent;
36import javax.swing.table.AbstractTableModel;
37import org.openide.util.NbBundle.Messages;
38import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE;
39import org.sleuthkit.autopsy.coreutils.Logger;
40import org.sleuthkit.autopsy.events.AutopsyEvent;
41import org.sleuthkit.autopsy.ingest.IngestManager;
42import org.sleuthkit.datamodel.IngestJobInfo;
43import org.sleuthkit.datamodel.IngestModuleInfo;
44import org.sleuthkit.datamodel.SleuthkitCase;
45import org.sleuthkit.datamodel.TskCoreException;
46import org.sleuthkit.datamodel.DataSource;
47
51@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
52public 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<>();
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
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
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;
121 if (selectedDataSource != null) {
122 for (IngestJobInfo jobInfo : ingestJobs) {
123 if (selectedDataSource.getId() == jobInfo.getObjectId()) {
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());
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
201 IngestJobTableModel() {
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() {
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
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
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 void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition Case.java:712
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static synchronized IngestManager getInstance()
void addIngestJobEventListener(final PropertyChangeListener listener)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.