19 package org.sleuthkit.autopsy.ingest;
 
   21 import java.awt.Component;
 
   22 import java.awt.Dimension;
 
   23 import java.awt.Toolkit;
 
   24 import java.awt.event.ActionEvent;
 
   25 import java.awt.event.WindowAdapter;
 
   26 import java.awt.event.WindowEvent;
 
   27 import java.util.ArrayList;
 
   28 import java.util.Arrays;
 
   29 import java.util.List;
 
   31 import java.util.logging.Level;
 
   32 import java.util.logging.Logger;
 
   33 import javax.swing.DefaultComboBoxModel;
 
   34 import javax.swing.Icon;
 
   35 import javax.swing.ImageIcon;
 
   36 import javax.swing.JDialog;
 
   37 import javax.swing.JLabel;
 
   38 import javax.swing.JTable;
 
   39 import javax.swing.ListSelectionModel;
 
   40 import javax.swing.SwingUtilities;
 
   41 import javax.swing.event.ListSelectionEvent;
 
   42 import javax.swing.table.AbstractTableModel;
 
   43 import javax.swing.table.DefaultTableCellRenderer;
 
   44 import javax.swing.table.TableColumn;
 
   45 import org.openide.util.NbBundle.Messages;
 
   69     private final List<IngestJobInfo> 
ingestJobs = 
new ArrayList<>();
 
   70     private final List<IngestModuleModel> 
modules = 
new ArrayList<>();
 
   83         for (IngestModuleTemplate moduleTemplate : settings.getIngestModuleTemplates()) {
 
  100         this.dataSources.addAll(dataSources);
 
  103             ingestJobs.addAll(skCase.getIngestJobs());
 
  104         } 
catch (IllegalStateException ex) {
 
  105             logger.log(Level.SEVERE, 
"No open case", ex);
 
  106         } 
catch (TskCoreException ex) {
 
  107             logger.log(Level.SEVERE, 
"Failed to load ingest job information", ex);
 
  109         for (IngestModuleTemplate moduleTemplate : settings.getIngestModuleTemplates()) {
 
  123         List<IngestModuleTemplate> moduleTemplates = 
new ArrayList<>();
 
  125             IngestModuleTemplate moduleTemplate = module.getIngestModuleTemplate();
 
  126             if (module.hasModuleSettingsPanel()) {
 
  128                 moduleTemplate.setModuleSettings(moduleSettings);
 
  130             moduleTemplates.add(moduleTemplate);
 
  132         this.settings.setIngestModuleTemplates(moduleTemplates);
 
  136     @Messages({
"IngestJobSettingsPanel.noPerRunSettings=The selected module has no per-run settings."})
 
  140         modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 
  147         for (
int i = 0; i < 
modulesTable.getColumnCount(); ++i) {
 
  148             TableColumn column = 
modulesTable.getColumnModel().getColumn(i);
 
  150                 column.setPreferredWidth(((
int) (width * 0.15)));
 
  152                 column.setCellRenderer(renderer);
 
  153                 column.setPreferredWidth(((
int) (width * 0.84)));
 
  160         modulesTable.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
 
  161             ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
 
  162             if (!listSelectionModel.isSelectionEmpty()) {
 
  163                 int index = listSelectionModel.getMinSelectionIndex();
 
  164                 selectedModule = modules.get(index);
 
  166                 if (null != selectedModule.getModuleSettingsPanel()) {
 
  179         this.
modulesTable.getColumnModel().getColumn(0).setMaxWidth(22);
 
  180         this.
modulesTable.getColumnModel().getColumn(1).setMaxWidth(20);
 
  181         this.
modulesTable.getColumnModel().getColumn(1).setMinWidth(20);
 
  188         pastJobsButton.setEnabled(!dataSources.isEmpty() && !ingestJobs.isEmpty());
 
  191     void setPastJobsButtonVisible(
boolean isVisible) {
 
  200     @SuppressWarnings(
"unchecked")
 
  204         timeGroup = 
new javax.swing.ButtonGroup();
 
  207         jPanel1 = 
new javax.swing.JPanel();
 
  219         setMaximumSize(
new java.awt.Dimension(5750, 3000));
 
  220         setMinimumSize(
new java.awt.Dimension(0, 0));
 
  221         setPreferredSize(
new java.awt.Dimension(625, 450));
 
  223         modulesScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(
new java.awt.Color(160, 160, 160)));
 
  227         modulesTable.setBackground(
new java.awt.Color(240, 240, 240));
 
  228         modulesTable.setModel(
new javax.swing.table.DefaultTableModel(
 
  240         jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(
new java.awt.Color(160, 160, 160)));
 
  241         jPanel1.setPreferredSize(
new java.awt.Dimension(338, 257));
 
  247             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  252         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).");
 
  255         jScrollPane1.setPreferredSize(
new java.awt.Dimension(250, 180));
 
  261         javax.swing.GroupLayout jPanel1Layout = 
new javax.swing.GroupLayout(
jPanel1);
 
  262         jPanel1.setLayout(jPanel1Layout);
 
  263         jPanel1Layout.setHorizontalGroup(
 
  264             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  265             .addComponent(
jSeparator2, javax.swing.GroupLayout.Alignment.TRAILING)
 
  266             .addGroup(jPanel1Layout.createSequentialGroup()
 
  268                 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  269                     .addComponent(
descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
 
  270                     .addComponent(
jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 320, Short.MAX_VALUE)
 
  271                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
 
  272                         .addGap(0, 0, Short.MAX_VALUE)
 
  276         jPanel1Layout.setVerticalGroup(
 
  277             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  278             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
 
  280                 .addComponent(
jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE)
 
  282                 .addComponent(
jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  284                 .addComponent(
descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  285                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  296             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  305             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  315         pastJobsButton.addActionListener(
new java.awt.event.ActionListener() {
 
  316             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  325             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  330         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  331         this.setLayout(layout);
 
  332         layout.setHorizontalGroup(
 
  333             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  334             .addGroup(layout.createSequentialGroup()
 
  336                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, 
false)
 
  337                     .addGroup(layout.createSequentialGroup()
 
  338                         .addComponent(
jButtonSelectAll, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  339                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  340                         .addComponent(
jButtonDeselectAll, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  341                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  342                         .addComponent(
pastJobsButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  343                     .addComponent(
modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  344                     .addComponent(
fileIngestFilterLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  347                 .addComponent(
jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  351         layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, 
new java.awt.Component[] {jButtonDeselectAll, jButtonSelectAll, pastJobsButton});
 
  353         layout.setVerticalGroup(
 
  354             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  355             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 
  357                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
 
  358                     .addGroup(layout.createSequentialGroup()
 
  360                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  361                         .addComponent(
fileIngestFilterComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  362                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  363                         .addComponent(
modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  364                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  365                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 
  366                             .addComponent(
jButtonSelectAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  367                             .addComponent(
jButtonDeselectAll, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  368                             .addComponent(
pastJobsButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
 
  369                     .addComponent(
jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE))
 
  378             if (selectedModule.hasGlobalSettingsPanel()) {
 
  379                 selectedModule.saveResourcesConfig();
 
  384         dialog.addWindowListener(
new WindowAdapter() {
 
  386             public void windowClosing(WindowEvent e) {
 
  391         dialog.
display(selectedModule.getGlobalSettingsPanel());
 
  401     @Messages({
"IngestJobSettingsPanel.pastJobsButton.action.frame.title=Ingest History"})
 
  403         JDialog topFrame = (JDialog) SwingUtilities.getWindowAncestor(
this);
 
  404         JDialog dialog = 
new JDialog(topFrame, Bundle.IngestJobSettingsPanel_pastJobsButton_action_frame_title(), 
false);
 
  406         dialog.add(ingestInfo);
 
  407         Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
 
  408         double w = dialog.getSize().getWidth();
 
  409         double h = dialog.getSize().getHeight();
 
  410         dialog.setLocation((
int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
 
  411         dialog.setResizable(
true);
 
  413         dialog.setVisible(
true);
 
  421             fileIngestFilterPanel.
load();
 
  423             final ArrayList<String> oldFilterList = 
new ArrayList<>(Arrays.asList(
getComboBoxContents()));
 
  426                         fileIngestFilterPanel.
store();
 
  427                         ArrayList<FilesSet> newFilterList = 
new ArrayList<>();
 
  431                             logger.log(Level.SEVERE, 
"Failed to get user created file ingest filters, only default available for selection", ex); 
 
  433                         for (
FilesSet filter : newFilterList) {  
 
  434                             if (!oldFilterList.contains(filter.getName())) {
 
  436                                 settings.setFileIngestFilter(filter);
 
  446             dialog.
display(fileIngestFilterPanel);
 
  449         } 
else if (evt.getActionCommand().equals(
"comboBoxChanged")) {
 
  454                     fileIngestFilters.put(fSet.getName(), fSet);
 
  456                 settings.setFileIngestFilter(fileIngestFilters
 
  460                 logger.log(Level.SEVERE, 
"Failed to get file ingest filter from combobox selection, default filter being used", ex); 
 
  476         ArrayList<String> nameList = 
new ArrayList<>();
 
  478             nameList.add(fSet.getName());
 
  482                 nameList.add(fSet.getName());
 
  485             logger.log(Level.SEVERE, 
"Failed to get user created file ingest filters for combo box, only default available for selection", ex); 
 
  488         return nameList.toArray(
new String[nameList.size()]);
 
  493             module.setEnabled(set);
 
  528             if (moduleTemplate.hasModuleSettingsPanel()) {
 
  529                 moduleSettingsPanel = moduleTemplate.getModuleSettingsPanel();
 
  531             if (moduleTemplate.hasGlobalSettingsPanel()) {
 
  532                 globalSettingsPanel = moduleTemplate.getGlobalSettingsPanel();
 
  536         IngestModuleTemplate getIngestModuleTemplate() {
 
  541             return moduleTemplate.getModuleName();
 
  544         String getDescription() {
 
  545             return moduleTemplate.getModuleDescription();
 
  548         void setEnabled(
boolean enabled) {
 
  549             moduleTemplate.setEnabled(enabled);
 
  552         boolean isEnabled() {
 
  553             return moduleTemplate.isEnabled();
 
  556         boolean hasModuleSettingsPanel() {
 
  557             return moduleTemplate.hasModuleSettingsPanel();
 
  560         IngestModuleIngestJobSettingsPanel getModuleSettingsPanel() {
 
  564         boolean hasGlobalSettingsPanel() {
 
  565             return moduleTemplate.hasGlobalSettingsPanel();
 
  568         IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() {
 
  572         void saveResourcesConfig() {
 
  583         private static final long serialVersionUID = 1L;
 
  587             return modules.size();
 
  598             switch (columnIndex) {
 
  600                     return module.isEnabled();
 
  604                     return module.getName();
 
  610             return columnIndex == 0;
 
  614         public void setValueAt(Object aValue, 
int rowIndex, 
int columnIndex) {
 
  615             if (columnIndex == 0) {
 
  616                 modules.get(rowIndex).setEnabled((
boolean) aValue);
 
  626             if (dataSources.isEmpty() || ingestJobs.isEmpty()) {
 
  629             boolean previousVersionRun = 
false;
 
  630             for (IngestJobInfo ingestJob : ingestJobs) {
 
  631                 if (ingestJob.getStatus() != IngestJobInfo.IngestJobStatusType.COMPLETED) {
 
  634                 long objectId = ingestJob.getObjectId();
 
  635                 boolean isSameDataSource = 
false;
 
  636                 for (Content dataSource : dataSources) {
 
  637                     isSameDataSource = isSameDataSource || dataSource.getId() == objectId;
 
  639                 if (isSameDataSource) {
 
  642                         String uniqueName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + 
"-" 
  644                                 + IngestModuleInfo.IngestModuleType.DATA_SOURCE_LEVEL.toString() + 
"-" 
  646                         for (IngestModuleInfo ingestModuleInfo : ingestJob.getIngestModuleInfo()) {
 
  647                             boolean sameModule = ingestModuleInfo.getUniqueName().equals(uniqueName);
 
  649                                 if (ingestModuleInfo.getVersion().equals(module.getIngestModuleTemplate().getModuleFactory().getModuleVersionNumber())) {
 
  653                             previousVersionRun = previousVersionRun || sameModule;
 
  657                         String uniqueName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + 
"-" 
  659                                 + IngestModuleInfo.IngestModuleType.FILE_LEVEL.toString() + 
"-" 
  661                         for (IngestModuleInfo ingestModuleInfo : ingestJob.getIngestModuleInfo()) {
 
  662                             boolean sameModule = ingestModuleInfo.getUniqueName().equals(uniqueName);
 
  664                                 if (ingestModuleInfo.getVersion().equals(module.getIngestModuleTemplate().getModuleFactory().getModuleVersionNumber())) {
 
  668                             previousVersionRun = previousVersionRun || sameModule;
 
  673             if (previousVersionRun) {
 
  684     @Messages({
"IngestJobSettingsPanel.IngestModulesTableRenderer.warning.message=This ingest module has been run before on this data source.",
 
  685         "IngestJobSettingsPanel.IngestModulesTableRenderer.info.message=A previous version of this ingest module has been run before on this data source."})
 
  688         private static final long serialVersionUID = 1L;
 
  690         List<String> tooltips = 
new ArrayList<>();
 
  694                 tooltips.add(moduleTemplate.getDescription());
 
  700             super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
  703                 setToolTipText(tooltips.get(row));
 
  704             } 
else if (1 == column) {
 
  705                 setIcon((Icon) value);
 
  707                 if (warningIcon.equals(value)) {
 
  708                     setToolTipText(Bundle.IngestJobSettingsPanel_IngestModulesTableRenderer_warning_message());
 
  709                 } 
else if (infoIcon.equals(value)) {
 
  710                     setToolTipText(Bundle.IngestJobSettingsPanel_IngestModulesTableRenderer_info_message());
 
IngestJobSettingsPanel(IngestJobSettings settings, List< Content > dataSources)
IngestJobSettingsPanel(IngestJobSettings settings)
javax.swing.JSeparator jSeparator2
javax.swing.JLabel fileIngestFilterLabel
String getModuleVersionNumber()
void display(JPanel panel)
static List< FilesSet > getStandardFileIngestFilters()
final IngestModulesTableModel tableModel
boolean isFileIngestModuleFactory()
IngestModulesTableRenderer()
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 globalSettingsButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JButton pastJobsButton
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()
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)
final IngestJobSettings settings
void jButtonDeselectAllActionPerformed(java.awt.event.ActionEvent evt)
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
javax.swing.JPanel jPanel1
Object getValueAt(int rowIndex, int columnIndex)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
boolean isCellEditable(int rowIndex, int columnIndex)
javax.swing.JScrollPane jScrollPane1
IngestModuleModel selectedModule
final List< IngestJobInfo > ingestJobs
String getModuleDisplayName()
javax.swing.JButton globalSettingsButton
final IngestModuleTemplate moduleTemplate
final List< Content > dataSources
javax.swing.JPanel ingestSettingsPanel
boolean isDataSourceIngestModuleFactory()
void customizeComponents()
javax.swing.JButton jButtonDeselectAll