/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.beans.PropertyChangeEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.IngestJobInfo;
import org.sleuthkit.datamodel.IngestModuleInfo;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Panel for displaying ingest job history.
*/
public final class IngestJobInfoPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(IngestJobInfoPanel.class.getName());
private List<IngestJobInfo> ingestJobs;
private IngestJobTableModel ingestJobTableModel = new IngestJobTableModel();
private IngestModuleTableModel ingestModuleTableModel = new IngestModuleTableModel(null);
private final DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
/**
* Creates new form IngestJobInfoPanel
*/
public IngestJobInfoPanel() {
initComponents();
customizeComponents();
}
@Messages({"IngestJobInfoPanel.loadIngestJob.error.text=Failed to load ingest jobs.",
"IngestJobInfoPanel.loadIngestJob.error.title=Load Failure"})
private void customizeComponents() {
refresh();
this.ingestJobTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
this.ingestModuleTableModel = new IngestModuleTableModel(this.ingestJobs.get(ingestJobTable.getSelectedRow()));
this.ingestModuleTable.setModel(this.ingestModuleTableModel);
});
IngestManager.getInstance().addIngestJobEventListener((PropertyChangeEvent evt) -> {
if (evt.getPropertyName().equals(IngestManager.IngestJobEvent.STARTED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.CANCELLED.toString())
|| evt.getPropertyName().equals(IngestManager.IngestJobEvent.COMPLETED.toString())) {
refresh();
}
});
}
private void refresh() {
SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
try {
List<IngestJobInfo> ingestJobs = skCase.getIngestJobs();
this.ingestJobs = ingestJobs;
this.repaint();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to load ingest jobs.", ex);
JOptionPane.showMessageDialog(null, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
}
}
@Messages({"IngestJobInfoPanel.IngestJobTableModel.DataSource.header=Data Source",
"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",
"IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time",
"IngestJobInfoPanel.IngestJobTableModel.IngestStatus.header=Ingest Status"})
private class IngestJobTableModel extends AbstractTableModel {
private List<String> columnHeaders = new ArrayList<>();
IngestJobTableModel() {
columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_DataSource_header());
columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_StartTime_header());
columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_EndTime_header());
columnHeaders.add(Bundle.IngestJobInfoPanel_IngestJobTableModel_IngestStatus_header());
}
@Override
public int getRowCount() {
return ingestJobs.size();
}
@Override
public int getColumnCount() {
return columnHeaders.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
IngestJobInfo currIngestJob = ingestJobs.get(rowIndex);
SleuthkitCase skCase = Case.getCurrentCase().getSleuthkitCase();
if (columnIndex == 0) {
try {
return skCase.getContentById(currIngestJob.getObjectId()).getName();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get content from db", ex);
return "";
}
} else if (columnIndex == 1) {
return datetimeFormat.format(currIngestJob.getStartDateTime());
} else if (columnIndex == 2) {
Date endDate = currIngestJob.getEndDateTime();
if (endDate.getTime() == 0) {
return "N/A";
}
return datetimeFormat.format(currIngestJob.getEndDateTime());
} else if (columnIndex == 3) {
return currIngestJob.getStatus().getDisplayName();
}
return null;
}
@Override
public String getColumnName(int column) {
return columnHeaders.get(column);
}
}
@Messages({"IngestJobInfoPanel.IngestModuleTableModel.ModuleName.header=Module Name",
"IngestJobInfoPanel.IngestModuleTableModel.ModuleVersion.header=Module Version"})
private class IngestModuleTableModel extends AbstractTableModel {
private List<String> columnHeaders = new ArrayList<>();
private IngestJobInfo currJob;
IngestModuleTableModel(IngestJobInfo currJob) {
columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleName_header());
columnHeaders.add(Bundle.IngestJobInfoPanel_IngestModuleTableModel_ModuleVersion_header());
this.currJob = currJob;
}
@Override
public int getRowCount() {
if (currJob == null) {
return 0;
}
return currJob.getIngestModuleInfo().size();
}
@Override
public int getColumnCount() {
return columnHeaders.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (currJob != null) {
IngestModuleInfo currIngestModule = currJob.getIngestModuleInfo().get(rowIndex);
if (columnIndex == 0) {
return currIngestModule.getDisplayName();
} else if (columnIndex == 1) {
return currIngestModule.getVersion();
}
return null;
}
return null;
}
@Override
public String getColumnName(int column) {
return columnHeaders.get(column);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
ingestJobTable = new javax.swing.JTable();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jScrollPane2 = new javax.swing.JScrollPane();
ingestModuleTable = new javax.swing.JTable();
jScrollPane1.setBorder(null);
ingestJobTable.setModel(ingestJobTableModel);
ingestJobTable.getTableHeader().setReorderingAllowed(false);
jScrollPane1.setViewportView(ingestJobTable);
ingestJobTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel1.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(IngestJobInfoPanel.class, "IngestJobInfoPanel.jLabel2.text")); // NOI18N
ingestModuleTable.setModel(ingestModuleTableModel);
jScrollPane2.setViewportView(ingestModuleTable);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(15, 15, 15)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE))
.addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 254, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(jLabel2))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
.addGap(10, 10, 10))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTable ingestJobTable;
private javax.swing.JTable ingestModuleTable;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
// End of variables declaration//GEN-END:variables
}