19 package org.sleuthkit.autopsy.ingest;
21 import java.awt.Component;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.WindowAdapter;
24 import java.awt.event.WindowEvent;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
29 import java.util.logging.Level;
30 import javax.swing.DefaultComboBoxModel;
31 import javax.swing.Icon;
32 import javax.swing.ImageIcon;
33 import javax.swing.JDialog;
34 import javax.swing.JLabel;
35 import javax.swing.JTable;
36 import javax.swing.ListSelectionModel;
37 import javax.swing.SwingUtilities;
38 import javax.swing.event.ListSelectionEvent;
39 import javax.swing.table.AbstractTableModel;
40 import javax.swing.table.DefaultTableCellRenderer;
41 import javax.swing.table.TableColumn;
42 import org.openide.util.NbBundle.Messages;
68 private final List<IngestJobInfo>
ingestJobs =
new ArrayList<>();
69 private final List<IngestModuleModel>
modules =
new ArrayList<>();
99 this.dataSources.addAll(dataSources);
102 ingestJobs.addAll(skCase.getIngestJobs());
104 logger.log(Level.SEVERE,
"No open case", ex);
105 }
catch (TskCoreException ex) {
106 logger.log(Level.SEVERE,
"Failed to load ingest job information", ex);
122 List<IngestModuleTemplate> moduleTemplates =
new ArrayList<>();
125 if (module.hasModuleSettingsPanel()) {
129 moduleTemplates.add(moduleTemplate);
135 @Messages({
"IngestJobSettingsPanel.noPerRunSettings=The selected module has no per-run settings."})
139 modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
146 for (
int i = 0; i <
modulesTable.getColumnCount(); ++i) {
147 TableColumn column =
modulesTable.getColumnModel().getColumn(i);
149 column.setPreferredWidth(((
int) (width * 0.15)));
151 column.setCellRenderer(renderer);
152 column.setPreferredWidth(((
int) (width * 0.84)));
159 modulesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
160 ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
161 if (!listSelectionModel.isSelectionEmpty()) {
162 int index = listSelectionModel.getMinSelectionIndex();
163 selectedModule = modules.get(index);
165 if (null != selectedModule.getModuleSettingsPanel()) {
178 this.
modulesTable.getColumnModel().getColumn(0).setMaxWidth(22);
179 this.
modulesTable.getColumnModel().getColumn(1).setMaxWidth(20);
180 this.
modulesTable.getColumnModel().getColumn(1).setMinWidth(20);
187 pastJobsButton.setEnabled(!dataSources.isEmpty() && !ingestJobs.isEmpty());
190 void setPastJobsButtonVisible(
boolean isVisible) {
199 @SuppressWarnings(
"unchecked")
203 timeGroup =
new javax.swing.ButtonGroup();
206 jPanel1 =
new javax.swing.JPanel();
218 setMaximumSize(
new java.awt.Dimension(5750, 3000));
219 setMinimumSize(
new java.awt.Dimension(0, 0));
220 setPreferredSize(
new java.awt.Dimension(625, 450));
222 modulesScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(
new java.awt.Color(160, 160, 160)));
226 modulesTable.setBackground(
new java.awt.Color(240, 240, 240));
227 modulesTable.setModel(
new javax.swing.table.DefaultTableModel(
239 jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(
new java.awt.Color(160, 160, 160)));
240 jPanel1.setPreferredSize(
new java.awt.Dimension(338, 257));
246 public void actionPerformed(java.awt.event.ActionEvent evt) {
251 descriptionLabel.setText(
"DO NOT REMOVE. This dummy text is used to anchor the inner panel's size to the outer panel, while still being expandable. Without this the expandability behavior doesn't work well. This text will never be shown, as it would only be shown when no module is selected (which is not possible).");
254 jScrollPane1.setPreferredSize(
new java.awt.Dimension(250, 180));
260 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(
jPanel1);
261 jPanel1.setLayout(jPanel1Layout);
262 jPanel1Layout.setHorizontalGroup(
263 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
264 .addComponent(
jSeparator2, javax.swing.GroupLayout.Alignment.TRAILING)
265 .addGroup(jPanel1Layout.createSequentialGroup()
267 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
268 .addComponent(
descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
269 .addComponent(
jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
270 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
271 .addGap(0, 0, Short.MAX_VALUE)
275 jPanel1Layout.setVerticalGroup(
276 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
277 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
279 .addComponent(
jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 328, Short.MAX_VALUE)
281 .addComponent(
jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
283 .addComponent(
descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
284 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
294 public void actionPerformed(java.awt.event.ActionEvent evt) {
302 public void actionPerformed(java.awt.event.ActionEvent evt) {
311 pastJobsButton.addActionListener(
new java.awt.event.ActionListener() {
312 public void actionPerformed(java.awt.event.ActionEvent evt) {
321 public void actionPerformed(java.awt.event.ActionEvent evt) {
326 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
327 this.setLayout(layout);
328 layout.setHorizontalGroup(
329 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
330 .addGroup(layout.createSequentialGroup()
332 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,
false)
333 .addGroup(layout.createSequentialGroup()
334 .addComponent(
jButtonSelectAll, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
335 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
336 .addComponent(
jButtonDeselectAll, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
337 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
338 .addComponent(
pastJobsButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
339 .addComponent(
modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
343 .addComponent(
jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE)
347 layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {jButtonDeselectAll, jButtonSelectAll, pastJobsButton});
349 layout.setVerticalGroup(
350 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
351 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
353 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
354 .addGroup(layout.createSequentialGroup()
356 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
357 .addComponent(
fileIngestFilterComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
358 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
359 .addComponent(
modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
360 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
361 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
362 .addComponent(
jButtonSelectAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
364 .addComponent(
pastJobsButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
365 .addComponent(
jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE))
374 if (selectedModule.hasGlobalSettingsPanel()) {
375 selectedModule.saveResourcesConfig();
380 dialog.addWindowListener(
new WindowAdapter() {
382 public void windowClosing(WindowEvent e) {
387 dialog.
display(selectedModule.getGlobalSettingsPanel());
397 @Messages({
"IngestJobSettingsPanel.pastJobsButton.action.frame.title=Ingest History"})
399 JDialog topFrame = (JDialog) SwingUtilities.getWindowAncestor(
this);
400 JDialog dialog =
new JDialog(topFrame, Bundle.IngestJobSettingsPanel_pastJobsButton_action_frame_title(),
false);
402 dialog.add(ingestInfo);
403 dialog.setLocationRelativeTo(topFrame);
404 dialog.setResizable(
true);
406 dialog.setVisible(
true);
414 fileIngestFilterPanel.
load();
416 final ArrayList<String> oldFilterList =
new ArrayList<>(Arrays.asList(
getComboBoxContents()));
419 fileIngestFilterPanel.
store();
420 ArrayList<FilesSet> newFilterList =
new ArrayList<>();
424 logger.log(Level.SEVERE,
"Failed to get user created file ingest filters, only default available for selection", ex);
427 for (
FilesSet filter : newFilterList) {
428 if (!oldFilterList.contains(filter.getName())) {
430 filterToSelect = filter.getName();
443 dialog.
display(fileIngestFilterPanel);
446 }
else if (evt.getActionCommand().equals(
"comboBoxChanged")) {
456 fileIngestFilters.put(fSet.getName(), fSet);
462 logger.log(Level.SEVERE,
"Failed to get file ingest filter from combobox selection, default filter being used", ex);
477 ArrayList<String> nameList =
new ArrayList<>();
479 nameList.add(fSet.getName());
483 nameList.add(fSet.getName());
486 logger.log(Level.SEVERE,
"Failed to get user created file ingest filters for combo box, only default available for selection", ex);
489 return nameList.toArray(
new String[nameList.size()]);
494 module.setEnabled(set);
545 String getDescription() {
549 void setEnabled(
boolean enabled) {
553 boolean isEnabled() {
557 boolean hasModuleSettingsPanel() {
561 IngestModuleIngestJobSettingsPanel getModuleSettingsPanel() {
565 boolean hasGlobalSettingsPanel() {
569 IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() {
573 void saveResourcesConfig() {
584 private static final long serialVersionUID = 1L;
588 return modules.size();
599 switch (columnIndex) {
601 return module.isEnabled();
605 return module.getName();
611 return columnIndex == 0;
615 public void setValueAt(Object aValue,
int rowIndex,
int columnIndex) {
616 if (columnIndex == 0) {
617 modules.get(rowIndex).setEnabled((
boolean) aValue);
627 if (dataSources.isEmpty() || ingestJobs.isEmpty()) {
630 boolean previousVersionRun =
false;
631 for (IngestJobInfo ingestJob : ingestJobs) {
632 if (ingestJob.getStatus() != IngestJobInfo.IngestJobStatusType.COMPLETED) {
635 long objectId = ingestJob.getObjectId();
636 boolean isSameDataSource =
false;
637 for (Content dataSource : dataSources) {
638 isSameDataSource = isSameDataSource || dataSource.getId() == objectId;
640 if (isSameDataSource) {
643 String uniqueName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) +
"-"
645 + IngestModuleInfo.IngestModuleType.DATA_SOURCE_LEVEL.toString() +
"-"
647 for (IngestModuleInfo ingestModuleInfo : ingestJob.getIngestModuleInfo()) {
648 boolean sameModule = ingestModuleInfo.getUniqueName().equals(uniqueName);
654 previousVersionRun = previousVersionRun || sameModule;
658 String uniqueName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) +
"-"
660 + IngestModuleInfo.IngestModuleType.FILE_LEVEL.toString() +
"-"
662 for (IngestModuleInfo ingestModuleInfo : ingestJob.getIngestModuleInfo()) {
663 boolean sameModule = ingestModuleInfo.getUniqueName().equals(uniqueName);
669 previousVersionRun = previousVersionRun || sameModule;
674 if (previousVersionRun) {
685 @Messages({
"IngestJobSettingsPanel.IngestModulesTableRenderer.warning.message=This ingest module has been run before on this data source.",
686 "IngestJobSettingsPanel.IngestModulesTableRenderer.info.message=A previous version of this ingest module has been run before on this data source."})
689 private static final long serialVersionUID = 1L;
691 List<String> tooltips =
new ArrayList<>();
695 tooltips.add(moduleTemplate.getDescription());
701 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
704 setToolTipText(tooltips.get(row));
705 }
else if (1 == column) {
706 setIcon((Icon) value);
708 if (warningIcon.equals(value)) {
709 setToolTipText(Bundle.IngestJobSettingsPanel_IngestModulesTableRenderer_warning_message());
710 }
else if (infoIcon.equals(value)) {
711 setToolTipText(Bundle.IngestJobSettingsPanel_IngestModulesTableRenderer_info_message());
IngestJobSettingsPanel(IngestJobSettings settings, List< Content > dataSources)
IngestJobSettingsPanel(IngestJobSettings settings)
IngestModuleFactory getModuleFactory()
javax.swing.JSeparator jSeparator2
javax.swing.JLabel fileIngestFilterLabel
String getModuleVersionNumber()
void display(JPanel panel)
static List< FilesSet > getStandardFileIngestFilters()
final IngestModulesTableModel tableModel
boolean isFileIngestModuleFactory()
void setEnabled(boolean enabled)
static Case getOpenCase()
IngestModulesTableRenderer()
void updateSelectedFilter(String filterName)
void pastJobsButtonActionPerformed(java.awt.event.ActionEvent evt)
static synchronized FilesSetsManager getInstance()
javax.swing.JLabel descriptionLabel
static final Logger logger
void SelectAllModules(boolean set)
void addApplyButtonListener(ActionListener l)
javax.swing.JTable modulesTable
final List< IngestModuleModel > modules
void jButtonSelectAllActionPerformed(java.awt.event.ActionEvent evt)
Class<?> getColumnClass(int c)
Map< String, FilesSet > getCustomFileIngestFilters()
static final long serialVersionUID
void setIngestModuleTemplates(List< IngestModuleTemplate > moduleTemplates)
void globalSettingsButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JButton pastJobsButton
boolean hasGlobalSettingsPanel()
javax.swing.JComboBox< String > fileIngestFilterComboBox
static ImageIcon warningIcon
ImageIcon getIcon(IngestModuleModel module)
abstract void saveSettings()
javax.swing.JButton jButtonSelectAll
String[] getComboBoxContents()
IngestModuleGlobalSettingsPanel globalSettingsPanel
static String getCreateNewFileIngestFilterString()
IngestJobSettings getSettings()
void setFileFilter(FilesSet fileIngestFilter)
IngestModuleIngestJobSettingsPanel moduleSettingsPanel
javax.swing.ButtonGroup timeGroup
static FilesSet getDefaultFilter()
SleuthkitCase getSleuthkitCase()
void setValueAt(Object aValue, int rowIndex, int columnIndex)
static ImageIcon infoIcon
javax.swing.JScrollPane modulesScrollPane
void fileIngestFilterComboBoxActionPerformed(java.awt.event.ActionEvent evt)
boolean hasModuleSettingsPanel()
final IngestJobSettings settings
void jButtonDeselectAllActionPerformed(java.awt.event.ActionEvent evt)
List< IngestModuleTemplate > getIngestModuleTemplates()
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
javax.swing.JPanel jPanel1
Object getValueAt(int rowIndex, int columnIndex)
synchronized static Logger getLogger(String name)
boolean isCellEditable(int rowIndex, int columnIndex)
javax.swing.JScrollPane jScrollPane1
IngestModuleModel selectedModule
final List< IngestJobInfo > ingestJobs
String getModuleDisplayName()
String getModuleDescription()
javax.swing.JButton globalSettingsButton
final IngestModuleTemplate moduleTemplate
final List< Content > dataSources
javax.swing.JPanel ingestSettingsPanel
IngestModuleGlobalSettingsPanel getGlobalSettingsPanel()
void setModuleSettings(IngestModuleIngestJobSettings settings)
IngestModuleIngestJobSettingsPanel getModuleSettingsPanel()
boolean isDataSourceIngestModuleFactory()
void customizeComponents()
javax.swing.JButton jButtonDeselectAll