mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Work on user-defined file types UI
This commit is contained in:
parent
a75ebe8028
commit
a9bc43e320
@ -9,7 +9,6 @@ FileTypeIdModuleFactory.createFileIngestModule.exception.msg=Expected settings a
|
|||||||
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification.
|
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=Depending on how many files have known hashes, checking this box will improve the speed of file type identification.
|
||||||
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=Skip known files (NSRL)
|
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=Skip known files (NSRL)
|
||||||
FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text=0x
|
FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text=0x
|
||||||
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Save Type
|
|
||||||
FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=DeleteType
|
FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=DeleteType
|
||||||
FileTypeIdGlobalSettingsPanel.newTypeButton.text=New Type
|
FileTypeIdGlobalSettingsPanel.newTypeButton.text=New Type
|
||||||
FileTypeIdGlobalSettingsPanel.offsetTextField.text=
|
FileTypeIdGlobalSettingsPanel.offsetTextField.text=
|
||||||
@ -21,3 +20,4 @@ FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=Signature Type
|
|||||||
FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text=
|
FileTypeIdGlobalSettingsPanel.mimeTypeTextField.text=
|
||||||
FileTypeIdGlobalSettingsPanel.signatureLabel.text=Signature
|
FileTypeIdGlobalSettingsPanel.signatureLabel.text=Signature
|
||||||
FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=Mime Type
|
FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=Mime Type
|
||||||
|
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Save Type
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
|
||||||
<Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
|
<Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
@ -43,18 +42,17 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Group type="103" groupAlignment="1" max="-2" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="signatureTypeLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="signatureTypeLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="signatureTypeComboBox" min="-2" pref="82" max="-2" attributes="0"/>
|
<Component id="signatureTypeComboBox" min="-2" pref="82" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="signatureLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="signatureLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="hexPrefixLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="hexPrefixLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
@ -77,8 +75,6 @@
|
|||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||||
<Component id="jScrollPane2" min="-2" pref="260" max="-2" attributes="0"/>
|
<Component id="jScrollPane2" min="-2" pref="260" max="-2" attributes="0"/>
|
||||||
@ -88,12 +84,9 @@
|
|||||||
<Component id="postHitCheckBox" min="-2" max="-2" attributes="0"/>
|
<Component id="postHitCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -141,14 +134,14 @@
|
|||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
|
<Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="jSeparator1" min="-2" pref="260" max="-2" attributes="0"/>
|
<Component id="jSeparator1" min="-2" pref="260" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -167,6 +160,9 @@
|
|||||||
<StringArray count="0"/>
|
<StringArray count="0"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||||
|
</AuxValues>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
@ -223,6 +219,9 @@
|
|||||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.newTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.newTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newTypeButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="deleteTypeButton">
|
<Component class="javax.swing.JButton" name="deleteTypeButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -230,6 +229,9 @@
|
|||||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.deleteTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.deleteTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteTypeButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JButton" name="saveTypeButton">
|
<Component class="javax.swing.JButton" name="saveTypeButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -237,6 +239,9 @@
|
|||||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.saveTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.saveTypeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveTypeButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="hexPrefixLabel">
|
<Component class="javax.swing.JLabel" name="hexPrefixLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -248,13 +253,12 @@
|
|||||||
<Component class="javax.swing.JComboBox" name="signatureTypeComboBox">
|
<Component class="javax.swing.JComboBox" name="signatureTypeComboBox">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||||
<StringArray count="3">
|
<StringArray count="0"/>
|
||||||
<StringItem index="0" value="Bytes (Hex)"/>
|
|
||||||
<StringItem index="1" value="String"/>
|
|
||||||
<StringItem index="2" value=" "/>
|
|
||||||
</StringArray>
|
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||||
|
</AuxValues>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="signatureLabel">
|
<Component class="javax.swing.JLabel" name="signatureLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
@ -18,23 +18,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.filetypeid;
|
package org.sleuthkit.autopsy.modules.filetypeid;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.Map;
|
||||||
|
import javax.swing.DefaultComboBoxModel;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||||
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
|
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
|
||||||
import org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A panel to allow a user to make custom file type definitions.
|
* A panel to allow a user to make custom file type definitions.
|
||||||
*/
|
*/
|
||||||
final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
|
final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
|
||||||
|
|
||||||
private final HashMap<String, FileType> fileTypes = new HashMap<>();
|
private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = "Bytes (Hex)"; // RJCTODO: Bundle
|
||||||
private final HashMap<String, FileType> changedFileTypes = new HashMap<>();
|
private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = "String (ASCII)"; // RJCTODO: Bundle
|
||||||
private final HashMap<String, FileType> deletedFileTypes = new HashMap<>();
|
|
||||||
|
/**
|
||||||
|
* This mapping of file type names to file types is used to hold the types
|
||||||
|
* displayed in the file types list component.
|
||||||
|
*/
|
||||||
|
private Map<String, FileType> fileTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a panel to allow a user to make custom file type definitions.
|
* Creates a panel to allow a user to make custom file type definitions.
|
||||||
@ -56,19 +63,38 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
fileTypes.clear();
|
/**
|
||||||
|
* Get the user-defined file types and set up a list model for the file
|
||||||
|
* types list component.
|
||||||
|
*/
|
||||||
|
this.fileTypes = UserDefinedFileTypesManager.getInstance().getUserDefinedFileTypes();
|
||||||
DefaultListModel<String> fileTypesListModel = new DefaultListModel<>();
|
DefaultListModel<String> fileTypesListModel = new DefaultListModel<>();
|
||||||
for (FileType fileType : UserDefinedFileTypesManager.getInstance().getFileTypes()) {
|
for (FileType fileType : this.fileTypes.values()) {
|
||||||
fileTypes.put(fileType.getTypeName(), fileType);
|
|
||||||
fileTypesListModel.addElement(fileType.getTypeName());
|
fileTypesListModel.addElement(fileType.getTypeName());
|
||||||
}
|
}
|
||||||
typesList.setModel(fileTypesListModel);
|
this.typesList.setModel(fileTypesListModel);
|
||||||
|
|
||||||
typesList.addListSelectionListener(new TypesListSelectionListener());
|
/**
|
||||||
|
* Add a selection listener to populate the file type details
|
||||||
|
* display/edit components.
|
||||||
|
*/
|
||||||
|
this.typesList.addListSelectionListener(new TypesListSelectionListener());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is at least one user-defined file type, select it the file
|
||||||
|
* types list component.
|
||||||
|
*/
|
||||||
if (!fileTypesListModel.isEmpty()) {
|
if (!fileTypesListModel.isEmpty()) {
|
||||||
typesList.setSelectedIndex(0);
|
this.typesList.setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a model for the signature type combo box component.
|
||||||
|
*/
|
||||||
|
DefaultComboBoxModel<String> sigTypeComboBoxModel = new DefaultComboBoxModel<>();
|
||||||
|
sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
|
||||||
|
sigTypeComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
|
||||||
|
this.signatureTypeComboBox.setModel(sigTypeComboBoxModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,10 +103,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
@Override
|
@Override
|
||||||
public void store() {
|
public void store() {
|
||||||
try {
|
try {
|
||||||
UserDefinedFileTypesManager fileTypesManager = UserDefinedFileTypesManager.getInstance();
|
UserDefinedFileTypesManager.getInstance().setUserDefinedFileTypes(this.fileTypes);
|
||||||
fileTypesManager.addFileTypes(changedFileTypes.values());
|
} catch (UserDefinedFileTypesManager.UserDefinedFileTypesException ex) {
|
||||||
fileTypesManager.deleteFileTypes(deletedFileTypes.values());
|
|
||||||
} catch (UserDefinedFileTypesException ex) {
|
|
||||||
// RJCTODO
|
// RJCTODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,22 +114,36 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
@Override
|
@Override
|
||||||
public void valueChanged(ListSelectionEvent e) {
|
public void valueChanged(ListSelectionEvent e) {
|
||||||
if (e.getValueIsAdjusting() == false) {
|
if (e.getValueIsAdjusting() == false) {
|
||||||
if (typesList.getSelectedIndex() == -1) {
|
if (FileTypeIdGlobalSettingsPanel.this.typesList.getSelectedIndex() == -1) {
|
||||||
deleteTypeButton.setEnabled(false);
|
FileTypeIdGlobalSettingsPanel.this.deleteTypeButton.setEnabled(false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String typeName = (String) typesList.getSelectedValue();
|
String typeName = FileTypeIdGlobalSettingsPanel.this.typesList.getSelectedValue();
|
||||||
FileType fileType = fileTypes.get(typeName);
|
FileType fileType = FileTypeIdGlobalSettingsPanel.this.fileTypes.get(typeName);
|
||||||
Signature signature = fileType.getSignature();
|
Signature signature = fileType.getSignature();
|
||||||
mimeTypeTextField.setText(typeName);
|
FileTypeIdGlobalSettingsPanel.this.mimeTypeTextField.setText(typeName);
|
||||||
offsetTextField.setText(Long.toString(signature.getOffset()));
|
FileType.Signature.Type sigType = fileType.getSignature().getType();
|
||||||
deleteTypeButton.setEnabled(true);
|
FileTypeIdGlobalSettingsPanel.this.signatureTypeComboBox.setSelectedItem(sigType == FileType.Signature.Type.RAW ? FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM);
|
||||||
|
FileTypeIdGlobalSettingsPanel.this.offsetTextField.setText(Long.toString(signature.getOffset()));
|
||||||
|
FileTypeIdGlobalSettingsPanel.this.postHitCheckBox.setSelected(fileType.alertOnMatch());
|
||||||
|
FileTypeIdGlobalSettingsPanel.this.deleteTypeButton.setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RJCTODO: Consider fixing OptinsPanel interface or writing story
|
/**
|
||||||
|
* RJCTODO
|
||||||
|
*/
|
||||||
|
private void clearTypeDetailsComponents() {
|
||||||
|
this.typesList.setSelectedIndex(-1);
|
||||||
|
this.mimeTypeTextField.setText(""); //NON-NLS // RJCTODO: Default name?
|
||||||
|
this.signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
|
||||||
|
this.signatureTextField.setText(""); //NON-NLS
|
||||||
|
this.offsetTextField.setText(""); //NON-NLS
|
||||||
|
this.postHitCheckBox.setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RJCTODO: Consider fixing OptionsPanel interface or writing story
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* 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
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -117,7 +155,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
|
|
||||||
buttonGroup1 = new javax.swing.ButtonGroup();
|
buttonGroup1 = new javax.swing.ButtonGroup();
|
||||||
typesScrollPane = new javax.swing.JScrollPane();
|
typesScrollPane = new javax.swing.JScrollPane();
|
||||||
typesList = new javax.swing.JList();
|
typesList = new javax.swing.JList<String>();
|
||||||
jSeparator1 = new javax.swing.JSeparator();
|
jSeparator1 = new javax.swing.JSeparator();
|
||||||
mimeTypeLabel = new javax.swing.JLabel();
|
mimeTypeLabel = new javax.swing.JLabel();
|
||||||
mimeTypeTextField = new javax.swing.JTextField();
|
mimeTypeTextField = new javax.swing.JTextField();
|
||||||
@ -129,7 +167,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
deleteTypeButton = new javax.swing.JButton();
|
deleteTypeButton = new javax.swing.JButton();
|
||||||
saveTypeButton = new javax.swing.JButton();
|
saveTypeButton = new javax.swing.JButton();
|
||||||
hexPrefixLabel = new javax.swing.JLabel();
|
hexPrefixLabel = new javax.swing.JLabel();
|
||||||
signatureTypeComboBox = new javax.swing.JComboBox();
|
signatureTypeComboBox = new javax.swing.JComboBox<String>();
|
||||||
signatureLabel = new javax.swing.JLabel();
|
signatureLabel = new javax.swing.JLabel();
|
||||||
jScrollPane2 = new javax.swing.JScrollPane();
|
jScrollPane2 = new javax.swing.JScrollPane();
|
||||||
jTextArea1 = new javax.swing.JTextArea();
|
jTextArea1 = new javax.swing.JTextArea();
|
||||||
@ -152,15 +190,28 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
offsetTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetTextField.text")); // NOI18N
|
offsetTextField.setText(org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetTextField.text")); // NOI18N
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(newTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.newTypeButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(newTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.newTypeButton.text")); // NOI18N
|
||||||
|
newTypeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
newTypeButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(deleteTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteTypeButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(deleteTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.deleteTypeButton.text")); // NOI18N
|
||||||
|
deleteTypeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
deleteTypeButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(saveTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.saveTypeButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(saveTypeButton, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.saveTypeButton.text")); // NOI18N
|
||||||
|
saveTypeButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
saveTypeButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(hexPrefixLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(hexPrefixLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.hexPrefixLabel.text")); // NOI18N
|
||||||
|
|
||||||
signatureTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Bytes (Hex)", "String", " " }));
|
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(signatureLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(signatureLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureLabel.text")); // NOI18N
|
||||||
|
|
||||||
jTextArea1.setEditable(false);
|
jTextArea1.setEditable(false);
|
||||||
@ -190,25 +241,23 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(37, 37, 37)
|
.addGap(37, 37, 37)
|
||||||
.addComponent(saveTypeButton)
|
.addComponent(saveTypeButton))
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(18, 18, 18)
|
.addGap(18, 18, 18)
|
||||||
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||||
.addComponent(signatureTypeLabel)
|
.addComponent(signatureTypeLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGap(0, 0, Short.MAX_VALUE))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(signatureLabel)
|
.addComponent(signatureLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(hexPrefixLabel)
|
.addComponent(hexPrefixLabel)
|
||||||
.addGap(2, 2, 2))
|
.addGap(2, 2, 2))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
@ -223,16 +272,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
.addComponent(mimeTypeLabel)
|
.addComponent(mimeTypeLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 181, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
.addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 181, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(6, 6, 6)
|
.addGap(6, 6, 6)
|
||||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(postHitCheckBox)))
|
.addComponent(postHitCheckBox)))))
|
||||||
.addGap(0, 0, Short.MAX_VALUE)))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
.addContainerGap())))
|
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -270,13 +316,50 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
.addComponent(newTypeButton)
|
.addComponent(newTypeButton)
|
||||||
.addComponent(deleteTypeButton)))
|
.addComponent(deleteTypeButton)))
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(saveTypeButton))))
|
.addComponent(saveTypeButton))))
|
||||||
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 260, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void newTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTypeButtonActionPerformed
|
||||||
|
this.clearTypeDetailsComponents();
|
||||||
|
// RJCTODO: Default name?
|
||||||
|
}//GEN-LAST:event_newTypeButtonActionPerformed
|
||||||
|
|
||||||
|
private void deleteTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTypeButtonActionPerformed
|
||||||
|
String typeName = this.typesList.getSelectedValue();
|
||||||
|
this.fileTypes.remove(typeName);
|
||||||
|
this.clearTypeDetailsComponents();
|
||||||
|
this.typesList.setSelectedIndex(-1);
|
||||||
|
}//GEN-LAST:event_deleteTypeButtonActionPerformed
|
||||||
|
|
||||||
|
private void saveTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTypeButtonActionPerformed
|
||||||
|
try {
|
||||||
|
String typeName = this.mimeTypeTextField.getText();
|
||||||
|
if (typeName.isEmpty()) {
|
||||||
|
JOptionPane.showMessageDialog(null, "MIME type name cannot be empty.", "Missing MIME Type", JOptionPane.ERROR_MESSAGE); // RJCTODO: Bundle
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String sigString = this.signatureTextField.getText();
|
||||||
|
if (sigString.isEmpty()) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Signature cannot be empty.", "Missing Signature", JOptionPane.ERROR_MESSAGE); // RJCTODO: Bundle
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long offset = Long.parseUnsignedLong(this.offsetTextField.getText());
|
||||||
|
|
||||||
|
FileType.Signature.Type sigType = this.signatureTypeComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM ? FileType.Signature.Type.RAW : FileType.Signature.Type.ASCII;
|
||||||
|
FileType.Signature signature = new FileType.Signature(new byte[1], offset, sigType); // RJCTODO:
|
||||||
|
FileType fileType = new FileType(typeName, signature, this.postHitCheckBox.isSelected());
|
||||||
|
this.fileTypes.put(typeName, fileType);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Offset is not a positive integer.", "Invalid Offset", JOptionPane.ERROR_MESSAGE); // RJCTODO: Bundle
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_saveTypeButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.ButtonGroup buttonGroup1;
|
private javax.swing.ButtonGroup buttonGroup1;
|
||||||
@ -294,9 +377,9 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
|
|||||||
private javax.swing.JButton saveTypeButton;
|
private javax.swing.JButton saveTypeButton;
|
||||||
private javax.swing.JLabel signatureLabel;
|
private javax.swing.JLabel signatureLabel;
|
||||||
private javax.swing.JTextField signatureTextField;
|
private javax.swing.JTextField signatureTextField;
|
||||||
private javax.swing.JComboBox signatureTypeComboBox;
|
private javax.swing.JComboBox<String> signatureTypeComboBox;
|
||||||
private javax.swing.JLabel signatureTypeLabel;
|
private javax.swing.JLabel signatureTypeLabel;
|
||||||
private javax.swing.JList typesList;
|
private javax.swing.JList<String> typesList;
|
||||||
private javax.swing.JScrollPane typesScrollPane;
|
private javax.swing.JScrollPane typesScrollPane;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
@ -18,8 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.filetypeid;
|
package org.sleuthkit.autopsy.modules.filetypeid;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Map;
|
||||||
import java.util.List;
|
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,16 +26,14 @@ import org.sleuthkit.datamodel.AbstractFile;
|
|||||||
*/
|
*/
|
||||||
final class UserDefinedFileTypeIdentifier {
|
final class UserDefinedFileTypeIdentifier {
|
||||||
|
|
||||||
private final List<FileType> fileTypes;
|
private final Map<String, FileType> fileTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an object that can do file type identification for user-defined
|
* Creates an object that can do file type identification for user-defined
|
||||||
* file types.
|
* file types.
|
||||||
*/
|
*/
|
||||||
UserDefinedFileTypeIdentifier() {
|
UserDefinedFileTypeIdentifier() {
|
||||||
this.fileTypes = new ArrayList<>();
|
this.fileTypes = UserDefinedFileTypesManager.getInstance().getFileTypes();
|
||||||
List<FileType> fileTypeDefs = UserDefinedFileTypesManager.getInstance().getFileTypes();
|
|
||||||
this.fileTypes.addAll(fileTypeDefs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +45,7 @@ final class UserDefinedFileTypeIdentifier {
|
|||||||
*/
|
*/
|
||||||
FileType identify(final AbstractFile file) {
|
FileType identify(final AbstractFile file) {
|
||||||
FileType type = null;
|
FileType type = null;
|
||||||
for (FileType fileType : this.fileTypes) {
|
for (FileType fileType : this.fileTypes.values()) {
|
||||||
if (fileType.matches(file)) {
|
if (fileType.matches(file)) {
|
||||||
type = fileType;
|
type = fileType;
|
||||||
break;
|
break;
|
||||||
|
@ -62,6 +62,13 @@ final class UserDefinedFileTypesManager {
|
|||||||
private static final String ASCII_ENCODING = "US-ASCII"; //NON-NLS
|
private static final String ASCII_ENCODING = "US-ASCII"; //NON-NLS
|
||||||
private static UserDefinedFileTypesManager instance;
|
private static UserDefinedFileTypesManager instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predefined file types are stored in this mapping of file type names to
|
||||||
|
* file types. Access to this map is guarded by the intrinsic lock of the
|
||||||
|
* user-defined file types manager for thread-safety.
|
||||||
|
*/
|
||||||
|
private final Map<String, FileType> predefinedFileTypes = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-defined file types to be persisted to the user-defined file type
|
* User-defined file types to be persisted to the user-defined file type
|
||||||
* definitions file are stored in this mapping of file type names to file
|
* definitions file are stored in this mapping of file type names to file
|
||||||
@ -96,6 +103,10 @@ final class UserDefinedFileTypesManager {
|
|||||||
* (e.g., MIME type) and signatures.
|
* (e.g., MIME type) and signatures.
|
||||||
*/
|
*/
|
||||||
private UserDefinedFileTypesManager() {
|
private UserDefinedFileTypesManager() {
|
||||||
|
/**
|
||||||
|
* Load the predefined types first so that they can be overwritten by
|
||||||
|
* any user-defined types with the same names.
|
||||||
|
*/
|
||||||
loadPredefinedFileTypes();
|
loadPredefinedFileTypes();
|
||||||
loadUserDefinedFileTypes();
|
loadUserDefinedFileTypes();
|
||||||
}
|
}
|
||||||
@ -109,14 +120,16 @@ final class UserDefinedFileTypesManager {
|
|||||||
/**
|
/**
|
||||||
* Create a file type that should match $MBR in Small2 image.
|
* Create a file type that should match $MBR in Small2 image.
|
||||||
*/
|
*/
|
||||||
this.fileTypes.put("predefinedRAW", new FileType("predefinedRAW", new Signature(new byte[]{(byte) 0x66, (byte) 0x73, (byte) 0x00}, 8L, FileType.Signature.Type.RAW), true));
|
FileType fileType = new FileType("predefinedRAW", new Signature(new byte[]{(byte) 0x66, (byte) 0x73, (byte) 0x00}, 8L, FileType.Signature.Type.RAW), true);
|
||||||
|
this.addPredefinedFileType(fileType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a file type that should match test.txt in the Small2 image.
|
* Create a file type that should match test.txt in the Small2 image.
|
||||||
*/
|
*/
|
||||||
// RJCTODO: Remove test type
|
// RJCTODO: Remove test type
|
||||||
try {
|
try {
|
||||||
this.fileTypes.put("predefinedASCII", new FileType("predefinedASCII", new Signature("hello".getBytes(UserDefinedFileTypesManager.ASCII_ENCODING), 0L, FileType.Signature.Type.ASCII), true));
|
fileType = new FileType("predefinedASCII", new Signature("hello".getBytes(UserDefinedFileTypesManager.ASCII_ENCODING), 0L, FileType.Signature.Type.ASCII), true);
|
||||||
|
this.addPredefinedFileType(fileType);
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Unable to create 'predefinedASCII' predefined file type definition", ex); //NON-NLS
|
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Unable to create 'predefinedASCII' predefined file type definition", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
@ -144,16 +157,28 @@ final class UserDefinedFileTypesManager {
|
|||||||
// catch (IndexOutOfBoundsException e) {
|
// catch (IndexOutOfBoundsException e) {
|
||||||
// // do nothing
|
// // do nothing
|
||||||
// }
|
// }
|
||||||
this.fileTypes.put("text/xml", new FileType("text/xml", new Signature("<?xml".getBytes(UserDefinedFileTypesManager.ASCII_ENCODING), 0L, FileType.Signature.Type.ASCII), false));
|
fileType = new FileType("text/xml", new Signature("<?xml".getBytes(UserDefinedFileTypesManager.ASCII_ENCODING), 0L, FileType.Signature.Type.ASCII), false);
|
||||||
|
this.addPredefinedFileType(fileType);
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
/**
|
/**
|
||||||
* Using an all-or-none strategy.
|
* Using an all-or-none policy.
|
||||||
*/
|
*/
|
||||||
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Unable to create predefined file type definitions", ex); //NON-NLS
|
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Unable to create predefined file type definitions", ex); //NON-NLS
|
||||||
this.fileTypes.clear();
|
this.fileTypes.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a file type to the the predefined file types and combined file types
|
||||||
|
* maps.
|
||||||
|
*
|
||||||
|
* @param fileType The file type to add.
|
||||||
|
*/
|
||||||
|
private void addPredefinedFileType(FileType fileType) {
|
||||||
|
this.predefinedFileTypes.put(fileType.getTypeName(), fileType);
|
||||||
|
this.fileTypes.put(fileType.getTypeName(), fileType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads user-defined file types into an in-memory mapping of file type
|
* Reads user-defined file types into an in-memory mapping of file type
|
||||||
* names to file types.
|
* names to file types.
|
||||||
@ -164,14 +189,13 @@ final class UserDefinedFileTypesManager {
|
|||||||
File file = new File(filePath);
|
File file = new File(filePath);
|
||||||
if (file.exists() && file.canRead()) {
|
if (file.exists() && file.canRead()) {
|
||||||
for (FileType fileType : XMLReader.readFileTypes(filePath)) {
|
for (FileType fileType : XMLReader.readFileTypes(filePath)) {
|
||||||
this.userDefinedFileTypes.put(fileType.getTypeName(), fileType);
|
this.addUserDefinedFileType(fileType);
|
||||||
this.fileTypes.put(fileType.getTypeName(), fileType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (UserDefinedFileTypesManager.InvalidXMLException ex) {
|
} catch (UserDefinedFileTypesManager.InvalidXMLException ex) {
|
||||||
/**
|
/**
|
||||||
* Using an all-or-none strategy.
|
* Using an all-or-none policy.
|
||||||
*/
|
*/
|
||||||
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Unable to load user-defined types", ex); //NON-NLS
|
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Unable to load user-defined types", ex); //NON-NLS
|
||||||
this.fileTypes.clear();
|
this.fileTypes.clear();
|
||||||
@ -180,101 +204,79 @@ final class UserDefinedFileTypesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the user-defined file types.
|
* Adds a file type to the the user-defined file types and combined file
|
||||||
|
* types maps.
|
||||||
|
*
|
||||||
|
* @param fileType The file type to add.
|
||||||
|
*/
|
||||||
|
private void addUserDefinedFileType(FileType fileType) {
|
||||||
|
this.userDefinedFileTypes.put(fileType.getTypeName(), fileType);
|
||||||
|
this.fileTypes.put(fileType.getTypeName(), fileType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets both the predefined and the user-defined file types.
|
||||||
*
|
*
|
||||||
* @return A mapping of file type names to file types, possibly empty.
|
* @return A mapping of file type names to file types, possibly empty.
|
||||||
*/
|
*/
|
||||||
synchronized List<FileType> getFileTypes() {
|
synchronized Map<String, FileType> getFileTypes() {
|
||||||
/**
|
/**
|
||||||
* It is safe to return references to the internal file type objects
|
* It is safe to return references to the internal file type objects
|
||||||
* because they are immutable.
|
* because they are immutable.
|
||||||
*/
|
*/
|
||||||
return new ArrayList<>(this.fileTypes.values());
|
return new HashMap<>(this.fileTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new user-defined file type, overwriting any existing file type
|
* Gets the user-defined file types.
|
||||||
* with the same type name.
|
|
||||||
*
|
*
|
||||||
* @param fileType The file type to add.
|
* @return A mapping of file type names to file types, possibly empty.
|
||||||
* @throws
|
|
||||||
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
|
||||||
*/
|
*/
|
||||||
synchronized void addFileType(FileType fileType) throws UserDefinedFileTypesException {
|
synchronized Map<String, FileType> getUserDefinedFileTypes() {
|
||||||
this.addFileTypes(Collections.singletonList(fileType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a collection of new user-defined file types, overwriting any
|
* It is safe to return references to the internal file type objects
|
||||||
* existing file types with the same type names.
|
|
||||||
*
|
|
||||||
* @param newFileTypes The file types to add.
|
|
||||||
* @throws
|
|
||||||
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
|
||||||
*/
|
|
||||||
synchronized void addFileTypes(Collection<FileType> newFileTypes) throws UserDefinedFileTypesException {
|
|
||||||
/**
|
|
||||||
* It is safe to hold references to client-constructed file type objects
|
|
||||||
* because they are immutable.
|
* because they are immutable.
|
||||||
*/
|
*/
|
||||||
for (FileType fileType : newFileTypes) {
|
return new HashMap<>(this.userDefinedFileTypes);
|
||||||
this.userDefinedFileTypes.put(fileType.getTypeName(), fileType);
|
|
||||||
this.fileTypes.put(fileType.getTypeName(), fileType);
|
|
||||||
}
|
|
||||||
this.saveUserDefinedTypes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a user-defined file type.
|
* Sets the user-defined file types.
|
||||||
*
|
*
|
||||||
* @param fileType The file type to delete.
|
* @param newFileTypes A mapping of file type names to user-defined
|
||||||
|
* file types.
|
||||||
* @throws
|
* @throws
|
||||||
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
||||||
*/
|
*/
|
||||||
synchronized void deleteFileType(FileType fileType) throws UserDefinedFileTypesException {
|
synchronized void setUserDefinedFileTypes(Map<String, FileType> newFileTypes) throws UserDefinedFileTypesManager.UserDefinedFileTypesException {
|
||||||
this.deleteFileTypes(Collections.singletonList(fileType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a set of user-defined file types.
|
|
||||||
*
|
|
||||||
* @param deletedFileTypes The file types to delete.
|
|
||||||
* @throws
|
|
||||||
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
|
||||||
*/
|
|
||||||
synchronized void deleteFileTypes(Collection<FileType> deletedFileTypes) throws UserDefinedFileTypesException {
|
|
||||||
for (FileType fileType : deletedFileTypes) {
|
|
||||||
this.userDefinedFileTypes.remove(fileType.getTypeName(), fileType);
|
|
||||||
this.fileTypes.remove(fileType.getTypeName(), fileType);
|
|
||||||
}
|
|
||||||
this.saveUserDefinedTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Persists the user-defined file type definitions.
|
|
||||||
*
|
|
||||||
* @throws
|
|
||||||
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
|
||||||
*/
|
|
||||||
private void saveUserDefinedTypes() throws UserDefinedFileTypesException {
|
|
||||||
String filePath = UserDefinedFileTypesManager.getFileTypeDefinitionsFilePath(UserDefinedFileTypesManager.USER_DEFINED_TYPE_DEFINITIONS_FILE);
|
|
||||||
UserDefinedFileTypesManager.writeFileTypes(this.userDefinedFileTypes.values(), filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a set of file type definitions to a given file.
|
|
||||||
*
|
|
||||||
* @param fileTypes The file types.
|
|
||||||
* @param filePath The destination file.
|
|
||||||
* @throws UserDefinedFileTypesException
|
|
||||||
*/
|
|
||||||
private static void writeFileTypes(Collection<FileType> fileTypes, String filePath) throws UserDefinedFileTypesException {
|
|
||||||
try {
|
try {
|
||||||
UserDefinedFileTypesManager.XMLWriter.writeFileTypes(fileTypes, filePath);
|
/**
|
||||||
|
* Persist the user-defined file type definitions.
|
||||||
|
*/
|
||||||
|
String filePath = UserDefinedFileTypesManager.getFileTypeDefinitionsFilePath(UserDefinedFileTypesManager.USER_DEFINED_TYPE_DEFINITIONS_FILE);
|
||||||
|
UserDefinedFileTypesManager.XMLWriter.writeFileTypes(newFileTypes.values(), filePath);
|
||||||
|
|
||||||
} catch (ParserConfigurationException | IOException ex) {
|
} catch (ParserConfigurationException | IOException ex) {
|
||||||
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Failed to write file types file", ex);
|
UserDefinedFileTypesManager.logger.log(Level.SEVERE, "Failed to write file types file", ex);
|
||||||
throw new UserDefinedFileTypesManager.UserDefinedFileTypesException(ex.getLocalizedMessage()); // RJCTODO: Create a bundled message
|
throw new UserDefinedFileTypesManager.UserDefinedFileTypesException(ex.getLocalizedMessage()); // RJCTODO: Create a bundled message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear and reinitialize the user-defined file type map. It is safe to
|
||||||
|
* hold references to file type objects obtained for the caller because
|
||||||
|
* they are immutable.
|
||||||
|
*/
|
||||||
|
this.userDefinedFileTypes.clear();
|
||||||
|
this.userDefinedFileTypes.putAll(newFileTypes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear and reinitialize the combined file type map, loading the
|
||||||
|
* predefined types first so that they can be overwritten by any
|
||||||
|
* user-defined types with the same names.
|
||||||
|
*/
|
||||||
|
this.fileTypes.clear();
|
||||||
|
this.fileTypes.putAll(this.predefinedFileTypes);
|
||||||
|
this.fileTypes.putAll(this.userDefinedFileTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user