19 package org.sleuthkit.autopsy.modules.filetypeid;
21 import java.awt.EventQueue;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.logging.Level;
27 import javax.swing.DefaultComboBoxModel;
28 import javax.swing.DefaultListModel;
29 import javax.swing.JOptionPane;
30 import javax.swing.event.ListSelectionEvent;
31 import javax.swing.event.ListSelectionListener;
32 import org.netbeans.spi.options.OptionsPanelController;
33 import org.openide.util.NbBundle;
46 @SuppressWarnings(
"PMD.SingularField")
47 final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
48 private static final long serialVersionUID = 1L;
49 private static final Logger logger = Logger.getLogger(FileTypeIdGlobalSettingsPanel.class.getName());
51 private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem");
52 private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem");
54 private static final String START_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem");
55 private static final String END_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem");
63 private DefaultListModel<FileType> typesListModel;
64 private java.util.List<FileType> fileTypes;
65 private DefaultListModel<Signature> signaturesListModel;
76 IngestJobEventPropertyChangeListener ingestJobEventsListener;
81 FileTypeIdGlobalSettingsPanel() {
83 customizeComponents();
84 addIngestJobEventsListener();
91 @NbBundle.Messages({
"FileTypeIdGlobalSettingsPanel.Title=Global File Type Identification Settings"})
92 private void customizeComponents() {
93 setName(Bundle.FileTypeIdGlobalSettingsPanel_Title());
94 setFileTypesListModel();
95 setSignaturesListModel();
96 setSignatureTypeComboBoxModel();
97 setOffsetRealtiveToComboBoxModel();
98 addTypeListSelectionListener();
99 populateTypeDetailsComponents();
105 private void setFileTypesListModel() {
106 typesListModel =
new DefaultListModel<>();
107 typesList.setModel(typesListModel);
110 private void setSignaturesListModel() {
111 this.signaturesListModel =
new DefaultListModel<>();
112 signatureList.setModel(signaturesListModel);
118 private void setSignatureTypeComboBoxModel() {
119 DefaultComboBoxModel<String> sigTypeComboBoxModel =
new DefaultComboBoxModel<>();
120 sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
121 sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
127 private void setOffsetRealtiveToComboBoxModel() {
128 DefaultComboBoxModel<String> offsetRelComboBoxModel =
new DefaultComboBoxModel<>();
129 offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
130 offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
138 private void addTypeListSelectionListener() {
139 typesList.addListSelectionListener(
new ListSelectionListener() {
141 public void valueChanged(ListSelectionEvent e) {
142 if (e.getValueIsAdjusting() ==
false) {
143 if (typesList.getSelectedIndex() == -1) {
144 clearTypeDetailsComponents();
146 populateTypeDetailsComponents();
162 private void addIngestJobEventsListener() {
163 ingestJobEventsListener =
new IngestJobEventPropertyChangeListener();
164 IngestManager.getInstance().addIngestJobEventListener(ingestJobEventsListener);
174 EventQueue.invokeLater(
new Runnable() {
187 private void enableButtons() {
189 newTypeButton.setEnabled(!ingestIsRunning);
191 boolean fileTypeIsSelected = typesList.getSelectedIndex() != -1;
192 deleteTypeButton.setEnabled(!ingestIsRunning && fileTypeIsSelected);
193 editTypeButton.setEnabled(!ingestIsRunning && fileTypeIsSelected);
195 ingestRunningWarningLabel.setVisible(ingestIsRunning);
204 fileTypes = CustomFileTypesManager.getInstance().getUserDefinedFileTypes();
205 updateFileTypesListModel();
206 if (!typesListModel.isEmpty()) {
207 typesList.setSelectedIndex(0);
209 }
catch (CustomFileTypesException ex) {
210 logger.log(Level.SEVERE,
"Failed to get custom file types", ex);
211 JOptionPane.showMessageDialog(
this,
212 NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.loadFileTypes.errorMessage"),
213 NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title"),
214 JOptionPane.ERROR_MESSAGE);
215 fileTypes = Collections.emptyList();
223 private void updateFileTypesListModel() {
224 typesListModel.clear();
225 for (FileType fileType : fileTypes) {
226 typesListModel.addElement(fileType);
235 private void populateTypeDetailsComponents() {
236 FileType fileType = typesList.getSelectedValue();
237 this.signatureList.setEnabled(
false);
238 if (null != fileType) {
239 List<Signature> signatures = fileType.getSignatures();
240 this.signaturesListModel.clear();
241 for (Signature sig : signatures) {
242 signaturesListModel.addElement(sig);
252 private void clearTypeDetailsComponents() {
253 typesList.clearSelection();
254 this.signaturesListModel.clear();
262 public void store() {
264 CustomFileTypesManager.getInstance().setUserDefinedFileTypes(fileTypes);
265 }
catch (CustomFileTypesManager.CustomFileTypesException ex) {
266 logger.log(Level.SEVERE,
"Failed to set custom file types", ex);
267 JOptionPane.showMessageDialog(
this,
268 NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.saveFileTypes.errorMessage"),
269 NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title"),
270 JOptionPane.ERROR_MESSAGE);
278 public void saveSettings() {
286 @SuppressWarnings(
"FinalizeDeclaration")
287 protected
void finalize() throws Throwable {
288 IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventsListener);
297 @SuppressWarnings(
"unchecked")
299 private
void initComponents() {
301 jPanel3 =
new javax.swing.JPanel();
302 ingestRunningWarningLabel =
new javax.swing.JLabel();
303 jLabel3 =
new javax.swing.JLabel();
304 jScrollPane2 =
new javax.swing.JScrollPane();
305 jSplitPane1 =
new javax.swing.JSplitPane();
306 jPanel1 =
new javax.swing.JPanel();
307 jLabel2 =
new javax.swing.JLabel();
308 typesScrollPane =
new javax.swing.JScrollPane();
309 typesList =
new javax.swing.JList<>();
310 deleteTypeButton =
new javax.swing.JButton();
311 newTypeButton =
new javax.swing.JButton();
312 editTypeButton =
new javax.swing.JButton();
313 jPanel2 =
new javax.swing.JPanel();
314 jLabel1 =
new javax.swing.JLabel();
315 jScrollPane1 =
new javax.swing.JScrollPane();
316 signatureList =
new javax.swing.JList<>();
318 setMaximumSize(null);
319 setPreferredSize(
new java.awt.Dimension(752, 507));
321 jPanel3.setPreferredSize(
new java.awt.Dimension(781, 339));
323 ingestRunningWarningLabel.setFont(ingestRunningWarningLabel.getFont().deriveFont(ingestRunningWarningLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
324 ingestRunningWarningLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/modules/filetypeid/warning16.png")));
325 org.openide.awt.Mnemonics.setLocalizedText(ingestRunningWarningLabel,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text"));
327 jLabel3.setFont(jLabel3.getFont().deriveFont(jLabel3.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
328 org.openide.awt.Mnemonics.setLocalizedText(jLabel3,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.jLabel3.text"));
330 jScrollPane2.setMinimumSize(
new java.awt.Dimension(300, 0));
331 jScrollPane2.setPreferredSize(
new java.awt.Dimension(550, 275));
333 jSplitPane1.setDividerSize(1);
334 jSplitPane1.setMinimumSize(
new java.awt.Dimension(0, 0));
336 jPanel1.setMinimumSize(
new java.awt.Dimension(362, 0));
337 jPanel1.setPreferredSize(
new java.awt.Dimension(362, 0));
339 jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
340 org.openide.awt.Mnemonics.setLocalizedText(jLabel2,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.jLabel2.text"));
342 typesList.setFont(typesList.getFont().deriveFont(typesList.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
343 typesList.setMaximumSize(
new java.awt.Dimension(150, 0));
344 typesList.setMinimumSize(
new java.awt.Dimension(150, 0));
345 typesScrollPane.setViewportView(typesList);
347 deleteTypeButton.setFont(deleteTypeButton.getFont().deriveFont(deleteTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
348 deleteTypeButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/delete16.png")));
349 org.openide.awt.Mnemonics.setLocalizedText(deleteTypeButton,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.deleteTypeButton.text"));
350 deleteTypeButton.addActionListener(
new java.awt.event.ActionListener() {
351 public void actionPerformed(java.awt.event.ActionEvent evt) {
352 deleteTypeButtonActionPerformed(evt);
356 newTypeButton.setFont(newTypeButton.getFont().deriveFont(newTypeButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
357 newTypeButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/add16.png")));
358 org.openide.awt.Mnemonics.setLocalizedText(newTypeButton,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.newTypeButton.text"));
359 newTypeButton.addActionListener(
new java.awt.event.ActionListener() {
360 public void actionPerformed(java.awt.event.ActionEvent evt) {
361 newTypeButtonActionPerformed(evt);
365 editTypeButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/edit16.png")));
366 org.openide.awt.Mnemonics.setLocalizedText(editTypeButton,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.editTypeButton.text"));
367 editTypeButton.addActionListener(
new java.awt.event.ActionListener() {
368 public void actionPerformed(java.awt.event.ActionEvent evt) {
369 editTypeButtonActionPerformed(evt);
373 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(jPanel1);
374 jPanel1.setLayout(jPanel1Layout);
375 jPanel1Layout.setHorizontalGroup(
376 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
377 .addGroup(jPanel1Layout.createSequentialGroup()
379 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
380 .addGroup(jPanel1Layout.createSequentialGroup()
381 .addComponent(newTypeButton)
382 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
383 .addComponent(editTypeButton)
384 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
385 .addComponent(deleteTypeButton))
386 .addComponent(jLabel2)
387 .addComponent(typesScrollPane))
390 jPanel1Layout.setVerticalGroup(
391 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
392 .addGroup(jPanel1Layout.createSequentialGroup()
394 .addComponent(jLabel2)
395 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
396 .addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)
398 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
399 .addComponent(newTypeButton)
400 .addComponent(editTypeButton)
401 .addComponent(deleteTypeButton))
405 jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {deleteTypeButton, newTypeButton});
407 jSplitPane1.setLeftComponent(jPanel1);
409 jPanel2.setMinimumSize(
new java.awt.Dimension(79, 0));
411 org.openide.awt.Mnemonics.setLocalizedText(jLabel1,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.jLabel1.text"));
413 signatureList.setModel(
new javax.swing.AbstractListModel<Signature>() {
414 Signature[] signatures = {};
415 public int getSize() {
return signatures.length; }
416 public Signature getElementAt(
int i) {
return signatures[i]; }
418 signatureList.setEnabled(
false);
419 signatureList.setMaximumSize(
new java.awt.Dimension(32767, 32767));
420 signatureList.setPreferredSize(null);
421 jScrollPane1.setViewportView(signatureList);
423 javax.swing.GroupLayout jPanel2Layout =
new javax.swing.GroupLayout(jPanel2);
424 jPanel2.setLayout(jPanel2Layout);
425 jPanel2Layout.setHorizontalGroup(
426 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
427 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
429 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
430 .addGroup(jPanel2Layout.createSequentialGroup()
431 .addComponent(jLabel1)
432 .addGap(100, 100, 100))
433 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
436 jPanel2Layout.setVerticalGroup(
437 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
438 .addGroup(jPanel2Layout.createSequentialGroup()
440 .addComponent(jLabel1)
441 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
442 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
446 jSplitPane1.setRightComponent(jPanel2);
448 jScrollPane2.setViewportView(jSplitPane1);
450 javax.swing.GroupLayout jPanel3Layout =
new javax.swing.GroupLayout(jPanel3);
451 jPanel3.setLayout(jPanel3Layout);
452 jPanel3Layout.setHorizontalGroup(
453 jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
454 .addGroup(jPanel3Layout.createSequentialGroup()
456 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
457 .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
458 .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
459 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 728, Short.MAX_VALUE))
462 jPanel3Layout.setVerticalGroup(
463 jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
464 .addGroup(jPanel3Layout.createSequentialGroup()
466 .addComponent(jLabel3)
467 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
468 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
469 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
470 .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
474 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
475 this.setLayout(layout);
476 layout.setHorizontalGroup(
477 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
478 .addGroup(layout.createSequentialGroup()
479 .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 752, Short.MAX_VALUE)
482 layout.setVerticalGroup(
483 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
484 .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 507, Short.MAX_VALUE)
488 private void newTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {
489 AddFileTypeDialog dialog =
new AddFileTypeDialog();
491 AddFileTypeDialog.BUTTON_PRESSED result = dialog.getResult();
492 if (result == AddFileTypeDialog.BUTTON_PRESSED.OK) {
493 fileTypes.add(dialog.getFileType());
494 updateFileTypesListModel();
495 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
500 private void deleteTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {
501 FileType fileType = typesList.getSelectedValue();
502 fileTypes.remove(fileType);
503 updateFileTypesListModel();
504 if (!typesListModel.isEmpty()) {
505 typesList.setSelectedIndex(0);
507 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
510 private void editTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {
511 int selected = this.typesList.getSelectedIndex();
512 AddFileTypeDialog dialog =
new AddFileTypeDialog(this.typesListModel.get(
this.typesList.getSelectedIndex()));
514 AddFileTypeDialog.BUTTON_PRESSED result = dialog.getResult();
515 if (result == AddFileTypeDialog.BUTTON_PRESSED.OK) {
516 this.fileTypes.remove(selected);
517 this.fileTypes.add(selected, dialog.getFileType());
518 updateFileTypesListModel();
519 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
524 private javax.swing.JButton deleteTypeButton;
525 private javax.swing.JButton editTypeButton;
526 private javax.swing.JLabel ingestRunningWarningLabel;
527 private javax.swing.JLabel jLabel1;
528 private javax.swing.JLabel jLabel2;
529 private javax.swing.JLabel jLabel3;
530 private javax.swing.JPanel jPanel1;
531 private javax.swing.JPanel jPanel2;
532 private javax.swing.JPanel jPanel3;
533 private javax.swing.JScrollPane jScrollPane1;
534 private javax.swing.JScrollPane jScrollPane2;
535 private javax.swing.JSplitPane jSplitPane1;
536 private javax.swing.JButton newTypeButton;
537 private javax.swing.JList<Signature> signatureList;
538 private javax.swing.JList<FileType> typesList;
539 private javax.swing.JScrollPane typesScrollPane;
void propertyChange(PropertyChangeEvent evt)
static synchronized IngestManager getInstance()
boolean isIngestRunning()