Eliminate duplicated merges and sorts of MIME type names

This commit is contained in:
Richard Cordovano
2017-06-01 12:49:06 -04:00
parent 4d88b017f8
commit be239a2b1b
5 changed files with 142 additions and 174 deletions
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,12 +19,9 @@
package org.sleuthkit.autopsy.filesearch;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
@@ -39,40 +36,20 @@ public class MimeTypePanel extends javax.swing.JPanel {
public MimeTypePanel() {
initComponents();
setComponentsEnabled();
this.mimeTypeList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
this.mimeTypeList.addListSelectionListener((ListSelectionEvent e) -> {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
});
}
private String[] getMimeTypeArray() {
Set<String> fileTypesCollated = new HashSet<>();
for (String mediaType : FileTypeDetector.getStandardDetectedTypes()) {
fileTypesCollated.add(mediaType);
}
FileTypeDetector fileTypeDetector;
List<String> mimeTypesList = new ArrayList<>();
try {
fileTypeDetector = new FileTypeDetector();
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
fileTypesCollated.addAll(userDefinedFileTypes);
mimeTypesList.addAll(FileTypeDetector.getDetectedTypes());
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
logger.log(Level.SEVERE, "Unable to get user defined file types", ex);
logger.log(Level.SEVERE, "Unable to get detectable file types", ex);
}
List<String> toSort = new ArrayList<>(fileTypesCollated);
toSort.sort((String string1, String string2) -> {
int result = String.CASE_INSENSITIVE_ORDER.compare(string1, string2);
if (result == 0) {
result = string1.compareTo(string2);
}
return result;
});
String[] mimeTypeArray = new String[toSort.size()];
return toSort.toArray(mimeTypeArray);
String[] mimeTypeArray = new String[mimeTypesList.size()];
return mimeTypesList.toArray(mimeTypeArray);
}
List<String> getMimeTypesSelected() {
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,7 +41,9 @@ import org.sleuthkit.datamodel.TskData;
/**
* Detects the MIME type of a file by an inspection of its contents, using
* custom file type definitions by users, custom file type definitions by
* Autopsy, and Tika.
* Autopsy, and Tika. User file type definitions take precedence over both
* Autopsy file type definitions and Tika, and Autopsy file type definitions
* take precendence over Tika.
*/
public class FileTypeDetector {
@@ -51,14 +53,67 @@ public class FileTypeDetector {
private final byte buffer[] = new byte[BUFFER_SIZE];
private final List<FileType> userDefinedFileTypes;
private final List<FileType> autopsyDefinedFileTypes;
private static SortedSet<String> detectedTypes; //no optional parameters
private static SortedSet<String> tikaDetectedTypes;
/**
* Gets a sorted set of the file types that can be detected: the MIME types
* detected by Tika (without optional parameters), the custom MIME types
* defined by Autopsy, and any custom MIME types defined by the user.
*
* @return A list of all detectable file types.
*
* @throws FileTypeDetectorInitException If an error occurs while assembling
* the list of types
*/
public static synchronized SortedSet<String> getDetectedTypes() throws FileTypeDetectorInitException {
TreeSet<String> detectedTypes = new TreeSet<>((String string1, String string2) -> {
int result = String.CASE_INSENSITIVE_ORDER.compare(string1, string2);
if (result == 0) {
result = string1.compareTo(string2);
}
return result;
});
detectedTypes.addAll(FileTypeDetector.getTikaDetectedTypes());
try {
for (FileType fileType : CustomFileTypesManager.getInstance().getAutopsyDefinedFileTypes()) {
detectedTypes.add(fileType.getMimeType());
}
} catch (CustomFileTypesManager.CustomFileTypesException ex) {
throw new FileTypeDetectorInitException("Error loading Autopsy custom file types", ex);
}
try {
for (FileType fileType : CustomFileTypesManager.getInstance().getUserDefinedFileTypes()) {
detectedTypes.add(fileType.getMimeType());
}
} catch (CustomFileTypesManager.CustomFileTypesException ex) {
throw new FileTypeDetectorInitException("Error loading user custom file types", ex);
}
return detectedTypes;
}
/**
* Gets a sorted set of the MIME types detected by Tika (without optional
* parameters).
*
* @return A list of all detectable non-custom file types.
*
*/
private static SortedSet<String> getTikaDetectedTypes() {
if (null == tikaDetectedTypes) {
tikaDetectedTypes = org.apache.tika.mime.MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry().getTypes()
.stream().filter(t -> !t.hasParameters()).map(s -> s.toString()).collect(Collectors.toCollection(TreeSet::new));
}
return Collections.unmodifiableSortedSet(tikaDetectedTypes);
}
/**
* Constructs an object that detects the MIME type of a file by an
* inspection of its contents, using custom file type definitions by users,
* custom file type definitions by Autopsy, and Tika.
* custom file type definitions by Autopsy, and Tika. User file type
* definitions take precedence over both Autopsy file type definitions and
* Tika, and Autopsy file type definitions take precendence over Tika.
*
* @throws FileTypeDetectorInitException if an initialization error occurs,
* @throws FileTypeDetectorInitException If an initialization error occurs,
* e.g., user-defined file type
* definitions exist but cannot be
* loaded.
@@ -72,23 +127,6 @@ public class FileTypeDetector {
}
}
/**
* Gets the names of the custom file types defined by the user or by
* Autopsy.
*
* @return A list of the user-defined MIME types.
*/
public List<String> getUserDefinedTypes() {
List<String> customFileTypes = new ArrayList<>();
for (FileType fileType : userDefinedFileTypes) {
customFileTypes.add(fileType.getMimeType());
}
for (FileType fileType : autopsyDefinedFileTypes) {
customFileTypes.add(fileType.getMimeType());
}
return customFileTypes;
}
/**
* Determines whether or not a given MIME type is detectable by this
* detector.
@@ -103,21 +141,6 @@ public class FileTypeDetector {
|| isDetectableByTika(mimeType);
}
/**
* Returns an unmodifiable list of standard MIME types that does not contain
* types with optional parameters. The list has no duplicate types and is in
* alphabetical order.
*
* @return an unmodifiable view of a set of MIME types
*/
public static synchronized SortedSet<String> getStandardDetectedTypes() {
if (detectedTypes == null) {
detectedTypes = org.apache.tika.mime.MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry().getTypes()
.stream().filter(t -> !t.hasParameters()).map(s -> s.toString()).collect(Collectors.toCollection(TreeSet::new));
}
return Collections.unmodifiableSortedSet(detectedTypes);
}
/**
* Determines whether or not a given MIME type is detectable as a
* user-defined MIME type by this detector.
@@ -144,7 +167,7 @@ public class FileTypeDetector {
* @return True or false.
*/
private boolean isDetectableByTika(String mimeType) {
return FileTypeDetector.getStandardDetectedTypes().contains(removeOptionalParameter(mimeType));
return FileTypeDetector.getTikaDetectedTypes().contains(removeOptionalParameter(mimeType));
}
/**
@@ -307,12 +330,14 @@ public class FileTypeDetector {
/**
* Removes the optional parameter from a MIME type string
* @param mimeType
*
* @param mimeType
*
* @return MIME type without the optional parameter
*/
private String removeOptionalParameter(String mimeType) {
int indexOfSemicolon = mimeType.indexOf(";");
if (indexOfSemicolon != -1 ) {
int indexOfSemicolon = mimeType.indexOf(';');
if (indexOfSemicolon != -1) {
return mimeType.substring(0, indexOfSemicolon).trim();
} else {
return mimeType;
@@ -384,16 +409,16 @@ public class FileTypeDetector {
}
/*
* Exception thrown when a file type detector experiences an error
* condition.
* Exception thrown if an initialization error occurs, e.g., user-defined
* file type definitions exist but cannot be loaded.
*/
public static class FileTypeDetectorInitException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Constructs an exception to throw when a file type detector
* experiences an error condition.
* Constructs an exception to throw if an initialization error occurs,
* e.g., user-defined file type definitions exist but cannot be loaded.
*
* @param message The exception message,
*/
@@ -402,8 +427,8 @@ public class FileTypeDetector {
}
/**
* Constructs an exception to throw when a file type detector
* experiences an error condition.
* Constructs an exception to throw if an initialization error occurs,
* e.g., user-defined file type definitions exist but cannot be loaded.
*
* @param message The exception message,
* @param throwable The underlying cause of the exception.
@@ -414,6 +439,26 @@ public class FileTypeDetector {
}
/**
* Gets the names of the custom file types defined by the user or by
* Autopsy.
*
* @return A list of the user-defined MIME types.
*
* @deprecated Do not use.
*/
@Deprecated
public List<String> getUserDefinedTypes() {
List<String> customFileTypes = new ArrayList<>();
userDefinedFileTypes.forEach((fileType) -> {
customFileTypes.add(fileType.getMimeType());
});
autopsyDefinedFileTypes.forEach((fileType) -> {
customFileTypes.add(fileType.getMimeType());
});
return customFileTypes;
}
/**
* Gets the MIME type of a file, detecting it if it is not already known. If
* detection is necessary, the result is added to the case database.
@@ -23,10 +23,9 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.logging.Level;
import javax.swing.DefaultListModel;
@@ -52,6 +51,8 @@ import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
*/
public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
private static final long serialVersionUID = 1L;
@NbBundle.Messages({"# {0} - filter name",
"# {1} - profile name",
"FilesSetDefsPanel.ingest.fileFilterInUseError=The selected file filter, {0}, is being used by a profile, {1}, and cannot be deleted while any profile uses it.",
@@ -125,7 +126,6 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
} else {
this.ruleDialogTitle = "FilesSetPanel.interesting.title";
this.ingoreUnallocCheckbox.setVisible(false);
}
}
@@ -138,33 +138,15 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
setName(Bundle.FilesSetDefsPanel_Interesting_Title());
}
Set<String> fileTypesCollated = new HashSet<>();
for (String mediaType : FileTypeDetector.getStandardDetectedTypes()) {
fileTypesCollated.add(mediaType);
}
FileTypeDetector fileTypeDetector;
try {
fileTypeDetector = new FileTypeDetector();
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
fileTypesCollated.addAll(userDefinedFileTypes);
SortedSet<String> detectableMimeTypes = FileTypeDetector.getDetectedTypes();
detectableMimeTypes.forEach((type) -> {
mimeTypeComboBox.addItem(type);
});
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
logger.log(Level.SEVERE, "Unable to get user defined file types", ex);
logger.log(Level.SEVERE, "Unable to get detectable file types", ex);
}
List<String> toSort = new ArrayList<>(fileTypesCollated);
toSort.sort((String string1, String string2) -> {
int result = String.CASE_INSENSITIVE_ORDER.compare(string1, string2);
if (result == 0) {
result = string1.compareTo(string2);
}
return result;
});
for (String file : toSort) {
mimeTypeComboBox.addItem(file);
}
this.fileSizeUnitComboBox.setSelectedIndex(1);
this.equalitySignComboBox.setSelectedIndex(2);
}
@@ -226,9 +208,9 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
// Populate the list model for the interesting files sets list
// component.
for (FilesSet set : this.filesSets.values()) {
this.filesSets.values().forEach((set) -> {
this.setsListModel.addElement(set);
}
});
if (!this.filesSets.isEmpty()) {
// Select the first files set by default. The list selections
@@ -308,9 +290,9 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
FilesSetDefsPanel.this.exportSetButton.setEnabled(true);
// Populate the rule definitions list, sorted by name.
TreeMap<String, FilesSet.Rule> rules = new TreeMap<>(selectedSet.getRules());
for (FilesSet.Rule rule : rules.values()) {
rules.values().forEach((rule) -> {
FilesSetDefsPanel.this.rulesListModel.addElement(rule);
}
});
// Select the first rule by default.
if (!FilesSetDefsPanel.this.rulesListModel.isEmpty()) {
FilesSetDefsPanel.this.rulesList.setSelectedIndex(0);
@@ -538,9 +520,9 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
// Redo the list model for the files set list component, which will make
// everything stays sorted as in the working copy tree set.
FilesSetDefsPanel.this.setsListModel.clear();
for (FilesSet set : this.filesSets.values()) {
this.filesSets.values().forEach((set) -> {
this.setsListModel.addElement(set);
}
});
// Select the new/edited files set definition in the set definitions
// list. This will cause the selection listeners to repopulate the
@@ -1198,9 +1180,9 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp
}
// Redo the list model for the files set list component
FilesSetDefsPanel.this.setsListModel.clear();
for (FilesSet set : this.filesSets.values()) {
this.filesSets.values().forEach((set) -> {
this.setsListModel.addElement(set);
}
});
// Select the new/edited files set definition in the set definitions
// list. This will cause the selection listeners to repopulate the
// subordinate components.
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014-2016 Basis Technology Corp.
* Copyright 2014-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,10 +20,8 @@ package org.sleuthkit.autopsy.modules.interestingitems;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -55,6 +53,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
"FilesSetRulePanel.ZeroFileSizeError=File size condition value must not be 0 (Unless = is selected)."
})
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(FilesSetRulePanel.class.getName());
private static final String SLEUTHKIT_PATH_SEPARATOR = "/"; // NON-NLS
private static final List<String> ILLEGAL_FILE_NAME_CHARS = FilesSetsManager.getIllegalFileNameChars();
@@ -130,32 +129,13 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
private void populateMimeTypesComboBox() {
Set<String> fileTypesCollated = new HashSet<>();
for (String mediaType : FileTypeDetector.getStandardDetectedTypes()) {
fileTypesCollated.add(mediaType);
}
FileTypeDetector fileTypeDetector;
try {
fileTypeDetector = new FileTypeDetector();
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
fileTypesCollated.addAll(userDefinedFileTypes);
SortedSet<String> detectableMimeTypes = FileTypeDetector.getDetectedTypes();
detectableMimeTypes.forEach((type) -> {
mimeTypeComboBox.addItem(type);
});
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
logger.log(Level.SEVERE, "Unable to get user defined file types", ex);
}
List<String> toSort = new ArrayList<>(fileTypesCollated);
toSort.sort((String string1, String string2) -> {
int result = String.CASE_INSENSITIVE_ORDER.compare(string1, string2);
if (result == 0) {
result = string1.compareTo(string2);
}
return result;
});
for (String file : toSort) {
mimeTypeComboBox.addItem(file);
logger.log(Level.SEVERE, "Unable to get detectable file types", ex);
}
this.setOkButton();
}
@@ -208,7 +188,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
* @return
*/
private JOptionPane getOptionPane(JComponent parent) {
JOptionPane pane = null;
JOptionPane pane;
if (!(parent instanceof JOptionPane)) {
pane = getOptionPane((JComponent) parent.getParent());
} else {
@@ -226,19 +206,13 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
private void setButtons(JButton ok, JButton cancel) {
this.okButton = ok;
this.cancelButton = cancel;
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane(okButton);
pane.setValue(okButton);
}
okButton.addActionListener((ActionEvent e) -> {
JOptionPane pane = getOptionPane(okButton);
pane.setValue(okButton);
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane(cancelButton);
pane.setValue(cancelButton);
}
cancelButton.addActionListener((ActionEvent e) -> {
JOptionPane pane = getOptionPane(cancelButton);
pane.setValue(cancelButton);
});
this.setOkButton();
}
@@ -192,7 +192,7 @@ public final class FileExporterSettingsPanel extends JPanel {
public FileExporterSettingsPanel(JDialog jDialog) {
timeSettings.setFormatForDisplayTime(PickerUtilities.createFormatterFromPatternString("HH:mm:ss", timeSettings.getLocale()));
timeSettings.setFormatForMenuTimes(PickerUtilities.createFormatterFromPatternString("HH:mm", timeSettings.getLocale()));
initComponents();
rootNode = new DefaultMutableTreeNode(new Item(ROOTNODE, ROOTNODE, ItemType.RULE_SET));
trRuleList.setModel(new DefaultTreeModel(rootNode));
@@ -511,24 +511,14 @@ public final class FileExporterSettingsPanel extends JPanel {
* Populate the MIME types in the combo box.
*/
void populateMimeTypes() {
Set<String> mimeTypesCollated = scanRulesForMimetypes();
for (MediaType mediaType : mediaTypes) {
mimeTypesCollated.add(mediaType.toString());
}
FileTypeDetector fileTypeDetector;
try {
fileTypeDetector = new FileTypeDetector();
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
mimeTypesCollated.addAll(userDefinedFileTypes);
SortedSet<String> detectableMimeTypes = FileTypeDetector.getDetectedTypes();
detectableMimeTypes.addAll(scanRulesForMimetypes());
detectableMimeTypes.forEach((type) -> {
comboBoxMimeValue.addItem(type);
});
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
logger.log(Level.SEVERE, "Unable to get user defined file types", ex);
}
List<String> sorted = new ArrayList<>(mimeTypesCollated);
Collections.sort(sorted, String.CASE_INSENSITIVE_ORDER);
for (String mime : sorted) {
comboBoxMimeValue.addItem(mime);
logger.log(Level.SEVERE, "Unable to get detectable file types", ex);
}
}
@@ -1940,8 +1930,8 @@ public final class FileExporterSettingsPanel extends JPanel {
}
/**
* Allows Options Panel to tell if the root directory is valid.
* Throws an exception with explanatory text if it is not valid.
* Allows Options Panel to tell if the root directory is valid. Throws an
* exception with explanatory text if it is not valid.
*
* throws FolderDidNotValidateException
*/
@@ -1950,8 +1940,8 @@ public final class FileExporterSettingsPanel extends JPanel {
}
/**
* Allows Options Panel to tell if the report directory is valid.
* Throws an exception with explanatory text if it is not valid.
* Allows Options Panel to tell if the report directory is valid. Throws an
* exception with explanatory text if it is not valid.
*
* throws FolderDidNotValidateException
*/