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 descriptionLabel =
new javax.swing.JLabel();
304 jScrollPane2 =
new javax.swing.JScrollPane();
305 jSplitPane1 =
new javax.swing.JSplitPane();
306 jPanel1 =
new javax.swing.JPanel();
307 customTypesLabel =
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 signaturesLabel =
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.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/modules/filetypeid/warning16.png")));
324 org.openide.awt.Mnemonics.setLocalizedText(ingestRunningWarningLabel,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text"));
326 org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.descriptionLabel.text"));
328 jScrollPane2.setMinimumSize(
new java.awt.Dimension(300, 0));
329 jScrollPane2.setPreferredSize(
new java.awt.Dimension(550, 275));
331 jSplitPane1.setDividerSize(1);
332 jSplitPane1.setMinimumSize(
new java.awt.Dimension(0, 0));
334 jPanel1.setMinimumSize(
new java.awt.Dimension(362, 0));
335 jPanel1.setPreferredSize(
new java.awt.Dimension(362, 0));
337 org.openide.awt.Mnemonics.setLocalizedText(customTypesLabel,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.customTypesLabel.text"));
339 typesList.setMaximumSize(
new java.awt.Dimension(150, 0));
340 typesList.setMinimumSize(
new java.awt.Dimension(150, 0));
341 typesScrollPane.setViewportView(typesList);
343 deleteTypeButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/delete16.png")));
344 org.openide.awt.Mnemonics.setLocalizedText(deleteTypeButton,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.deleteTypeButton.text"));
345 deleteTypeButton.addActionListener(
new java.awt.event.ActionListener() {
346 public void actionPerformed(java.awt.event.ActionEvent evt) {
347 deleteTypeButtonActionPerformed(evt);
351 newTypeButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/add16.png")));
352 org.openide.awt.Mnemonics.setLocalizedText(newTypeButton,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.newTypeButton.text"));
353 newTypeButton.addActionListener(
new java.awt.event.ActionListener() {
354 public void actionPerformed(java.awt.event.ActionEvent evt) {
355 newTypeButtonActionPerformed(evt);
359 editTypeButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/edit16.png")));
360 org.openide.awt.Mnemonics.setLocalizedText(editTypeButton,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.editTypeButton.text"));
361 editTypeButton.addActionListener(
new java.awt.event.ActionListener() {
362 public void actionPerformed(java.awt.event.ActionEvent evt) {
363 editTypeButtonActionPerformed(evt);
367 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(jPanel1);
368 jPanel1.setLayout(jPanel1Layout);
369 jPanel1Layout.setHorizontalGroup(
370 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
371 .addGroup(jPanel1Layout.createSequentialGroup()
373 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
374 .addGroup(jPanel1Layout.createSequentialGroup()
375 .addComponent(newTypeButton)
376 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
377 .addComponent(editTypeButton)
378 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
379 .addComponent(deleteTypeButton))
380 .addComponent(customTypesLabel)
381 .addComponent(typesScrollPane))
384 jPanel1Layout.setVerticalGroup(
385 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
386 .addGroup(jPanel1Layout.createSequentialGroup()
388 .addComponent(customTypesLabel)
389 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
390 .addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)
392 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
393 .addComponent(newTypeButton)
394 .addComponent(editTypeButton)
395 .addComponent(deleteTypeButton))
399 jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL,
new java.awt.Component[] {deleteTypeButton, newTypeButton});
401 jSplitPane1.setLeftComponent(jPanel1);
403 jPanel2.setMinimumSize(
new java.awt.Dimension(79, 0));
405 org.openide.awt.Mnemonics.setLocalizedText(signaturesLabel,
org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class,
"FileTypeIdGlobalSettingsPanel.signaturesLabel.text"));
407 signatureList.setModel(
new javax.swing.AbstractListModel<Signature>() {
408 Signature[] signatures = {};
409 public int getSize() {
return signatures.length; }
410 public Signature getElementAt(
int i) {
return signatures[i]; }
412 signatureList.setEnabled(
false);
413 signatureList.setMaximumSize(
new java.awt.Dimension(32767, 32767));
414 signatureList.setPreferredSize(null);
415 jScrollPane1.setViewportView(signatureList);
417 javax.swing.GroupLayout jPanel2Layout =
new javax.swing.GroupLayout(jPanel2);
418 jPanel2.setLayout(jPanel2Layout);
419 jPanel2Layout.setHorizontalGroup(
420 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
421 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
423 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
424 .addGroup(jPanel2Layout.createSequentialGroup()
425 .addComponent(signaturesLabel)
426 .addGap(100, 100, 100))
427 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
430 jPanel2Layout.setVerticalGroup(
431 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
432 .addGroup(jPanel2Layout.createSequentialGroup()
434 .addComponent(signaturesLabel)
435 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
436 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
440 jSplitPane1.setRightComponent(jPanel2);
442 jScrollPane2.setViewportView(jSplitPane1);
444 javax.swing.GroupLayout jPanel3Layout =
new javax.swing.GroupLayout(jPanel3);
445 jPanel3.setLayout(jPanel3Layout);
446 jPanel3Layout.setHorizontalGroup(
447 jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
448 .addGroup(jPanel3Layout.createSequentialGroup()
450 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
451 .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
452 .addComponent(descriptionLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
453 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 728, Short.MAX_VALUE))
456 jPanel3Layout.setVerticalGroup(
457 jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
458 .addGroup(jPanel3Layout.createSequentialGroup()
460 .addComponent(descriptionLabel)
461 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
462 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)
463 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
464 .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
468 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
469 this.setLayout(layout);
470 layout.setHorizontalGroup(
471 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
472 .addGroup(layout.createSequentialGroup()
473 .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 752, Short.MAX_VALUE)
476 layout.setVerticalGroup(
477 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
478 .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 507, Short.MAX_VALUE)
482 private void newTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {
483 AddFileTypeDialog dialog =
new AddFileTypeDialog();
485 AddFileTypeDialog.BUTTON_PRESSED result = dialog.getResult();
486 if (result == AddFileTypeDialog.BUTTON_PRESSED.OK) {
487 fileTypes.add(dialog.getFileType());
488 updateFileTypesListModel();
489 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
494 private void deleteTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {
495 FileType fileType = typesList.getSelectedValue();
496 fileTypes.remove(fileType);
497 updateFileTypesListModel();
498 if (!typesListModel.isEmpty()) {
499 typesList.setSelectedIndex(0);
501 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
504 private void editTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {
505 int selected = this.typesList.getSelectedIndex();
506 AddFileTypeDialog dialog =
new AddFileTypeDialog(this.typesListModel.get(
this.typesList.getSelectedIndex()));
508 AddFileTypeDialog.BUTTON_PRESSED result = dialog.getResult();
509 if (result == AddFileTypeDialog.BUTTON_PRESSED.OK) {
510 this.fileTypes.remove(selected);
511 this.fileTypes.add(selected, dialog.getFileType());
512 updateFileTypesListModel();
513 firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
518 private javax.swing.JLabel customTypesLabel;
519 private javax.swing.JButton deleteTypeButton;
520 private javax.swing.JLabel descriptionLabel;
521 private javax.swing.JButton editTypeButton;
522 private javax.swing.JLabel ingestRunningWarningLabel;
523 private javax.swing.JPanel jPanel1;
524 private javax.swing.JPanel jPanel2;
525 private javax.swing.JPanel jPanel3;
526 private javax.swing.JScrollPane jScrollPane1;
527 private javax.swing.JScrollPane jScrollPane2;
528 private javax.swing.JSplitPane jSplitPane1;
529 private javax.swing.JButton newTypeButton;
530 private javax.swing.JList<Signature> signatureList;
531 private javax.swing.JLabel signaturesLabel;
532 private javax.swing.JList<FileType> typesList;
533 private javax.swing.JScrollPane typesScrollPane;
void propertyChange(PropertyChangeEvent evt)
static synchronized IngestManager getInstance()
boolean isIngestRunning()