Merge remote-tracking branch 'upstream/develop' into aut-2025-pt2

This commit is contained in:
Oliver Spohngellert
2016-03-18 10:40:34 -04:00
154 changed files with 5485 additions and 4354 deletions
+1 -6
View File
@@ -5,11 +5,7 @@
<project name="org.sleuthkit.autopsy.core" default="netbeans" basedir=".">
<description>Builds, tests, and runs the project org.sleuthkit.autopsy.core</description>
<import file="nbproject/build-impl.xml"/>
<!-- Verify that the TSK_HOME env variable is set -->
<target name="findTSK">
<property environment="env"/>
@@ -30,7 +26,6 @@
<copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.8.11.jar" tofile="${basedir}/release/modules/ext/sqlite-jdbc-3.8.11.jar"/>
</target>
<target name="init" depends="basic-init,files-init,build-init,-javac-init">
<!-- get additional deps -->
<antcall target="getTSKJars" />
@@ -19,15 +19,13 @@
package org.sleuthkit.autopsy.casemodule;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.SleuthkitJNI;
@@ -35,66 +33,220 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskDataException;
/*
* A background task that adds the given image to database using the Sleuthkit
* JNI interface.
*
* It updates the given ProgressMonitor as it works through adding the image,
* and et the end, calls the specified Callback.
* A runnable that adds an image data source to the case database.
*/
class AddImageTask implements Runnable {
private final Logger logger = Logger.getLogger(AddImageTask.class.getName());
private final Case currentCase;
// true if the process was requested to cancel
private final Object lock = new Object(); // synchronization object for cancelRequested
private volatile boolean cancelRequested = false;
//true if revert has been invoked.
private boolean reverted = false;
// true if there was a critical error in adding the data source
private boolean hasCritError = false;
private final List<String> errorList = new ArrayList<>();
private final DataSourceProcessorProgressMonitor progressMonitor;
private final DataSourceProcessorCallback callbackObj;
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
private SleuthkitJNI.CaseDbHandle.AddImageProcess addImageProcess;
private Thread dirFetcher;
private final String deviceId;
private final String imagePath;
String timeZone;
boolean noFatOrphans;
private final String dataSourceId;
private final String timeZone;
private final boolean ignoreFatOrphanFiles;
private final DataSourceProcessorProgressMonitor progressMonitor;
private final DataSourceProcessorCallback callback;
private boolean criticalErrorOccurred;
/*
* A thread that updates the progressMonitor with the name of the directory
* currently being processed by the AddImageTask
* The cancellation requested flag and SleuthKit add image process are
* guarded by a monitor (called a lock here to avoid confusion with the
* progress monitor) to synchronize cancelling the process (setting the flag
* and calling its stop method) and calling either its commit or revert
* method. The built-in monitor of the add image process can't be used for
* this because it is already used to synchronize its run (init part),
* commit, revert, and currentDirectory methods.
*
* TODO (AUT-2021): Merge SleuthkitJNI.AddImageProcess and AddImageTask
*/
private class CurrentDirectoryFetcher implements Runnable {
private final Object tskAddImageProcessLock;
private boolean tskAddImageProcessStopped;
private SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess;
DataSourceProcessorProgressMonitor progressMonitor;
SleuthkitJNI.CaseDbHandle.AddImageProcess process;
/**
* Constructs a runnable task that adds an image to the case database.
*
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is
* intended to be unique across multiple cases
* (e.g., a UUID).
* @param imagePath Path to the image file.
* @param timeZone The time zone to use when processing dates
* and times for the image, obtained from
* java.util.TimeZone.getID.
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
* FAT filesystem.
* @param progressMonitor Progress monitor to report progress during
* processing.
* @param callback Callback to call when processing is done.
*/
AddImageTask(String deviceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
this.deviceId = deviceId;
this.imagePath = imagePath;
this.timeZone = timeZone;
this.ignoreFatOrphanFiles = ignoreFatOrphanFiles;
this.callback = callback;
this.progressMonitor = progressMonitor;
tskAddImageProcessLock = new Object();
}
CurrentDirectoryFetcher(DataSourceProcessorProgressMonitor aProgressMonitor, SleuthkitJNI.CaseDbHandle.AddImageProcess proc) {
this.progressMonitor = aProgressMonitor;
this.process = proc;
/**
* Adds the image to the case database.
*/
@Override
public void run() {
progressMonitor.setIndeterminate(true);
progressMonitor.setProgress(0);
Case currentCase = Case.getCurrentCase();
List<String> errorMessages = new ArrayList<>();
List<Content> newDataSources = new ArrayList<>();
try {
currentCase.getSleuthkitCase().acquireExclusiveLock();
synchronized (tskAddImageProcessLock) {
tskAddImageProcess = currentCase.makeAddImageProcess(timeZone, true, ignoreFatOrphanFiles);
}
Thread progressUpdateThread = new Thread(new ProgressUpdater(progressMonitor, tskAddImageProcess));
progressUpdateThread.start();
runAddImageProcess(errorMessages);
if (null != progressUpdateThread) {
progressUpdateThread.interrupt();
}
commitOrRevertAddImageProcess(currentCase, errorMessages, newDataSources);
progressMonitor.setProgress(100);
} finally {
currentCase.getSleuthkitCase().releaseExclusiveLock();
DataSourceProcessorCallback.DataSourceProcessorResult result;
if (criticalErrorOccurred) {
result = DataSourceProcessorResult.CRITICAL_ERRORS;
} else if (!errorMessages.isEmpty()) {
result = DataSourceProcessorResult.NONCRITICAL_ERRORS;
} else {
result = DataSourceProcessorResult.NO_ERRORS;
}
callback.done(result, errorMessages, newDataSources);
}
}
/*
* Attempts to cancel adding the image to the case database.
*/
public void cancelTask() {
synchronized (tskAddImageProcessLock) {
if (null != tskAddImageProcess) {
try {
/*
* All this does is set a flag that will make the TSK add
* image process exit when the flag is checked between
* processing steps. The state of the flag is not
* accessible, so record it here so that it is known that
* the revert method of the process object needs to be
* called.
*/
tskAddImageProcess.stop();
tskAddImageProcessStopped = true;
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error cancelling adding image %s to the case database", imagePath), ex); //NON-NLS
}
}
}
}
/**
* Runs the TSK add image process.
*
* @param errorMessages Error messages, if any, are added to this list for
* eventual return via the callback.
*/
private void runAddImageProcess(List<String> errorMessages) {
try {
tskAddImageProcess.run(deviceId, new String[]{imagePath});
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Critical error occurred adding image %s", imagePath), ex); //NON-NLS
criticalErrorOccurred = true;
errorMessages.add(ex.getMessage());
} catch (TskDataException ex) {
logger.log(Level.WARNING, String.format("Non-critical error occurred adding image %s", imagePath), ex); //NON-NLS
errorMessages.add(ex.getMessage());
}
}
/**
* Commits or reverts the results of the TSK add image process. If the
* process was stopped before it completed or there was a critical error the
* results are reverted, otherwise they are committed.
*
* @param currentCase The current case.
* @param errorMessages Error messages, if any, are added to this list for
* eventual return via the callback.
* @param newDataSources If the new image is successfully committed, it is
* added to this list for eventual return via the
* callback.
*
* @return
*/
private void commitOrRevertAddImageProcess(Case currentCase, List<String> errorMessages, List<Content> newDataSources) {
synchronized (tskAddImageProcessLock) {
if (tskAddImageProcessStopped || criticalErrorOccurred) {
try {
tskAddImageProcess.revert();
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error reverting adding image %s to the case database", imagePath), ex); //NON-NLS
errorMessages.add(ex.getMessage());
criticalErrorOccurred = true;
}
} else {
try {
long imageId = tskAddImageProcess.commit();
if (imageId != 0) {
Image newImage = currentCase.getSleuthkitCase().getImageById(imageId);
String verificationError = newImage.verifyImageSize();
if (!verificationError.isEmpty()) {
errorMessages.add(verificationError);
}
newDataSources.add(newImage);
} else {
String errorMessage = String.format("Error commiting adding image %s to the case database, no object id returned", imagePath); //NON-NLS
logger.log(Level.SEVERE, errorMessage);
errorMessages.add(errorMessage);
criticalErrorOccurred = true;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, String.format("Error committing adding image %s to the case database", imagePath), ex); //NON-NLS
errorMessages.add(ex.getMessage());
criticalErrorOccurred = true;
}
}
}
}
/**
* A Runnable that updates the progress monitor with the name of the
* directory currently being processed by the SleuthKit add image process.
*/
private class ProgressUpdater implements Runnable {
private final DataSourceProcessorProgressMonitor progressMonitor;
private final SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess;
/**
* Constructs a Runnable that updates the progress monitor with the name
* of the directory currently being processed by the SleuthKit.
*
* @param progressMonitor
* @param tskAddImageProcess
*/
ProgressUpdater(DataSourceProcessorProgressMonitor progressMonitor, SleuthkitJNI.CaseDbHandle.AddImageProcess tskAddImageProcess) {
this.progressMonitor = progressMonitor;
this.tskAddImageProcess = tskAddImageProcess;
}
/**
* @return the currently processing directory
* Updates the progress monitor with the name of the directory currently
* being processed by the SleuthKit add image process.
*/
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
String currDir = process.currentDirectory();
String currDir = tskAddImageProcess.currentDirectory();
if (currDir != null) {
if (!currDir.isEmpty()) {
progressMonitor.setProgressText(
@@ -102,227 +254,20 @@ class AddImageTask implements Runnable {
currDir));
}
}
// this sleep here prevents the UI from locking up
// due to too frequent updates to the progressMonitor above
/*
* The sleep here throttles the UI updates and provides a
* non-standard mechanism for completing this task by
* interrupting the thread in which it is running.
*
* TODO (AUT-1870): Replace this with giving the task to a
* java.util.concurrent.ScheduledThreadPoolExecutor that is
* shut down when the main task completes.
*/
Thread.sleep(500);
}
} catch (InterruptedException ie) {
// nothing to do, thread was interrupted externally
// signaling the end of AddImageProcess
} catch (InterruptedException expected) {
}
}
}
/**
* Constructs a runnable task that adds an image to the case database.
*
* @param dataSourceId An ASCII-printable identifier for the data
* source that is intended to be unique across
* multiple cases (e.g., a UUID).
* @param imagePath Path to the image file.
* @param timeZone The time zone to use when processing dates
* and times for the image, obtained from
* java.util.TimeZone.getID.
* @param ignoreFatOrphanFiles Whether to parse orphans if the image has a
* FAT filesystem.
* @param monitor Progress monitor to report progress during
* processing.
* @param cbObj Callback to call when processing is done.
*/
AddImageTask(String dataSourceId, String imagePath, String timeZone, boolean ignoreFatOrphanFiles, DataSourceProcessorProgressMonitor monitor, DataSourceProcessorCallback cbObj) {
currentCase = Case.getCurrentCase();
this.dataSourceId = dataSourceId;
this.imagePath = imagePath;
this.timeZone = timeZone;
this.noFatOrphans = ignoreFatOrphanFiles;
this.callbackObj = cbObj;
this.progressMonitor = monitor;
}
/**
* Starts the addImage process, but does not commit the results.
*
* @return
*
* @throws Exception
*/
@Override
public void run() {
errorList.clear();
try {
currentCase.getSleuthkitCase().acquireExclusiveLock();
addImageProcess = currentCase.makeAddImageProcess(timeZone, true, noFatOrphans);
dirFetcher = new Thread(new CurrentDirectoryFetcher(progressMonitor, addImageProcess));
try {
progressMonitor.setIndeterminate(true);
progressMonitor.setProgress(0);
dirFetcher.start();
addImageProcess.run(dataSourceId, new String[]{imagePath});
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Core errors occurred while running add image on " + imagePath, ex); //NON-NLS
hasCritError = true;
errorList.add(ex.getMessage());
} catch (TskDataException ex) {
logger.log(Level.WARNING, "Data errors occurred while running add image " + imagePath, ex); //NON-NLS
errorList.add(ex.getMessage());
}
postProcess();
} finally {
currentCase.getSleuthkitCase().releaseExclusiveLock();
}
}
/**
* Commit the newly added image to DB
*
*
* @throws Exception if commit or adding the image to the case failed
*/
private void commitImage() throws Exception {
long imageId = 0;
try {
imageId = addImageProcess.commit();
} catch (TskCoreException e) {
logger.log(Level.WARNING, "Errors occurred while committing the image " + imagePath, e); //NON-NLS
errorList.add(e.getMessage());
} finally {
if (imageId != 0) {
// get the newly added Image so we can return to caller
Image newImage = currentCase.getSleuthkitCase().getImageById(imageId);
//while we have the image, verify the size of its contents
String verificationErrors = newImage.verifyImageSize();
if (verificationErrors.equals("") == false) {
//data error (non-critical)
errorList.add(verificationErrors);
}
// Add the image to the list of new content
newContents.add(newImage);
}
logger.log(Level.INFO, "Image committed, imageId: {0}", imageId); //NON-NLS
logger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
}
}
/**
* Post processing after the addImageProcess is done.
*
*/
private void postProcess() {
// cancel the directory fetcher
dirFetcher.interrupt();
if (cancelRequested() || hasCritError) {
logger.log(Level.WARNING, "Critical errors or interruption in add image process on {0}. Image will not be committed.", imagePath); //NON-NLS
revert();
}
if (!errorList.isEmpty()) {
logger.log(Level.INFO, "There were errors that occurred in add image process for {0}", imagePath); //NON-NLS
}
// When everything happens without an error:
if (!(cancelRequested() || hasCritError)) {
try {
if (addImageProcess != null) {
// commit image
try {
commitImage();
} catch (Exception ex) {
errorList.add(ex.getMessage());
// Log error/display warning
logger.log(Level.SEVERE, "Error adding image " + imagePath + " to case.", ex); //NON-NLS
}
} else {
logger.log(Level.SEVERE, "Missing image process object"); //NON-NLS
}
// Tell the progress monitor we're done
progressMonitor.setProgress(100);
} catch (Exception ex) {
//handle unchecked exceptions post image add
errorList.add(ex.getMessage());
logger.log(Level.WARNING, "Unexpected errors occurred while running post add image cleanup for " + imagePath, ex); //NON-NLS
logger.log(Level.SEVERE, "Error adding image " + imagePath + " to case", ex); //NON-NLS
}
}
// invoke the callBack, unless the caller cancelled
if (!cancelRequested()) {
doCallBack();
}
}
/*
* Call the callback with results, new content, and errors, if any
*/
private void doCallBack() {
DataSourceProcessorCallback.DataSourceProcessorResult result;
if (hasCritError) {
result = DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
} else if (!errorList.isEmpty()) {
result = DataSourceProcessorCallback.DataSourceProcessorResult.NONCRITICAL_ERRORS;
} else {
result = DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS;
}
// invoke the callback, passing it the result, list of new contents, and list of errors
callbackObj.done(result, errorList, newContents);
}
/*
* cancel the image addition, if possible
*/
public void cancelTask() {
synchronized (lock) {
cancelRequested = true;
try {
interrupt();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to interrupt the add image task..."); //NON-NLS
}
}
}
/*
* Interrupt the add image process if it is still running
*/
private void interrupt() throws Exception {
try {
logger.log(Level.INFO, "interrupt() add image process"); //NON-NLS
addImageProcess.stop(); //it might take time to truly stop processing and writing to db
} catch (TskCoreException ex) {
throw new Exception(NbBundle.getMessage(this.getClass(), "AddImageTask.interrupt.exception.msg"), ex);
}
}
/*
* Revert - if image has already been added but not committed yet
*/
private void revert() {
if (!reverted) {
logger.log(Level.INFO, "Revert after add image process"); //NON-NLS
try {
addImageProcess.revert();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error reverting add image process", ex); //NON-NLS
}
reverted = true;
}
}
private boolean cancelRequested() {
synchronized (lock) {
return cancelRequested;
}
}
}
@@ -146,6 +146,7 @@ final class AddImageWizardChooseDataSourceVisual extends JPanel {
*
* @param panel instance of ImageTypePanel to change to
*/
@SuppressWarnings("deprecation")
private void updateCurrentPanel(JPanel panel) {
currentPanel = panel;
typePanel.removeAll();
@@ -68,6 +68,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
private DataSourceProcessor dsProcessor;
private boolean cancelled;
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
this.addImageAction = action;
@@ -228,6 +229,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
@Override
void cleanup() throws Exception {
cancelDataSourceProcessing(dataSourceId);
cancelled = true;
}
};
@@ -244,7 +246,6 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
dataSourceProcessorDone(dataSourceId, result, errList, contents);
}
};
progressPanel.setStateStarted();
@@ -258,9 +259,6 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
* Cancels the data source processing - in case the users presses 'Cancel'
*/
private void cancelDataSourceProcessing(UUID dataSourceId) {
new Thread(() -> {
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
}).start();
dsProcessor.cancel();
}
@@ -303,21 +301,23 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
progressPanel.addErrors(err, critErr);
}
newContents.clear();
newContents.addAll(contents);
//notify the UI of the new content added to the case
new Thread(() -> {
if (!newContents.isEmpty()) {
Case.getCurrentCase().notifyDataSourceAdded(newContents.get(0), dataSourceId);
if (!contents.isEmpty()) {
Case.getCurrentCase().notifyDataSourceAdded(contents.get(0), dataSourceId);
} else {
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
}
}).start();
// Start ingest if we can
progressPanel.setStateStarted();
startIngest();
if (!cancelled) {
newContents.clear();
newContents.addAll(contents);
progressPanel.setStateStarted();
startIngest();
} else {
cancelled = false;
}
}
}
@@ -219,11 +219,11 @@ public class Case implements SleuthkitCase.ErrorObserver {
* multi-user (using PostgreSql)
*/
@NbBundle.Messages({"Case_caseType_singleUser=Single-user case",
"Case_caseType_multiUser=Multi-user case"})
"Case_caseType_multiUser=Multi-user case"})
public enum CaseType {
SINGLE_USER_CASE(Bundle.Case_caseType_singleUser()),
MULTI_USER_CASE(Bundle.Case_caseType_multiUser());
SINGLE_USER_CASE("Single-user case"), //NON-NLS
MULTI_USER_CASE("Multi-user case"); //NON-NLS
private final String caseType;
@@ -250,6 +250,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
public String toString() {
return caseType;
}
String getLocalizedDisplayName() {
if (fromString(caseType) == SINGLE_USER_CASE) {
return Bundle.Case_caseType_singleUser();
} else {
return Bundle.Case_caseType_multiUser();
}
}
};
private String name;
@@ -92,7 +92,7 @@ class CasePropertiesForm extends javax.swing.JPanel {
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(currentCase.getConfigFilePath()));
tbDbName.setText(caseMetadata.getCaseDatabaseName());
Case.CaseType caseType = caseMetadata.getCaseType();
tbDbType.setText(caseType.toString());
tbDbType.setText(caseType.getLocalizedDisplayName());
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
deleteCaseButton.setEnabled(true);
} else {
@@ -466,7 +466,11 @@ final class CollaborationMonitor {
*/
@Override
public void run() {
eventPublisher.publishRemotely(new CollaborationEvent(hostName, localTasksManager.getCurrentTasks()));
try {
eventPublisher.publishRemotely(new CollaborationEvent(hostName, localTasksManager.getCurrentTasks()));
} catch (Exception ex) {
logger.log(Level.SEVERE, "Unexpected exception in HeartbeatTask", ex); //NON-NLS
}
}
}
@@ -482,7 +486,11 @@ final class CollaborationMonitor {
*/
@Override
public void run() {
remoteTasksManager.finishStaleTasks();
try {
remoteTasksManager.finishStaleTasks();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Unexpected exception in StaleTaskDetectionTask", ex); //NON-NLS
}
}
}
@@ -31,7 +31,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
/**
* An image file data source processor that implements the DataSourceProcessor
* A image file data source processor that implements the DataSourceProcessor
* service provider interface to allow integration with the add data source
* wizard. It also provides a run method overload to allow it to be used
* independently of the wizard.
@@ -81,10 +81,10 @@ public class ImageDSProcessor implements DataSourceProcessor {
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
public static String getType() {
return DATA_SOURCE_TYPE;
@@ -92,21 +92,23 @@ public class ImageDSProcessor implements DataSourceProcessor {
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
@Override
public String getDataSourceType() {
return DATA_SOURCE_TYPE;
return getType();
}
/**
* Gets the panel that allows a user to select a data source and do any
* configuration the data source processor may require.
* configuration required by the data source. The panel is less than 544
* pixels wide and less than 173 pixels high.
*
* @return A JPanel less than 544 pixels wide and 173 pixels high.
* @return A selection and configuration panel for this data source
* processor.
*/
@Override
public JPanel getPanel() {
@@ -116,10 +118,11 @@ public class ImageDSProcessor implements DataSourceProcessor {
}
/**
* Indicates whether the settings in the panel are valid and complete.
* Indicates whether the settings in the selection and configuration panel
* are valid and complete.
*
* @return True if the settings are valid and complete and the processor is
* ready to have its run method called; false otherwise.
* ready to have its run method called, false otherwise.
*/
@Override
public boolean isPanelValid() {
@@ -127,16 +130,18 @@ public class ImageDSProcessor implements DataSourceProcessor {
}
/**
* Adds a data source to the case database using a separate thread and the
* settings provided by the panel. Returns as soon as the background task is
* started and uses the callback object to signal task completion and return
* results.
* Adds a data source to the case database using a background task in a
* separate thread and the settings provided by the selection and
* configuration panel. Returns as soon as the background task is started.
* The background task uses a callback object to signal task completion and
* return results.
*
* NOTE: This method should not be called unless isPanelValid returns true.
* This method should not be called unless isPanelValid returns true.
*
* @param progressMonitor Progress monitor for reporting progress during
* processing.
* @param callback Callback to call when processing is done.
* @param progressMonitor Progress monitor that will be used by the
* background task to report progress.
* @param callback Callback that will be used by the background task
* to return results.
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
@@ -151,10 +156,11 @@ public class ImageDSProcessor implements DataSourceProcessor {
}
/**
* Adds a data source to the case database using a separate thread and the
* given settings instead of those provided by the panel. Returns as soon as
* the background task is started and uses the callback object to signal
* task completion and return results.
* Adds a data source to the case database using a background task in a
* separate thread and the given settings instead of those provided by the
* selection and configuration panel. Returns as soon as the background task
* is started and uses the callback object to signal task completion and
* return results.
*
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is
@@ -176,8 +182,11 @@ public class ImageDSProcessor implements DataSourceProcessor {
}
/**
* Requests cancellation of the data source processing task after it is
* started using the run method. Cancellation is not guaranteed.
* Requests cancellation of the background task that adds a data source to
* the case database, after the task is started using the run method. This
* is a "best effort" cancellation, with no guarantees that the case
* database will be unchanged. If cancellation succeeded, the list of new
* data sources returned by the background task will be empty.
*/
@Override
public void cancel() {
@@ -185,7 +194,8 @@ public class ImageDSProcessor implements DataSourceProcessor {
}
/**
* Resets the panel.
* Resets the selection and configuration panel for this data source
* processor.
*/
@Override
public void reset() {
@@ -199,7 +209,7 @@ public class ImageDSProcessor implements DataSourceProcessor {
/**
* Sets the configuration of the data source processor without using the
* configuration panel.
* selection and configuration panel.
*
* @param imagePath Path to the image file.
* @param timeZone The time zone to use when processing dates
@@ -190,7 +190,7 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@SuppressWarnings("deprecation")
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
String oldText = pathTextField.getText();
// set the current directory of the FileChooser if the ImagePath Field is valid
@@ -61,10 +61,10 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
public static String getType() {
return DATA_SOURCE_TYPE;
@@ -72,10 +72,10 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
@Override
public String getDataSourceType() {
@@ -83,10 +83,12 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
/**
* Gets the JPanel that allows a user to select a data source and do any
* configuration the data source processor may require.
* Gets the panel that allows a user to select a data source and do any
* configuration required by the data source. The panel is less than 544
* pixels wide and less than 173 pixels high.
*
* @return A JPanel less than 544 pixels wide and 173 pixels high.
* @return A selection and configuration panel for this data source
* processor.
*/
@Override
public JPanel getPanel() {
@@ -95,10 +97,11 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
/**
* Indicates whether the settings in the panel are valid and complete.
* Indicates whether the settings in the selection and configuration panel
* are valid and complete.
*
* @return True if the settings are valid and complete and the processor is
* ready to have its run method called; false otherwise.
* ready to have its run method called, false otherwise.
*/
@Override
public boolean isPanelValid() {
@@ -106,16 +109,18 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
/**
* Adds a data source to the case database using a separate thread and the
* settings provided by the panel. Returns as soon as the background task is
* started and uses the callback object to signal task completion and return
* results.
* Adds a data source to the case database using a background task in a
* separate thread and the settings provided by the selection and
* configuration panel. Returns as soon as the background task is started.
* The background task uses a callback object to signal task completion and
* return results.
*
* NOTE: This method should not be called unless isPanelValid returns true.
* This method should not be called unless isPanelValid returns true.
*
* @param progressMonitor Progress monitor for reporting progress during
* processing.
* @param callback Callback to call when processing is done.
* @param progressMonitor Progress monitor that will be used by the
* background task to report progress.
* @param callback Callback that will be used by the background task
* to return results.
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
@@ -130,10 +135,11 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
/**
* Adds a data source to the case database using a separate thread and the
* given settings instead of those provided by the panel. Returns as soon as
* the background task is started and uses the callback object to signal
* task completion and return results.
* Adds a data source to the case database using a background task in a
* separate thread and the given settings instead of those provided by the
* selection and configuration panel. Returns as soon as the background task
* is started and uses the callback object to signal task completion and
* return results.
*
* @param deviceId An ASCII-printable identifier for the device
* associated with the data source that is
@@ -155,8 +161,11 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
/**
* Requests cancellation of the data source processing task after it is
* started using the run method. Cancellation is not guaranteed.
* Requests cancellation of the background task that adds a data source to
* the case database, after the task is started using the run method. This
* is a "best effort" cancellation, with no guarantees that the case
* database will be unchanged. If cancellation succeeded, the list of new
* data sources returned by the background task will be empty.
*/
@Override
public void cancel() {
@@ -164,7 +173,8 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
/**
* Resets the panel.
* Resets the selection and configuration panel for this data source
* processor.
*/
@Override
public void reset() {
@@ -59,10 +59,10 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
public static String getType() {
return DATA_SOURCE_TYPE;
@@ -70,10 +70,10 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
@Override
public String getDataSourceType() {
@@ -82,9 +82,11 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
/**
* Gets the panel that allows a user to select a data source and do any
* configuration the data source processor may require.
* configuration required by the data source. The panel is less than 544
* pixels wide and less than 173 pixels high.
*
* @return A JPanel less than 544 pixels wide and 173 pixels high.
* @return A selection and configuration panel for this data source
* processor.
*/
@Override
public JPanel getPanel() {
@@ -93,10 +95,11 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
}
/**
* Indicates whether the settings in the panel are valid and complete.
* Indicates whether the settings in the selection and configuration panel
* are valid and complete.
*
* @return True if the settings are valid and complete and the processor is
* ready to have its run method called; false otherwise.
* ready to have its run method called, false otherwise.
*/
@Override
public boolean isPanelValid() {
@@ -104,16 +107,18 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
}
/**
* Adds a data source to the case database using a separate thread and the
* settings provided by the panel. Returns as soon as the background task is
* started and uses the callback object to signal task completion and return
* results.
* Adds a data source to the case database using a background task in a
* separate thread and the settings provided by the selection and
* configuration panel. Returns as soon as the background task is started.
* The background task uses a callback object to signal task completion and
* return results.
*
* NOTE: This method should not be called unless isPanelValid returns true.
* This method should not be called unless isPanelValid returns true.
*
* @param progressMonitor Progress monitor for reporting progress during
* processing.
* @param callback Callback to call when processing is done.
* @param progressMonitor Progress monitor that will be used by the
* background task to report progress.
* @param callback Callback that will be used by the background task
* to return results.
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
@@ -125,10 +130,11 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
}
/**
* Adds a data source to the case database using a separate thread and the
* given settings instead of those provided by the panel. Returns as soon as
* the background task is started and uses the callback object to signal
* task completion and return results.
* Adds a data source to the case database using a background task in a
* separate thread and the given settings instead of those provided by the
* selection and configuration panel. Returns as soon as the background task
* is started and uses the callback object to signal task completion and
* return results.
*
* @param deviceId An ASCII-printable identifier for the
* device associated with the data source
@@ -151,18 +157,22 @@ public class LocalFilesDSProcessor implements DataSourceProcessor {
}
/**
* Requests cancellation of the data source processing task after it is
* started using the run method. Cancellation is not guaranteed.
* Requests cancellation of the background task that adds a data source to
* the case database, after the task is started using the run method. This
* is a "best effort" cancellation, with no guarantees that the case
* database will be unchanged. If cancellation succeeded, the list of new
* data sources returned by the background task will be empty.
*
* TODO (AUT-1907): Implement cancellation by deleting rows added to the
* case database.
*/
@Override
public void cancel() {
/*
* Cancellation is not currently supported.
*/
}
/**
* Resets the panel.
* Resets the selection and configuration panel for this data source
* processor.
*/
@Override
public void reset() {
@@ -239,7 +239,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
Object res2 = DialogDisplayer.getDefault().notify(d2);
if (res2 != null && res2 == DialogDescriptor.YES_OPTION) {
// if user say yes
// if user says yes
try {
createDirectory(caseDirPath, getComponent().getCaseType());
} catch (Exception ex) {
@@ -251,7 +251,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
}
}
if (res2 != null && res2 == DialogDescriptor.NO_OPTION) {
// if user say no
// if user says no
validationError(NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg",
caseDirPath));
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-15 Basis Technology Corp.
* Copyright 2011-16 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,86 +37,66 @@ import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A per case instance of this class functions as an Autopsy service that
* manages the creation, updating, and deletion of tags applied to content and
* blackboard artifacts by users.
* A per case Autopsy service that manages the creation, updating, and deletion
* of tags applied to content and blackboard artifacts by users.
*/
public class TagsManager implements Closeable {
private static final Logger logger = Logger.getLogger(TagsManager.class.getName());
private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS
private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS
private final SleuthkitCase tskCase;
private final SleuthkitCase caseDb;
private final HashMap<String, TagName> uniqueTagNames = new HashMap<>();
private boolean tagNamesInitialized = false; // @@@ This is part of a work around to be removed when database access on the EDT is correctly synchronized.
private boolean tagNamesLoaded = false;
/**
* Use this exception and the member hash map to manage uniqueness of hash
* names. This is deemed more proactive and informative than leaving this to
* the UNIQUE constraint on the display_name field of the tag_names table in
* the case database.
*/
public static class TagNameAlreadyExistsException extends Exception {
}
/**
* Package-scope constructor for use of the Services class. An instance of
* TagsManager should be created for each case that is opened.
* Constructs a per case Autopsy service that manages the creation,
* updating, and deletion of tags applied to content and blackboard
* artifacts by users.
*
* @param tskCase The SleuthkitCase object for the current case.
* @param caseDb The case database for the current case.
*/
TagsManager(SleuthkitCase tskCase) {
this.tskCase = tskCase;
// @@@ The removal of this call is a work around until database access on the EDT is correctly synchronized.
// getExistingTagNames();
TagsManager(SleuthkitCase caseDb) {
this.caseDb = caseDb;
}
/**
* Gets a list of all tag names currently available for tagging content or
* blackboard artifacts.
* artifacts.
*
* @return A list, possibly empty, of TagName data transfer objects (DTOs).
*
* @throws TskCoreException
* @throws TskCoreException If there is an error reading from the case
* database.
*/
public synchronized List<TagName> getAllTagNames() throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getAllTagNames();
lazyLoadExistingTagNames();
return caseDb.getAllTagNames();
}
/**
* Gets a list of all tag names currently used for tagging content or
* blackboard artifacts.
* Gets a list of all tag names currently in use for tagging content or
* artifacts.
*
* @return A list, possibly empty, of TagName data transfer objects (DTOs).
*
* @throws TskCoreException
* @throws TskCoreException If there is an error reading from the case
* database.
*/
public synchronized List<TagName> getTagNamesInUse() throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getTagNamesInUse();
lazyLoadExistingTagNames();
return caseDb.getTagNamesInUse();
}
/**
* Checks whether a tag name with a given display name exists.
*
* @param tagDisplayName The display name for which to check.
* @param tagDisplayName The display name to check.
*
* @return True if the tag name exists, false otherwise.
* @return True or false.
*/
public synchronized boolean tagNameExists(String tagDisplayName) {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
lazyLoadExistingTagNames();
return uniqueTagNames.containsKey(tagDisplayName);
}
@@ -128,7 +108,10 @@ public class TagsManager implements Closeable {
* @return A TagName data transfer object (DTO) representing the new tag
* name.
*
* @throws TagNameAlreadyExistsException, TskCoreException
* @throws TagNameAlreadyExistsException If the tag name would be a
* duplicate.
* @throws TskCoreException If there is an error adding the tag
* to the case database.
*/
public TagName addTagName(String displayName) throws TagNameAlreadyExistsException, TskCoreException {
return addTagName(displayName, "", TagName.HTML_COLOR.NONE);
@@ -143,7 +126,10 @@ public class TagsManager implements Closeable {
* @return A TagName data transfer object (DTO) representing the new tag
* name.
*
* @throws TagNameAlreadyExistsException, TskCoreException
* @throws TagNameAlreadyExistsException If the tag name would be a
* duplicate.
* @throws TskCoreException If there is an error adding the tag
* to the case database.
*/
public TagName addTagName(String displayName, String description) throws TagNameAlreadyExistsException, TskCoreException {
return addTagName(displayName, description, TagName.HTML_COLOR.NONE);
@@ -159,22 +145,25 @@ public class TagsManager implements Closeable {
* @return A TagName data transfer object (DTO) representing the new tag
* name.
*
* @throws TagNameAlreadyExistsException, TskCoreException
* @throws TagNameAlreadyExistsException If the tag name would be a
* duplicate.
* @throws TskCoreException If there is an error adding the tag
* to the case database.
*/
public synchronized TagName addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
lazyLoadExistingTagNames();
if (uniqueTagNames.containsKey(displayName)) {
throw new TagNameAlreadyExistsException();
}
// Add the tag name to the case.
TagName newTagName = tskCase.addTagName(displayName, description, color);
/*
* Add the tag name to the case.
*/
TagName newTagName = caseDb.addTagName(displayName, description, color);
// Add the tag name to the tags settings.
/*
* Add the tag name to the tags settings.
*/
uniqueTagNames.put(newTagName.getDisplayName(), newTagName);
saveTagNamesToTagsSettings();
@@ -189,7 +178,8 @@ public class TagsManager implements Closeable {
*
* @return A ContentTag data transfer object (DTO) representing the new tag.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error adding the tag to the case
* database.
*/
public ContentTag addContentTag(Content content, TagName tagName) throws TskCoreException {
return addContentTag(content, tagName, "", -1, -1);
@@ -204,7 +194,8 @@ public class TagsManager implements Closeable {
*
* @return A ContentTag data transfer object (DTO) representing the new tag.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error adding the tag to the case
* database.
*/
public ContentTag addContentTag(Content content, TagName tagName, String comment) throws TskCoreException {
return addContentTag(content, tagName, comment, -1, -1);
@@ -221,39 +212,44 @@ public class TagsManager implements Closeable {
*
* @return A ContentTag data transfer object (DTO) representing the new tag.
*
* @throws IllegalArgumentException, TskCoreException
* @throws IllegalArgumentException If a requested byte offset is out of
* range.
* @throws TskCoreException If there is an error adding the tag to
* the case database.
*/
public synchronized ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
public ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException {
ContentTag tag;
synchronized (this) {
lazyLoadExistingTagNames();
if (beginByteOffset >= 0 && endByteOffset >= 1) {
if (beginByteOffset > content.getSize() - 1) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(),
"TagsManager.addContentTag.exception.beginByteOffsetOOR.msg",
beginByteOffset, content.getSize() - 1));
}
if (endByteOffset > content.getSize() - 1) {
throw new IllegalArgumentException(
NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endByteOffsetOOR.msg",
endByteOffset, content.getSize() - 1));
}
if (endByteOffset < beginByteOffset) {
throw new IllegalArgumentException(
NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg"));
}
}
tag = caseDb.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset);
}
if (beginByteOffset >= 0 && endByteOffset >= 1) {
if (beginByteOffset > content.getSize() - 1) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(),
"TagsManager.addContentTag.exception.beginByteOffsetOOR.msg",
beginByteOffset, content.getSize() - 1));
}
if (endByteOffset > content.getSize() - 1) {
throw new IllegalArgumentException(
NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endByteOffsetOOR.msg",
endByteOffset, content.getSize() - 1));
}
if (endByteOffset < beginByteOffset) {
throw new IllegalArgumentException(
NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg"));
}
}
final ContentTag newContentTag = tskCase.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset);
try {
Case.getCurrentCase().notifyContentTagAdded(newContentTag);
Case.getCurrentCase().notifyContentTagAdded(tag);
} catch (IllegalStateException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.addContentTag.noCaseWarning"));
logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.addContentTag.noCaseWarning"), ex);
}
return newContentTag;
return tag;
}
/**
@@ -261,19 +257,19 @@ public class TagsManager implements Closeable {
*
* @param tag The tag to delete.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error deleting the tag from the
* case database.
*/
public synchronized void deleteContentTag(ContentTag tag) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
public void deleteContentTag(ContentTag tag) throws TskCoreException {
synchronized (this) {
lazyLoadExistingTagNames();
caseDb.deleteContentTag(tag);
}
tskCase.deleteContentTag(tag);
try {
Case.getCurrentCase().notifyContentTagDeleted(tag);
} catch (IllegalStateException e) {
Logger.getLogger(TagsManager.class.getName()).log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteContentTag.noCaseWarning"));
} catch (IllegalStateException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteContentTag.noCaseWarning"), ex);
}
}
@@ -282,15 +278,12 @@ public class TagsManager implements Closeable {
*
* @return A list, possibly empty, of content tags.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public List<ContentTag> getAllContentTags() throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getAllContentTags();
public synchronized List<ContentTag> getAllContentTags() throws TskCoreException {
lazyLoadExistingTagNames();
return caseDb.getAllContentTags();
}
/**
@@ -300,15 +293,12 @@ public class TagsManager implements Closeable {
*
* @return A count of the content tags with the specified tag name.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags count from
* the case database.
*/
public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getContentTagsCountByTagName(tagName);
lazyLoadExistingTagNames();
return caseDb.getContentTagsCountByTagName(tagName);
}
/**
@@ -316,17 +306,14 @@ public class TagsManager implements Closeable {
*
* @param tagID The tag id of interest.
*
* @return the content tag with the specified tag id.
* @return The content tag with the specified tag id.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tag from the
* case database.
*/
public synchronized ContentTag getContentTagByTagID(long tagID) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getContentTagByID(tagID);
lazyLoadExistingTagNames();
return caseDb.getContentTagByID(tagID);
}
/**
@@ -337,15 +324,12 @@ public class TagsManager implements Closeable {
* @return A list, possibly empty, of the content tags with the specified
* tag name.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public synchronized List<ContentTag> getContentTagsByTagName(TagName tagName) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getContentTagsByTagName(tagName);
lazyLoadExistingTagNames();
return caseDb.getContentTagsByTagName(tagName);
}
/**
@@ -356,15 +340,12 @@ public class TagsManager implements Closeable {
* @return A list, possibly empty, of the tags that have been applied to the
* artifact.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public synchronized List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getContentTagsByContent(content);
lazyLoadExistingTagNames();
return caseDb.getContentTagsByContent(content);
}
/**
@@ -376,7 +357,8 @@ public class TagsManager implements Closeable {
* @return A BlackboardArtifactTag data transfer object (DTO) representing
* the new tag.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error adding the tag to the case
* database.
*/
public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName) throws TskCoreException {
return addBlackboardArtifactTag(artifact, tagName, "");
@@ -392,21 +374,22 @@ public class TagsManager implements Closeable {
* @return A BlackboardArtifactTag data transfer object (DTO) representing
* the new tag.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error adding the tag to the case
* database.
*/
public synchronized BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException {
BlackboardArtifactTag tag;
synchronized (this) {
lazyLoadExistingTagNames();
tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment);
}
BlackboardArtifactTag addBlackboardArtifactTag = tskCase.addBlackboardArtifactTag(artifact, tagName, comment);
try {
Case.getCurrentCase().notifyBlackBoardArtifactTagAdded(addBlackboardArtifactTag);
} catch (IllegalStateException e) {
Logger.getLogger(TagsManager.class.getName()).log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.addBlackboardArtifactTag.noCaseWarning"));
Case.getCurrentCase().notifyBlackBoardArtifactTagAdded(tag);
} catch (IllegalStateException ex) {
logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.addBlackboardArtifactTag.noCaseWarning"), ex);
}
return addBlackboardArtifactTag;
return tag;
}
/**
@@ -414,19 +397,19 @@ public class TagsManager implements Closeable {
*
* @param tag The tag to delete.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error deleting the tag from the
* case database.
*/
public synchronized void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
public void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException {
synchronized (this) {
lazyLoadExistingTagNames();
caseDb.deleteBlackboardArtifactTag(tag);
}
tskCase.deleteBlackboardArtifactTag(tag);
try {
Case.getCurrentCase().notifyBlackBoardArtifactTagDeleted(tag);
} catch (IllegalStateException e) {
Logger.getLogger(TagsManager.class.getName()).log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteBlackboardArtifactTag.noCaseWarning"));
} catch (IllegalStateException ex) {
logger.log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteBlackboardArtifactTag.noCaseWarning"), ex);
}
}
@@ -435,15 +418,12 @@ public class TagsManager implements Closeable {
*
* @return A list, possibly empty, of blackboard artifact tags.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getAllBlackboardArtifactTags();
public synchronized List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException {
lazyLoadExistingTagNames();
return caseDb.getAllBlackboardArtifactTags();
}
/**
@@ -454,15 +434,12 @@ public class TagsManager implements Closeable {
* @return A count of the blackboard artifact tags with the specified tag
* name.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags count from
* the case database.
*/
public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getBlackboardArtifactTagsCountByTagName(tagName);
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsCountByTagName(tagName);
}
/**
@@ -472,15 +449,12 @@ public class TagsManager implements Closeable {
*
* @return the blackboard artifact tag with the specified tag id.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tag from the
* case database.
*/
public synchronized BlackboardArtifactTag getBlackboardArtifactTagByTagID(long tagID) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getBlackboardArtifactTagByID(tagID);
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagByID(tagID);
}
/**
@@ -491,15 +465,12 @@ public class TagsManager implements Closeable {
* @return A list, possibly empty, of the blackboard artifact tags with the
* specified tag name.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getBlackboardArtifactTagsByTagName(tagName);
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsByTagName(tagName);
}
/**
@@ -510,33 +481,43 @@ public class TagsManager implements Closeable {
* @return A list, possibly empty, of the tags that have been applied to the
* artifact.
*
* @throws TskCoreException
* @throws TskCoreException If there is an error getting the tags from the
* case database.
*/
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException {
// @@@ This is a work around to be removed when database access on the EDT is correctly synchronized.
if (!tagNamesInitialized) {
getExistingTagNames();
}
return tskCase.getBlackboardArtifactTagsByArtifact(artifact);
lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsByArtifact(artifact);
}
/**
* Saves the avaialble tag names to secondary storage.
*/
@Override
public void close() throws IOException {
public synchronized void close() throws IOException {
saveTagNamesToTagsSettings();
}
private void getExistingTagNames() {
getTagNamesFromCurrentCase();
getTagNamesFromTagsSettings();
getPredefinedTagNames();
saveTagNamesToTagsSettings();
tagNamesInitialized = true; // @@@ This is part of a work around to be removed when database access on the EDT is correctly synchronized.
/**
* Populates the tag names collection and the tag names table in the case
* database with the existing tag names from all sources.
*/
private void lazyLoadExistingTagNames() {
if (!tagNamesLoaded) {
addTagNamesFromCurrentCase();
addTagNamesFromTagsSettings();
addPredefinedTagNames();
saveTagNamesToTagsSettings();
tagNamesLoaded = true;
}
}
private void getTagNamesFromCurrentCase() {
/**
* Adds any tag names that are in the case database to the tag names
* collection.
*/
private void addTagNamesFromCurrentCase() {
try {
List<TagName> currentTagNames = tskCase.getAllTagNames();
List<TagName> currentTagNames = caseDb.getAllTagNames();
for (TagName tagName : currentTagNames) {
uniqueTagNames.put(tagName.getDisplayName(), tagName);
}
@@ -545,7 +526,12 @@ public class TagsManager implements Closeable {
}
}
private void getTagNamesFromTagsSettings() {
/**
* Adds any tag names that are in the properties file to the tag names
* collection and to the case database. The properties file is used to make
* it possible to use tag names across cases.
*/
private void addTagNamesFromTagsSettings() {
String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY);
if (null != setting && !setting.isEmpty()) {
// Read the tag name setting and break it into tag name tuples.
@@ -557,7 +543,7 @@ public class TagsManager implements Closeable {
String[] tagNameAttributes = tagNameTuple.split(",");
if (!uniqueTagNames.containsKey(tagNameAttributes[0])) {
try {
TagName tagName = tskCase.addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2]));
TagName tagName = caseDb.addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2]));
uniqueTagNames.put(tagName.getDisplayName(), tagName);
} catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS
@@ -567,18 +553,25 @@ public class TagsManager implements Closeable {
}
}
private void getPredefinedTagNames() {
/**
* Adds the standard tag names to the tag names collection.
*/
private void addPredefinedTagNames() {
if (!uniqueTagNames.containsKey(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))) {
try {
TagName tagName = tskCase.addTagName(
TagName tagName = caseDb.addTagName(
NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), "", TagName.HTML_COLOR.NONE);
uniqueTagNames.put(tagName.getDisplayName(), tagName);
} catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add predefined 'Bookmark' tag name", ex); //NON-NLS
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add standard 'Bookmark' tag name to case database", ex); //NON-NLS
}
}
}
/**
* Saves the tag names to a properties file. The properties file is used to
* make it possible to use tag names across cases.
*/
private void saveTagNamesToTagsSettings() {
if (!uniqueTagNames.isEmpty()) {
StringBuilder setting = new StringBuilder();
@@ -593,4 +586,13 @@ public class TagsManager implements Closeable {
ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString());
}
}
/**
* Exception thrown if there is an attempt to add a duplicate tag name.
*/
public static class TagNameAlreadyExistsException extends Exception {
private static final long serialVersionUID = 1L;
}
}
@@ -389,7 +389,11 @@ public class ServicesMonitor {
*/
@Override
public void run() {
checkAllServices();
try {
checkAllServices();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Unexpected exception in CrashDetectionTask", ex); //NON-NLS
}
}
}
@@ -22,18 +22,24 @@ import javax.swing.JPanel;
/**
* Interface implemented by classes that add data sources of a particular type
* (e.g., images, local disks, virtual directories of local/logical files, etc.)
* to a case database. A data source processor is NOT responsible for analyzing
* the data source (running ingest modules on the data source and its contents).
* (e.g., images, local disks, virtual directories of local/logical files) to a
* case database. A data source processor is NOT responsible for analyzing the
* data source, i.e., running ingest modules on the data source and its
* contents.
*
* Data source processors plug in to the add data source wizard and should
* provide a JPanel to allow a user to select a data source and do any
* configuration the data source processor may require. The panel should support
* addition of the add data source wizard as a property change listener and
* should fire DSP_PANEL_EVENT property changes to communicate with the wizard.
* provide a UI panel to allow a user to select a data source and do any
* configuration required by the data source processor. The selection and
* configuration panel should support addition of the add data source wizard as
* a property change listener and should fire DSP_PANEL_EVENT property change
* events to communicate with the wizard.
*
* Data source processors should perform all processing on a separate thread,
* reporting results using a callback object.
* Data source processors should perform all processing in a background task in
* a separate thread, reporting results using a callback object.
*
* It is recommended that implementers provide an overload of the run method
* that allows the data source processor to be run independently of the
* selection and configuration panel.
*/
public interface DataSourceProcessor {
@@ -48,64 +54,76 @@ public interface DataSourceProcessor {
enum DSP_PANEL_EVENT {
/**
* Fire this event when the user changes something in the panel to
* notify the add data source wizard that it should call isPanelValid.
* This event is fired when the user changes something in the selection
* and configuration panel. It notifies the add data source wizard that
* it should call isPanelValid.
*/
UPDATE_UI,
/**
* Fire this event to make the add data source wizard move focus to the
* next button.
* This event is fired to make the add data source wizard move focus to
* the wizard's next button.
* @deprecated Use UPDATE_UI.
*/
@Deprecated
FOCUS_NEXT
};
/**
* Gets a string that describes the type of data sources this processor is
* able to process.
* able to add to the case database. The string is suitable for display in a
* type selection UI component (e.g., a combo box).
*
* @return A string suitable for display in a data source processor
* selection UI component (e.g., a combo box).
* @return A data source type display string for this data source processor.
*/
String getDataSourceType();
/**
* Gets the panel that allows a user to select a data source and do any
* configuration the data source processor may require.
* configuration required by the data source. The panel is less than 544
* pixels wide and less than 173 pixels high.
*
* @return A JPanel less than 544 pixels wide and 173 pixels high.
* @return A selection and configuration panel for this data source
* processor.
*/
JPanel getPanel();
/**
* Indicates whether the settings in the panel are valid and complete.
* Indicates whether the settings in the selection and configuration panel
* are valid and complete.
*
* @return True if the settings are valid and complete and the processor is
* ready to have its run method called; false otherwise.
* ready to have its run method called, false otherwise.
*/
boolean isPanelValid();
/**
* Adds a data source to the case database using a separate thread and the
* settings provided by the panel. Returns as soon as the background task is
* started and uses the callback object to signal task completion and return
* results.
* Adds a data source to the case database using a background task in a
* separate thread and the settings provided by the selection and
* configuration panel. Returns as soon as the background task is started.
* The background task uses a callback object to signal task completion and
* return results.
*
* NOTE: This method should not be called unless isPanelValid returns true.
* This method should not be called unless isPanelValid returns true.
*
* @param progressMonitor Progress monitor for reporting progress during
* processing.
* @param callback Callback to call when processing is done.
* @param progressMonitor Progress monitor that will be used by the
* background task to report progress.
* @param callback Callback that will be used by the background task
* to return results.
*/
void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback);
/**
* Requests cancellation of the data source processing task after it is
* started using the run method. Cancellation is not guaranteed.
* Requests cancellation of the background task that adds a data source to
* the case database, after the task is started using the run method. This
* is a "best effort" cancellation, with no guarantees that the case
* database will be unchanged. If cancellation succeeded, the list of new
* data sources returned by the background task will be empty.
*/
void cancel();
/**
* Resets the panel.
* Resets the selection and configuration panel for this data source
* processor.
*/
void reset();
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2014 Basis Technology Corp.
* Copyright 2013-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,56 +23,72 @@ import java.util.List;
import org.sleuthkit.datamodel.Content;
/**
* Abstract class for a callback for a DataSourceProcessor.
*
* Ensures that DSP invokes the caller overridden method, doneEDT(), in the EDT
* thread.
* An abstract base class for callback objects to be given to data source
* processors for use by the background tasks that add data sources to a case
* database. The callback objects are used to signal task completion and return
* results.
*
* Concrete implementations of DataSourceProcessorCallback should override
* either the done method or the doneEDT method, but not both.
*/
public abstract class DataSourceProcessorCallback {
public enum DataSourceProcessorResult {
NO_ERRORS, ///< No errors were encountered while ading the data source
CRITICAL_ERRORS, ///< No data was added to the database. There were fundamental errors processing the data (such as no data or system failure).
NONCRITICAL_ERRORS, ///< There was data added to the database, but there were errors from data corruption or a small number of minor issues.
/**
* No errors occurred while ading the data source to the case database.
*/
NO_ERRORS,
/**
* Critical errors occurred while ading the data source to the case
* database. The data source was not added to the case database.
*/
CRITICAL_ERRORS,
/**
* Non-critical errors occurred while adding the data source to the case
* database. The data source was added to the database, but the data
* source may have been corrupted in some way.
*/
NONCRITICAL_ERRORS
};
/**
* Called by a DSP implementation when it is done adding a data source to
* the database. Users of the DSP can override this method if they do not
* want to be notified on the EDT. Otherwise, this method will call
* doneEDT() with the same arguments.
* Called by a data source processor when it is done adding a data source to
* the case database, this method adds a task to call the doneEDT method to
* the EDT task queue.
*
* @param result Code for status
* @param errList List of error strings
* @param newContents List of root Content objects that were added to
* database. Typically only one is given.
* IMPORTANT: Concrete implementations of DataSourceProcessorCallback should
* override this method if the callback SHOULD NOT be done in the EDT.
*
* @param result Result code.
* @param errList List of error messages, possibly empty.
* @param newDataSources A list of the data sources added, empty if critical
* errors occurred or processing was successfully
* cancelled.
*/
public void done(DataSourceProcessorResult result, List<String> errList, List<Content> newContents) {
public void done(DataSourceProcessorResult result, List<String> errList, List<Content> newDataSources) {
final DataSourceProcessorResult resultf = result;
final List<String> errListf = errList;
final List<Content> newContentsf = newContents;
// Invoke doneEDT() that runs on the EDT .
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
doneEDT(resultf, errListf, newContentsf);
}
final List<Content> newContentsf = newDataSources;
EventQueue.invokeLater(() -> {
doneEDT(resultf, errListf, newContentsf);
});
}
/**
* Called by done() if the default implementation is used. Users of DSPs
* that have UI updates to do after the DSP is finished adding the DS can
* implement this method to receive the updates on the EDT.
* Called by a data source processor when it is done adding a data source to
* the case database, if the default done method has not been overridden.
*
* @param result Code for status
* @param errList List of error strings
* @param newContents List of root Content objects that were added to
* database. Typically only one is given.
* IMPORTANT: Concrete implementations of DataSourceProcessorCallback should
* override the done method and provide an implementation of this method
* that throws an UnsupportedOperationException if the callback SHOULD NOT
* be done in the EDT.
*
* @param result Result code.
* @param errList List of error messages, possibly empty.
* @param newDataSources A list of the data sources added, empty if critical
* errors occurred or processing was successfully
* cancelled.
*/
public abstract void doneEDT(DataSourceProcessorResult result, List<String> errList, List<Content> newContents);
abstract public void doneEDT(DataSourceProcessorResult result, List<String> errList, List<Content> newDataSources);
};
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,16 +47,22 @@ import org.sleuthkit.datamodel.SleuthkitJNI;
*/
public final class AboutWindowPanel extends JPanel implements HyperlinkListener {
private static final Logger Logger = org.sleuthkit.autopsy.coreutils.Logger.getLogger(AboutWindowPanel.class.getName());
private static final long serialVersionUID = 1L;
private URL url = null;
private Icon about;
private final Icon about;
private boolean verboseLogging;
public AboutWindowPanel() {
about = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/splash.png"));
init();
}
public AboutWindowPanel(String pathToBrandingImage) {
about = new ImageIcon(ImageUtilities.loadImage(pathToBrandingImage));
init();
}
private void init() {
initComponents();
logoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
description.setText(org.openide.util.NbBundle.getMessage(AboutWindowPanel.class,
@@ -67,8 +73,7 @@ public final class AboutWindowPanel extends JPanel implements HyperlinkListener
copyright.setBackground(getBackground());
if (verboseLoggingIsSet()) {
disableVerboseLoggingButton();
}
}
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@@ -148,7 +148,7 @@ FXVideoPanel.progress.bufferingCancelled=media buffering was canceled
FXVideoPanel.progress.bufferingInterrupted=media buffering was interrupted
FXVideoPanel.progress.errorWritingVideoToDisk=Error writing video to disk
OptionsCategory_Name_Multi_User_Settings=Multi-user
OptionsCategory_Keywords_Multi_User_Options=Multi-user Options
OptionsCategory_Keywords_Multi_User_Options=Multi-user Settings
MultiUserSettingsPanel.lbSolrSettings.text=Solr Settings
MultiUserSettingsPanel.cbEnableMultiUser.text=Enable Multi-user cases
MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings
@@ -488,7 +488,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// if the artifact has an ASSOCIATED ARTIFACT, then we display the associated artifact instead
try {
for (BlackboardAttribute attr : artifact.getAttributes()) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
long assocArtifactId = attr.getValueLong();
int assocArtifactIndex = -1;
for (BlackboardArtifact art : artifacts) {
@@ -28,9 +28,7 @@ import java.util.TreeSet;
import java.util.logging.Level;
import javax.swing.JPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Video viewer part of the Media View layered pane. Uses different engines
@@ -133,23 +131,18 @@ public abstract class MediaViewVideoPanel extends JPanel implements FrameCapture
@Override
public boolean isSupported(AbstractFile file) {
/*
* TODO (AUT-2042): Is this the logic we want?
*/
String extension = file.getNameExtension();
//TODO: is this what we want, to require both extension and mimetype support?
if (AUDIO_EXTENSIONS.contains("." + extension) || getExtensionsList().contains("." + extension)) {
SortedSet<String> mimeTypes = new TreeSet<>(getMimeTypes());
try {
String mimeType = new FileTypeDetector().getFileType(file);
if (nonNull(mimeType)) {
return mimeTypes.contains(mimeType);
}
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
logger.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex);
if (!mimeTypes.isEmpty() && file.isMimeType(mimeTypes) == AbstractFile.MimeMatchEnum.TRUE) {
return true;
}
String mimeType = file.getMIMEType();
if (nonNull(mimeType)) {
return mimeTypes.contains(mimeType);
} else {
return getExtensionsList().contains("." + extension);
}
return getExtensionsList().contains("." + extension);
}
return false;
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,38 +23,67 @@ import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
/**
* Complementary class to TableFilterNode.
* A children (child factory) implementation for a TableFilterNode. A
* TableFilterNode creates at most one layer of child nodes for the node it
* wraps. It is designed to be used for nodes displayed in Autopsy table views.
*/
class TableFilterChildren extends FilterNode.Children {
/**
* the constructor
* Constructs a children (child factory) implementation for a
* TableFilterNode. A TableFilterNode creates at most one layer of child
* nodes for the node it wraps. It is designed to be used for nodes
* displayed in Autopsy table views.
*
* @param wrappedNode The node wrapped by the TableFilterNode.
*/
TableFilterChildren(Node arg) {
super(arg);
}
@Override
protected Node copyNode(Node arg0) {
return new TableFilterNode(arg0, false);
}
@Override
protected Node[] createNodes(Node arg0) {
// filter out the children
return new Node[]{this.copyNode(arg0)};
TableFilterChildren(Node wrappedNode) {
super(wrappedNode);
}
/**
* Converts the given FsContent into "Children".
* Copies a TableFilterNode, with the create children (child factory) flag
* set to false.
*
* @param fs
* @param nodeToCopy The TableFilterNode to copy.
*
* @return children
* @return A copy of a TableFilterNode.
*/
public static Children createInstance(Node arg, boolean createChild) {
if (createChild) {
return new TableFilterChildren(arg);
@Override
protected Node copyNode(Node nodeToCopy) {
return new TableFilterNode(nodeToCopy, false);
}
/**
* Creates the child nodes represented by this children (child factory)
* object.
*
* @param key The key, i.e., the node, for which to create the child nodes.
*
* @return
*/
@Override
protected Node[] createNodes(Node key) {
return new Node[]{this.copyNode(key)};
}
/**
* Creates a children (child factory) object for a node wrapped in a
* TableFilterNode. A TableFilterNode creates at most one layer of child
* nodes for the node it wraps. It is designed to be used for nodes
* displayed in Autopsy table views.
*
*
* @param wrappedNode The node wrapped by the TableFilterNode.
* @param createChildren True if a children (child factory) object should be
* created for the wrapped node.
*
* @return A children (child factory) object for a node wrapped by a
* TableFilterNode.
*/
public static Children createInstance(Node wrappedNode, boolean createChildren) {
if (createChildren) {
return new TableFilterChildren(wrappedNode);
} else {
return Children.LEAF;
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,48 +23,40 @@ import org.openide.nodes.Node;
import org.openide.util.NbBundle;
/**
* This class is used to filter the nodes that we want to show on the
* "TreeTableView". So basically we just want to show one layer of nodes from
* it's parent.
*
* @author jantonius
* A filter node that creates at most one layer of child nodes for the node it
* wraps. It is designed to be used for nodes displayed in Autopsy table views.
*/
public class TableFilterNode extends FilterNode {
private boolean createChild;
private String itemType;
private final boolean createChildren;
/**
* the constructor
*/
public TableFilterNode(Node arg, boolean crChild) {
super(arg, TableFilterChildren.createInstance(arg, crChild));
this.createChild = crChild;
this.itemType = "";
}
public TableFilterNode(Node arg, boolean crChild, String itemType) {
super(arg, TableFilterChildren.createInstance(arg, crChild));
this.createChild = crChild;
this.itemType = itemType;
}
/**
* Override the display name / header for the first (tree) column on the
* "TreeTableView".
* Constructs a filter node that creates at most one layer of child nodes
* for the node it wraps. It is designed to be used for nodes displayed in
* Autopsy table views.
*
* @return disName the display name for the first column
* @param wrappedNode The node to wrap in the filter node.
* @param createChildren True if a children (child factory) object should be
* created for the wrapped node.
*/
public TableFilterNode(Node wrappedNode, boolean createChildren) {
super(wrappedNode, TableFilterChildren.createInstance(wrappedNode, createChildren));
this.createChildren = createChildren;
}
/**
* Returns a display name for the wrapped node, for use in the first column
* of an Autopsy table view.
*
* @return The display name.
*/
@Override
public String getDisplayName() {
if (createChild) {
if (createChildren) {
return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text");
} else {
return super.getDisplayName();
}
}
public String getItemType() {
return itemType;
}
}
@@ -149,8 +149,8 @@ public class ImageUtils {
/**
* thread that saves generated thumbnails to disk in the background
*/
private static final Executor imageSaver =
Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
private static final Executor imageSaver
= Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
.namingPattern("icon saver-%d").build()); //NOI18N NON-NLS
public static List<String> getSupportedImageExtensions() {
@@ -223,40 +223,19 @@ public class ImageUtils {
}
/**
* Does the image have a GIF mimetype.
* Checks the MIME type of a file to determine whether it is a GIF. If the
* MIME type is not known, checks for a "gif" extension.
*
* @param file
* @param file The file to be checked.
*
* @return true if the given file has a GIF mimetype
* @return True or false
*/
public static boolean isGIF(AbstractFile file) {
try {
final FileTypeDetector myFileTypeDetector = getFileTypeDetector();
if (nonNull(myFileTypeDetector)) {
String fileType = myFileTypeDetector.getFileType(file);
return IMAGE_GIF_MIME.equalsIgnoreCase(fileType);
}
} catch (FileTypeDetectorInitException ex) {
LOGGER.log(Level.WARNING, "Failed to initialize FileTypeDetector.", ex); //NOI18N NON-NLS
} catch (TskCoreException ex) {
if (ex.getMessage().contains("An SQLException was provoked by the following failure: java.lang.InterruptedException")) { //NON-NLS
LOGGER.log(Level.WARNING, "Mime type look up with FileTypeDetector was interupted."); //NOI18N} NON-NLS
return "gif".equalsIgnoreCase(file.getNameExtension()); //NOI18N
} else {
LOGGER.log(Level.SEVERE, "Failed to get mime type of " + getContentPathSafe(file) + " with FileTypeDetector.", ex); //NOI18N} NON-NLS
}
}
LOGGER.log(Level.WARNING, "Falling back on direct mime type check for {0}.", getContentPathSafe(file)); //NOI18N NON-NLS
switch (file.isMimeType(GIF_MIME_SET)) {
case TRUE:
return true;
case UNDEFINED:
LOGGER.log(Level.WARNING, "Falling back on extension check."); //NOI18N NON-NLS
return "gif".equalsIgnoreCase(file.getNameExtension()); //NOI18N
case FALSE:
default:
return false;
String mimeType = file.getMIMEType();
if (nonNull(mimeType)) {
return IMAGE_GIF_MIME.equalsIgnoreCase(mimeType);
} else {
return "gif".equalsIgnoreCase(file.getNameExtension()); //NOI18N
}
}
@@ -283,25 +262,15 @@ public class ImageUtils {
if (file.getSize() == 0) {
return false;
}
final String extension = file.getNameExtension();
try {
String mimeType = getFileTypeDetector().getFileType(file);
if (Objects.nonNull(mimeType)) {
return supportedMimeTypes.contains(mimeType)
|| (conditionalMimes.contains(mimeType.toLowerCase()) && supportedExtension.contains(extension));
}
} catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) {
LOGGER.log(Level.WARNING, "Failed to look up mimetype for {0} using FileTypeDetector:{1}", new Object[]{getContentPathSafe(file), ex.toString()}); //NOI18N NON-NLS
LOGGER.log(Level.INFO, "Falling back on AbstractFile.isMimeType"); //NOI18N NON-NLS
AbstractFile.MimeMatchEnum mimeMatch = file.isMimeType(supportedMimeTypes);
if (mimeMatch == AbstractFile.MimeMatchEnum.TRUE) {
return true;
} else if (mimeMatch == AbstractFile.MimeMatchEnum.FALSE) {
return false;
}
String mimeType = file.getMIMEType();
String extension = file.getNameExtension();
if (nonNull(mimeType)) {
return supportedMimeTypes.contains(mimeType)
|| (conditionalMimes.contains(mimeType.toLowerCase())
&& supportedExtension.contains(extension));
} else {
return StringUtils.isNotBlank(extension) && supportedExtension.contains(extension);
}
// if we have an extension, check it
return StringUtils.isNotBlank(extension) && supportedExtension.contains(extension);
}
/**
@@ -934,7 +903,7 @@ public class ImageUtils {
*
* @return
*/
static String getContentPathSafe(Content content) {
static String getContentPathSafe(Content content) {
try {
return content.getUniquePath();
} catch (TskCoreException tskCoreException) {
@@ -72,19 +72,19 @@ public class ArtifactStringContent implements StringContent {
// name column
buffer.append("<tr><td>"); //NON-NLS
buffer.append(attr.getAttributeTypeDisplayName());
buffer.append(attr.getAttributeType().getDisplayName());
buffer.append("</td>"); //NON-NLS
// value column
buffer.append("<td>"); //NON-NLS
if (attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()) {
if (attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()) {
long epoch = attr.getValueLong();
String time = "0000-00-00 00:00:00";
if (epoch != 0) {
@@ -93,7 +93,7 @@ public class ArtifactStringContent implements StringContent {
}
buffer.append(time);
} else {
switch (attr.getValueType()) {
switch (attr.getAttributeType().getValueType()) {
case STRING:
String str = attr.getValueString();
str = str.replaceAll(" ", "&nbsp;"); //NON-NLS
@@ -117,7 +117,7 @@ public class ArtifactStringContent implements StringContent {
case DATETIME:
buffer.append(attr.getValueLong());
break;
}
}
if (!"".equals(attr.getContext())) {
@@ -117,7 +117,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
if (artifact != null && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
try {
for (BlackboardAttribute attribute : artifact.getAttributes()) {
if (attribute.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
if (attribute.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
BlackboardArtifact associatedArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(attribute.getValueLong());
if (associatedArtifact != null) {
displayName = associatedArtifact.getDisplayName() + " Artifact"; // NON-NLS
@@ -171,7 +171,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
AbstractFile af = (AbstractFile) associated;
ext = af.getNameExtension();
actualMimeType = af.getMIMEType();
if(actualMimeType == null) {
if (actualMimeType == null) {
actualMimeType = "";
}
}
@@ -179,11 +179,11 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.displayName"),
NO_DESCR,
ext));
ss.put(new NodeProperty<>(
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.name"),
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.displayName"),
NO_DESCR,
actualMimeType));
ss.put(new NodeProperty<>(
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.name"),
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.displayName"),
NO_DESCR,
actualMimeType));
}
if (Arrays.asList(SHOW_UNIQUE_PATH).contains(artifactTypeId)) {
@@ -282,8 +282,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
/**
* Fill map with Artifact properties
*
* @param map map with preserved ordering, where property names/values are
* put
* @param map map with preserved ordering, where property names/values
* are put
* @param artifact to extract properties from
*/
@SuppressWarnings("deprecation") // TODO: Remove this when TSK_TAGGED_ARTIFACT rows are removed in a database upgrade.
@@ -384,7 +384,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
String keyword = null;
String regexp = null;
for (BlackboardAttribute att : attributes) {
final int attributeTypeID = att.getAttributeTypeID();
final int attributeTypeID = att.getAttributeType().getTypeID();
if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
keyword = att.getValueString();
} else if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()) {
@@ -271,8 +271,8 @@ public class DataResultFilterNode extends FilterNode {
Content c = null;
try {
for (BlackboardAttribute attr : art.getAttributes()) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
switch (attr.getValueType()) {
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
switch (attr.getAttributeType().getValueType()) {
case INTEGER:
int i = attr.getValueInt();
if (i != -1) {
@@ -865,7 +865,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
String setName = null;
List<BlackboardAttribute> attributes = art.getAttributes();
for (BlackboardAttribute att : attributes) {
int typeId = att.getAttributeTypeID();
int typeId = att.getAttributeType().getTypeID();
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
setName = att.getValueString();
}
@@ -882,7 +882,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
String keywordName = null;
List<BlackboardAttribute> attributes = art.getAttributes();
for (BlackboardAttribute att : attributes) {
int typeId = att.getAttributeTypeID();
int typeId = att.getAttributeType().getTypeID();
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
listName = att.getValueString();
} else if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
@@ -909,7 +909,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
String setName = null;
List<BlackboardAttribute> attributes = art.getAttributes();
for (BlackboardAttribute att : attributes) {
int typeId = att.getAttributeTypeID();
int typeId = att.getAttributeType().getTypeID();
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
setName = att.getValueString();
}
@@ -40,7 +40,7 @@ public final class AutopsyEventPublisher {
* Composed of thread-safe objects.
*/
private static final Logger logger = Logger.getLogger(AutopsyEventPublisher.class.getName());
private static final int MAX_REMOTE_EVENT_PUBLISH_TRIES = 3;
private static final int MAX_REMOTE_EVENT_PUBLISH_TRIES = 1;
private final LocalEventPublisher localPublisher;
private RemoteEventPublisher remotePublisher;
private String currentChannelName;
@@ -86,15 +86,8 @@ public final class AutopsyEventPublisher {
* events from other Autopsy nodes.
*/
public void closeRemoteEventChannel() {
stopRemotePublisher();
currentChannelName = null;
if (null != remotePublisher) {
try {
remotePublisher.stop();
} catch (JMSException ex) {
logger.log(Level.SEVERE, "Error closing remote event channel", ex); //NON-NLS
}
remotePublisher = null;
}
}
/**
@@ -162,12 +155,10 @@ public final class AutopsyEventPublisher {
* @param event The event to publish.
*/
public void publishRemotely(AutopsyEvent event) {
/*
* This is a no-op if a remote channel has not been opened.
*/
if (null != currentChannelName) {
boolean published = false;
int tryCount = 1;
while (false == published && tryCount <= MAX_REMOTE_EVENT_PUBLISH_TRIES) {
try {
if (null == remotePublisher) {
@@ -175,16 +166,28 @@ public final class AutopsyEventPublisher {
}
remotePublisher.publish(event);
published = true;
} catch (JMSException ex) {
} catch (AutopsyEventException | JMSException ex) {
logger.log(Level.SEVERE, String.format("Failed to publish %s using channel %s (tryCount = %s)", event.getPropertyName(), currentChannelName, tryCount), ex); //NON-NLS
closeRemoteEventChannel();
++tryCount;
} catch (AutopsyEventException ex) {
logger.log(Level.SEVERE, String.format("Failed to reopen channel %s to publish %s event (tryCount = %s)", currentChannelName, event.getPropertyName(), tryCount), ex); //NON-NLS
stopRemotePublisher();
++tryCount;
}
}
}
}
}
/**
* Stops the remote event publisher, but does not reset the current channel
* name.
*/
private void stopRemotePublisher() {
if (null != remotePublisher) {
try {
remotePublisher.stop();
} catch (JMSException ex) {
logger.log(Level.SEVERE, String.format("Error closing remote event publisher for channel %s", currentChannelName), ex); //NON-NLS
}
remotePublisher = null;
}
}
}
@@ -144,7 +144,7 @@ public final class MessageServiceConnectionInfo {
} catch (JMSException ex) {
String result;
Throwable cause = ex.getCause();
if (cause != null) {
if (null != cause && null != cause.getMessage()) {
// there is more information from another exception
String msg = cause.getMessage();
if (msg.startsWith(CONNECTION_TIMED_OUT)) {
@@ -115,5 +115,5 @@ IngestJob.cancelReason.notCancelled.text=Not cancelled
IngestJob.cancelReason.cancelledByUser.text=Cancelled by user
IngestJob.cancelReason.ingestModStartFail.text=Ingest modules startup failed
IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space
IngestJob.cancelReason.servicesDown.text=Not cancelled
IngestJob.cancelReason.servicesDown.text=Services Down
IngestJob.cancelReason.caseClosed.text=Case closed
@@ -1,116 +1,115 @@
CTL_IngestMessageTopComponent=\u30E1\u30C3\u30BB\u30FC\u30B8
HINT_IngestMessageTopComponent=\u30E1\u30C3\u30BB\u30FC\u30B8\u30A6\u30A3\u30F3\u30C9\u30A6
IngestDialog.closeButton.title=\u9589\u3058\u308B
IngestDialog.startButton.title=\u958B\u59CB
IngestDialog.title.text=\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
IngestJob.progress.cancelling={0}\uFF08\u30AD\u30E3\u30F3\u30BB\u30EB\u4E2D\u2026\uFF09
IngestJob.progress.dataSourceIngest.displayName={1}\u306E{0}
IngestJob.progress.fileIngest.displayName={0}\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u89E3\u6790\u4E2D
IngestManager.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
IngestManager.moduleErr.errListenToUpdates.msg=Ingest Manager\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u4E0D\u5B8C\u5168\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
IngestManager.StartIngestJobsTask.run.cancelling={0}\uFF08\u30AD\u30E3\u30F3\u30BB\u30EB\u4E2D\u2026\uFF09
IngestManager.StartIngestJobsTask.run.displayName=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u958B\u59CB\u4E2D
IngestMessage.exception.srcSubjDetailsDataNotNull.msg=\u30BD\u30FC\u30B9\u3001\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u3001\u8A73\u7D30\u304A\u3088\u3073\u30C7\u30FC\u30BF\u306F\u30CC\u30EB\u3067\u306F\u3044\u3051\u307E\u305B\u3093
IngestMessage.exception.srcSubjNotNull.msg=\u30BD\u30FC\u30B9\u304A\u3088\u3073\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u306F\u30CC\u30EB\u3067\u306F\u3044\u3051\u307E\u305B\u3093
IngestMessage.exception.typeSrcSubjNotNull.msg=\u30E1\u30C3\u30BB\u30FC\u30B8\u30BF\u30A4\u30D7\u3001\u30BD\u30FC\u30B9\u304A\u3088\u3073\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u306F\u30CC\u30EB\u3067\u306F\u3044\u3051\u307E\u305B\u3093
IngestMessage.toString.data.text=\ \u30C7\u30FC\u30BF\uFF1A{0}
IngestMessage.toString.date.text=\ \u65E5\u4ED8\uFF1A{0}
IngestMessage.toString.details.text=\ \u8A73\u7D30\uFF1A{0}
IngestMessage.toString.subject.text=\ \u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\uFF1A{0}
IngestMessage.toString.type.text=\u30BF\u30A4\u30D7\uFF1A{0}
IngestMessageDetailsPanel.copyMenuItem.text=\u30B3\u30D4\u30FC
IngestMessageDetailsPanel.messageDetailsPane.contentType=\u30C6\u30AD\u30B9\u30C8\uFF0Fhtml
IngestMessageDetailsPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E
IngestMessageDetailsPanel.viewArtifactButton.text=\u7D50\u679C\u3078\u79FB\u52D5
IngestMessageDetailsPanel.viewContentButton.text=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3078\u79FB\u52D5
IngestMessagePanel.BooleanRenderer.exception.nonBoolVal.msg=\u30D6\u30FC\u30EB\u5024\u3067\u306F\u306A\u3044\u3082\u306E\u306BBooleanRenderer\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F\u3002
IngestMessagePanel.DateRenderer.exception.nonDateVal.text=\u65E5\u4ED8\u3067\u306F\u306A\u3044\u3082\u306E\u306BDateRenderer\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u307E\u3057\u305F\u3002
IngestMessagePanel.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
IngestMessagePanel.moduleErr.errListenUpdates.text=IngestMessagePanel\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u4E0D\u5B8C\u5168\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
IngestMessagePanel.MsgTableMod.colNames.module=\u30E2\u30B8\u30E5\u30FC\u30EB
IngestMessagePanel.MsgTableMod.colNames.new=\u65B0\u898F\uFF1F
IngestMessagePanel.MsgTableMod.colNames.num=\u756A\u53F7
IngestMessagePanel.MsgTableMod.colNames.subject=\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8
IngestMessagePanel.MsgTableMod.colNames.timestamp=\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7
IngestMessagePanel.sortByComboBox.model.priority=\u512A\u5148\u5EA6
CTL_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8
HINT_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8\u30a6\u30a3\u30f3\u30c9\u30a6
IngestDialog.closeButton.title=\u9589\u3058\u308b
IngestDialog.startButton.title=\u958b\u59cb
IngestDialog.title.text=\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8
IngestJob.progress.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
IngestJob.progress.dataSourceIngest.displayName={1}\u306e{0}
IngestJob.progress.fileIngest.displayName={0}\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d
IngestManager.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
IngestManager.moduleErr.errListenToUpdates.msg=Ingest Manager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
IngestManager.StartIngestJobsTask.run.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
IngestManager.StartIngestJobsTask.run.displayName=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u958b\u59cb\u4e2d
IngestMessage.exception.srcSubjDetailsDataNotNull.msg=\u30bd\u30fc\u30b9\u3001\u30b5\u30d6\u30b8\u30a7\u30af\u30c8\u3001\u8a73\u7d30\u304a\u3088\u3073\u30c7\u30fc\u30bf\u306f\u30cc\u30eb\u3067\u306f\u3044\u3051\u307e\u305b\u3093
IngestMessage.exception.srcSubjNotNull.msg=\u30bd\u30fc\u30b9\u304a\u3088\u3073\u30b5\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u30cc\u30eb\u3067\u306f\u3044\u3051\u307e\u305b\u3093
IngestMessage.exception.typeSrcSubjNotNull.msg=\u30e1\u30c3\u30bb\u30fc\u30b8\u30bf\u30a4\u30d7\u3001\u30bd\u30fc\u30b9\u304a\u3088\u3073\u30b5\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u30cc\u30eb\u3067\u306f\u3044\u3051\u307e\u305b\u3093
IngestMessage.toString.data.text=\ \u30c7\u30fc\u30bf\uff1a{0}
IngestMessage.toString.date.text=\ \u65e5\u4ed8\uff1a{0}
IngestMessage.toString.details.text=\ \u8a73\u7d30\uff1a{0}
IngestMessage.toString.subject.text=\ \u30b5\u30d6\u30b8\u30a7\u30af\u30c8\uff1a{0}
IngestMessage.toString.type.text=\u30bf\u30a4\u30d7\uff1a{0}
IngestMessageDetailsPanel.copyMenuItem.text=\u30b3\u30d4\u30fc
IngestMessageDetailsPanel.messageDetailsPane.contentType=\u30c6\u30ad\u30b9\u30c8\uff0fhtml
IngestMessageDetailsPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e
IngestMessageDetailsPanel.viewArtifactButton.text=\u7d50\u679c\u3078\u79fb\u52d5
IngestMessageDetailsPanel.viewContentButton.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u79fb\u52d5
IngestMessagePanel.BooleanRenderer.exception.nonBoolVal.msg=\u30d6\u30fc\u30eb\u5024\u3067\u306f\u306a\u3044\u3082\u306e\u306bBooleanRenderer\u3092\u4f7f\u7528\u3057\u3088\u3046\u3068\u3057\u307e\u3057\u305f\u3002
IngestMessagePanel.DateRenderer.exception.nonDateVal.text=\u65e5\u4ed8\u3067\u306f\u306a\u3044\u3082\u306e\u306bDateRenderer\u3092\u4f7f\u7528\u3057\u3088\u3046\u3068\u3057\u307e\u3057\u305f\u3002
IngestMessagePanel.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
IngestMessagePanel.moduleErr.errListenUpdates.text=IngestMessagePanel\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
IngestMessagePanel.MsgTableMod.colNames.module=\u30e2\u30b8\u30e5\u30fc\u30eb
IngestMessagePanel.MsgTableMod.colNames.new=\u65b0\u898f\uff1f
IngestMessagePanel.MsgTableMod.colNames.num=\u756a\u53f7
IngestMessagePanel.MsgTableMod.colNames.subject=\u30b5\u30d6\u30b8\u30a7\u30af\u30c8
IngestMessagePanel.MsgTableMod.colNames.timestamp=\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7
IngestMessagePanel.sortByComboBox.model.priority=\u512a\u5148\u5ea6
IngestMessagePanel.sortByComboBox.model.time=\u6642\u9593
IngestMessagePanel.sortByComboBox.toolTipText=\u6642\u9593\u9806\uFF08\u6642\u7CFB\u5217\uFF09\u307E\u305F\u306F\u30E1\u30C3\u30BB\u30FC\u30B8\u306E\u512A\u5148\u5EA6\u3067\u30BD\u30FC\u30C8
IngestMessagePanel.sortByLabel.text=\u6B21\u3067\u30BD\u30FC\u30C8\uFF1A
IngestMessagePanel.totalMessagesNameLabel.text=\u5408\u8A08\uFF1A
IngestMessagePanel.sortByComboBox.toolTipText=\u6642\u9593\u9806\uff08\u6642\u7cfb\u5217\uff09\u307e\u305f\u306f\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u512a\u5148\u5ea6\u3067\u30bd\u30fc\u30c8
IngestMessagePanel.sortByLabel.text=\u6b21\u3067\u30bd\u30fc\u30c8\uff1a
IngestMessagePanel.totalMessagesNameLabel.text=\u5408\u8a08\uff1a
IngestMessagePanel.totalMessagesNameVal.text=-
IngestMessagePanel.totalUniqueMessagesNameLabel.text=\u30E6\u30CB\u30FC\u30AF\uFF1A
IngestMessagePanel.totalUniqueMessagesNameLabel.text=\u30e6\u30cb\u30fc\u30af\uff1a
IngestMessagePanel.totalUniqueMessagesNameVal.text=-
IngestMessagesToolbar.customizeButton.toolTipText=\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
IngestMessageTopComponent.displayName=\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
IngestMessageTopComponent.displayReport.option.GenRpt=\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210
IngestMessagesToolbar.customizeButton.toolTipText=\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8
IngestMessageTopComponent.displayName=\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8
IngestMessageTopComponent.displayReport.option.GenRpt=\u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210
IngestMessageTopComponent.displayReport.option.OK=OK
IngestMessageTopComponent.initComponents.name=\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
IngestMessageTopComponent.msgDlg.ingestRpt.text=\u30EC\u30DD\u30FC\u30C8\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
IngestMonitor.mgrErrMsg.lowDiskSpace.msg=\u30C7\u30A3\u30B9\u30AF{0}\u306E\u30C7\u30A3\u30B9\u30AF\u9818\u57DF\u4E0D\u8DB3\u306E\u305F\u3081\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u4E2D\u6B62\u3057\u307E\u3059\u3002\n\u30B1\u30FC\u30B9\u30C9\u30E9\u30A4\u30D6\u306B\u6700\u4F4E1GB\u306E\u7A7A\u304D\u9818\u57DF\u304C\u3042\u308B\u306E\u3092\u78BA\u8A8D\u3057\u3001\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u518D\u5B9F\u884C\u3057\u3066\u4E0B\u3055\u3044\u3002
IngestMonitor.mgrErrMsg.lowDiskSpace.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u304C\u4E2D\u6B62\u3055\u308C\u307E\u3057\u305F\u30FC{0}\u306E\u30C7\u30A3\u30B9\u30AF\u9818\u57DF\u4E0D\u8DB3
OpenIDE-Module-Name=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList=\n\u30A8\u30E9\u30FC\uFF1A\n{0}
IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg=\u5358\u6570\u307E\u305F\u306F\u8907\u6570\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30B9\u30BF\u30FC\u30C8\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u306F\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F\u3002
IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution=\u5931\u6557\u3057\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u7121\u52B9\u5316\u3059\u308B\u304B\u30A8\u30E9\u30FC\u3092\u89E3\u6C7A\u3057\u3001\u305D\u306E\u5F8C\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u3092\u53F3\u30AF\u30EA\u30C3\u30AF\u3057\u3001\n\u300C\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u5B9F\u884C\u300D\u3092\u9078\u629E\u3057\u3066\u3001\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u518D\u5B9F\u884C\u3057\u3066\u4E0B\u3055\u3044\u3002
IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u5931\u6557
IngestJobSettings.createModuleSettingsFolder.warning=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u8A2D\u5B9A\u30D5\u30A9\u30EB\u30C0\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u8A2D\u5B9A\u3092\u4FDD\u5B58\u3067\u304D\u307E\u305B\u3093\u3002
IngestJob.progress.dataSourceIngest.initialDisplayName={0}\u3092\u89E3\u6790\u4E2D
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.elapsedTime=\u7D4C\u904E\u6642\u9593\uFF08\u6642\uFF1A\u5206\uFF1A\u79D2\uFF09
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file=\u30D5\u30A1\u30A4\u30EB
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime=\u958B\u59CB\u6642\u9593
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.threadID=\u30B9\u30EC\u30C3\u30C9ID
IngestManager.IngestMessage.ErrorMessageLimitReached.msg=\u6700\u5927\u6570({0})\u306E\u30A8\u30E9\u30FC\u304A\u3088\u3073\u307E\u305F\u306F\u8B66\u544A\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u63B2\u8F09\u3055\u308C\u307E\u3057\u305F\u3002\u3055\u3089\u306A\u308B\u30A8\u30E9\u30FC\uFF0F\u8B66\u544A\u306F\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\uFF08\u30D8\u30EB\u30D7->\u30ED\u30B0\u30D5\u30A9\u30EB\u30C0\u30FC\u3092\u958B\u304F\uFF09
IngestManager.IngestMessage.ErrorMessageLimitReached.subject=\u6700\u5927\u6570\u306E\u30A8\u30E9\u30FC\u304C\u63B2\u8F09\u3055\u308C\u307E\u3057\u305F
IngestManager.IngestMessage.ErrorMessageLimitReached.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30DE\u30CD\u30B8\u30E3\u30FC
IngestManager.IngestThreadActivitySnapshot.idleThread=\u30A2\u30A4\u30C9\u30EB
IngestProgressSnapshotDialog.title.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30D7\u30ED\u30B0\u30EC\u30B9\u30FB\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8
IngestProgressSnapshotPanel.closeButton.text=\u9589\u3058\u308B
IngestProgressSnapshotPanel.refreshButton.text=\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3
IngestJobSettingsPanel.advancedButton.actionCommand=\u30A2\u30C9\u30D0\u30F3\u30B9
IngestJobSettingsPanel.advancedButton.text=\u30A2\u30C9\u30D0\u30F3\u30B9
IngestMessageTopComponent.initComponents.name=\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8
IngestMessageTopComponent.msgDlg.ingestRpt.text=\u30ec\u30dd\u30fc\u30c8\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8
IngestMonitor.mgrErrMsg.lowDiskSpace.msg=\u30c7\u30a3\u30b9\u30af{0}\u306e\u30c7\u30a3\u30b9\u30af\u9818\u57df\u4e0d\u8db3\u306e\u305f\u3081\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u4e2d\u6b62\u3057\u307e\u3059\u3002\n\u30b1\u30fc\u30b9\u30c9\u30e9\u30a4\u30d6\u306b\u6700\u4f4e1GB\u306e\u7a7a\u304d\u9818\u57df\u304c\u3042\u308b\u306e\u3092\u78ba\u8a8d\u3057\u3001\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u518d\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002
IngestMonitor.mgrErrMsg.lowDiskSpace.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u4e2d\u6b62\u3055\u308c\u307e\u3057\u305f\u30fc{0}\u306e\u30c7\u30a3\u30b9\u30af\u9818\u57df\u4e0d\u8db3
OpenIDE-Module-Name=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8
IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList=\n\u30a8\u30e9\u30fc\uff1a\n{0}
IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg=\u5358\u6570\u307e\u305f\u306f\u8907\u6570\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u30b9\u30bf\u30fc\u30c8\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u306f\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f\u3002
IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution=\u5931\u6557\u3057\u305f\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u7121\u52b9\u5316\u3059\u308b\u304b\u30a8\u30e9\u30fc\u3092\u89e3\u6c7a\u3057\u3001\u305d\u306e\u5f8c\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3001\n\u300c\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u5b9f\u884c\u300d\u3092\u9078\u629e\u3057\u3066\u3001\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u518d\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002
IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u5931\u6557
IngestJobSettings.createModuleSettingsFolder.warning=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u8a2d\u5b9a\u30d5\u30a9\u30eb\u30c0\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3002
IngestJob.progress.dataSourceIngest.initialDisplayName={0}\u3092\u89e3\u6790\u4e2d
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.elapsedTime=\u7d4c\u904e\u6642\u9593\uff08\u6642\uff1a\u5206\uff1a\u79d2\uff09
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file=\u30d5\u30a1\u30a4\u30eb
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime=\u958b\u59cb\u6642\u9593
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.threadID=\u30b9\u30ec\u30c3\u30c9ID
IngestManager.IngestMessage.ErrorMessageLimitReached.msg=\u6700\u5927\u6570({0})\u306e\u30a8\u30e9\u30fc\u304a\u3088\u3073\u307e\u305f\u306f\u8b66\u544a\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u63b2\u8f09\u3055\u308c\u307e\u3057\u305f\u3002\u3055\u3089\u306a\u308b\u30a8\u30e9\u30fc\uff0f\u8b66\u544a\u306f\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\uff08\u30d8\u30eb\u30d7->\u30ed\u30b0\u30d5\u30a9\u30eb\u30c0\u30fc\u3092\u958b\u304f\uff09
IngestManager.IngestMessage.ErrorMessageLimitReached.subject=\u6700\u5927\u6570\u306e\u30a8\u30e9\u30fc\u304c\u63b2\u8f09\u3055\u308c\u307e\u3057\u305f
IngestManager.IngestMessage.ErrorMessageLimitReached.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30de\u30cd\u30b8\u30e3\u30fc
IngestManager.IngestThreadActivitySnapshot.idleThread=\u30a2\u30a4\u30c9\u30eb
IngestProgressSnapshotDialog.title.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30d7\u30ed\u30b0\u30ec\u30b9\u30fb\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8
IngestProgressSnapshotPanel.closeButton.text=\u9589\u3058\u308b
IngestProgressSnapshotPanel.refreshButton.text=\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
IngestJobSettingsPanel.advancedButton.actionCommand=\u30a2\u30c9\u30d0\u30f3\u30b9
IngestJobSettingsPanel.advancedButton.text=\u30a2\u30c9\u30d0\u30f3\u30b9
ModuleTableModel.colName.duration=\u6240\u8981\u6642\u9593
IngestJob.cancellationDialog.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u30AD\u30E3\u30F3\u30BB\u30EB
IngestJobSettings.missingModule.warning=\u4EE5\u524D\u306B\u8AAD\u307F\u8FBC\u3093\u3060{0}\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=\u5168\u3066\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30AD\u30E3\u30F3\u30BB\u30EB
DataSourceIngestCancellationPanel.cancelCurrentModuleRadioButton.text=\u73FE\u5728\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u307F\u30AD\u30E3\u30F3\u30BB\u30EB
FileIngestCancellationPanel.cancelFileIngestRadioButton.text=\u30D5\u30A1\u30A4\u30EB\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u306E\u307F\u30AD\u30E3\u30F3\u30BB\u30EB
FileIngestCancellationPanel.cancelIngestJobRadioButton.text=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u304A\u3088\u3073\u30D5\u30A1\u30A4\u30EB\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u30AD\u30E3\u30F3\u30BB\u30EB
IngestJobSettings.moduleSettingsLoad.warning={1}\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306E{0}\u30E2\u30B8\u30E5\u30FC\u30EB\u7528\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u3066\u3044\u307E\u3059\u3002
IngestJobSettings.save.warning={0}\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A\u3092\u4FDD\u5B58\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
IngestJobTableModel.colName.dataSource=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9
IngestJobTableModel.colName.dirQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
IngestJobTableModel.colName.filesPerSec=\u30D5\u30A1\u30A4\u30EB\uFF0F\u79D2
IngestJobTableModel.colName.filesQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
IngestJobTableModel.colName.inProgress=\u51E6\u7406\u4E2D
IngestJobTableModel.colName.jobID=\u30B8\u30E7\u30D6ID
IngestJobTableModel.colName.numProcessed=\u51E6\u7406\u3055\u308C\u305F\u6570
IngestJobTableModel.colName.rootQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305F\u30EB\u30FC\u30C8
IngestJobTableModel.colName.start=\u30B9\u30BF\u30FC\u30C8
IngestModuleFactoryLoader.errorMessages.duplicateDisplayName=\u5225\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u540D\u524D\u3092\u91CD\u8907\u3059\u308B\u3001{0}\u306E\u540D\u524D\u3092\u6301\u3064\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002\u30E2\u30B8\u30E5\u30FC\u30EB\u306F\u4F7F\u7528\u3057\u307E\u305B\u3093\u3002
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.jobID=\u30B8\u30E7\u30D6ID
ModuleTableModel.colName.module=\u30E2\u30B8\u30E5\u30FC\u30EB
IngestJobSettingsPanel.processUnallocCheckbox.toolTipText=\u524A\u9664\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u7B49\u306E\u672A\u5272\u308A\u5F53\u3066\u9818\u57DF\u3092\u51E6\u7406\u3002\u3088\u308A\u5B8C\u5168\u306A\u7D50\u679C\u304C\u51FA\u307E\u3059\u304C\u3001\u5927\u304D\u3044\u30A4\u30E1\u30FC\u30B8\u3067\u306F\u51E6\u7406\u6642\u9593\u304C\u9577\u304F\u306A\u308B\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
IngestJob.cancellationDialog.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u30ad\u30e3\u30f3\u30bb\u30eb
IngestJobSettings.missingModule.warning=\u4ee5\u524d\u306b\u8aad\u307f\u8fbc\u3093\u3060{0}\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=\u5168\u3066\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u30ad\u30e3\u30f3\u30bb\u30eb
DataSourceIngestCancellationPanel.cancelCurrentModuleRadioButton.text=\u73fe\u5728\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u307f\u30ad\u30e3\u30f3\u30bb\u30eb
FileIngestCancellationPanel.cancelFileIngestRadioButton.text=\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306e\u307f\u30ad\u30e3\u30f3\u30bb\u30eb
FileIngestCancellationPanel.cancelIngestJobRadioButton.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304a\u3088\u3073\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u30ad\u30e3\u30f3\u30bb\u30eb
IngestJobSettings.moduleSettingsLoad.warning={1}\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e{0}\u30e2\u30b8\u30e5\u30fc\u30eb\u7528\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30c7\u30d5\u30a9\u30eb\u30c8\u8a2d\u5b9a\u3092\u4f7f\u7528\u3057\u3066\u3044\u307e\u3059\u3002
IngestJobSettings.save.warning={0}\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
IngestJobTableModel.colName.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
IngestJobTableModel.colName.dirQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea
IngestJobTableModel.colName.filesPerSec=\u30d5\u30a1\u30a4\u30eb\uff0f\u79d2
IngestJobTableModel.colName.filesQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb
IngestJobTableModel.colName.inProgress=\u51e6\u7406\u4e2d
IngestJobTableModel.colName.jobID=\u30b8\u30e7\u30d6ID
IngestJobTableModel.colName.numProcessed=\u51e6\u7406\u3055\u308c\u305f\u6570
IngestJobTableModel.colName.rootQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305f\u30eb\u30fc\u30c8
IngestJobTableModel.colName.start=\u30b9\u30bf\u30fc\u30c8
IngestModuleFactoryLoader.errorMessages.duplicateDisplayName=\u5225\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u540d\u524d\u3092\u91cd\u8907\u3059\u308b\u3001{0}\u306e\u540d\u524d\u3092\u6301\u3064\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u4f7f\u7528\u3057\u307e\u305b\u3093\u3002
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.jobID=\u30b8\u30e7\u30d6ID
ModuleTableModel.colName.module=\u30e2\u30b8\u30e5\u30fc\u30eb
IngestJobSettingsPanel.processUnallocCheckbox.toolTipText=\u524a\u9664\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u7b49\u306e\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\u3092\u51e6\u7406\u3002\u3088\u308a\u5b8c\u5168\u306a\u7d50\u679c\u304c\u51fa\u307e\u3059\u304c\u3001\u5927\u304d\u3044\u30a4\u30e1\u30fc\u30b8\u3067\u306f\u51e6\u7406\u6642\u9593\u304c\u9577\u304f\u306a\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
IngestJobSettingsPanel.processUnallocCheckbox.text=\u672A\u5272\u308A\u5F53\u3066\u9818\u57DF\u306E\u51E6\u7406
Menu/Tools/RunIngestModules=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5B9F\u884C
IngestJob.progress.fileIngest.cancelMessage={1}\u306E{0}\u3092\u5F85\u3063\u3066\u3044\u307E\u3059
IngestManager.OpenEventChannel.Fail.ErrMsg=\u3053\u306E\u30B1\u30FC\u30B9\u3067\u4F7F\u308F\u308C\u3066\u3044\u308B\u304B\u3082\u3057\u308C\u306A\u3044\u4ED6\u306E\u30CE\u30FC\u30C9\u306B\u89E3\u6790\u30D7\u30ED\u30BB\u30B9\u304C\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
IngestManager.OpenEventChannel.Fail.Title=\u63A5\u7D9A\u5931\u6557
IngestJobSettings.moduleSettingsSave.warning={1}\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306E{0}\u30E2\u30B8\u30E5\u30FC\u30EB\u7528\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
IngestJobTableModel.colName.dsQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305FDS
IngestJobSettingsPanel.jButtonSelectAll.text=\u5168\u3066\u9078\u629E
IngestJobSettingsPanel.jButtonDeselectAll.text=\u5168\u3066\u9078\u629E\u89E3\u9664
IngestManager.cancellingIngest.msgDlg.text=\u73FE\u5728\u5B9F\u884C\u4E2D\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u4E2D
IngestManager.serviceIsDown.msgDlg.text={0}\u304C\u30C0\u30A6\u30F3\u3057\u3066\u3044\u307E\u3059
RunIngestSubMenu.menuItem.empty=\u30FC\u7A7A\u767D\u30FC
RunIngestModulesMenu.getName.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5B9F\u884C
DataSourceIngestPipeline.moduleError.title.text={0}\u30A8\u30E9\u30FC
FileIngestPipeline.moduleError.title.text={0}\u30A8\u30E9\u30FC
IngestJob.cancelReason.notCancelled.text=\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u3066\u3044\u307E\u305B\u3093
IngestJob.cancelReason.cancelledByUser.text=\u30E6\u30FC\u30B6\u30FC\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3057\u305F
IngestJob.cancelReason.ingestModStartFail.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u8D77\u52D5\u306B\u5931\u6557
IngestJob.cancelReason.outOfDiskSpace.text=\u30C7\u30A3\u30B9\u30AF\u30B9\u30DA\u30FC\u30B9\u304C\u8DB3\u308A\u307E\u305B\u3093
IngestJob.cancelReason.servicesDown.text=\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F
IngestJob.cancelReason.caseClosed.text=\u30B1\u30FC\u30B9\u3092\u9589\u3058\u307E\u3057\u305F
IngestJobSettingsPanel.processUnallocCheckbox.text=\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\u306e\u51e6\u7406
Menu/Tools/RunIngestModules=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c
IngestJob.progress.fileIngest.cancelMessage={1}\u306e{0}\u3092\u5f85\u3063\u3066\u3044\u307e\u3059
IngestManager.OpenEventChannel.Fail.ErrMsg=\u3053\u306e\u30b1\u30fc\u30b9\u3067\u4f7f\u308f\u308c\u3066\u3044\u308b\u304b\u3082\u3057\u308c\u306a\u3044\u4ed6\u306e\u30ce\u30fc\u30c9\u306b\u89e3\u6790\u30d7\u30ed\u30bb\u30b9\u304c\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
IngestManager.OpenEventChannel.Fail.Title=\u63a5\u7d9a\u5931\u6557
IngestJobSettings.moduleSettingsSave.warning={1}\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e{0}\u30e2\u30b8\u30e5\u30fc\u30eb\u7528\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
IngestJobTableModel.colName.dsQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305fDS
IngestJobSettingsPanel.jButtonSelectAll.text=\u5168\u3066\u9078\u629e
IngestJobSettingsPanel.jButtonDeselectAll.text=\u5168\u3066\u9078\u629e\u89e3\u9664
IngestManager.cancellingIngest.msgDlg.text=\u73fe\u5728\u5b9f\u884c\u4e2d\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d
IngestManager.serviceIsDown.msgDlg.text={0}\u304c\u30c0\u30a6\u30f3\u3057\u3066\u3044\u307e\u3059
RunIngestSubMenu.menuItem.empty=\u30fc\u7a7a\u767d\u30fc
RunIngestModulesMenu.getName.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u5b9f\u884c
DataSourceIngestPipeline.moduleError.title.text={0}\u30a8\u30e9\u30fc
FileIngestPipeline.moduleError.title.text={0}\u30a8\u30e9\u30fc
IngestJob.cancelReason.notCancelled.text=\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u3066\u3044\u307e\u305b\u3093
IngestJob.cancelReason.cancelledByUser.text=\u30e6\u30fc\u30b6\u30fc\u304c\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3057\u305f
IngestJob.cancelReason.ingestModStartFail.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u8d77\u52d5\u306b\u5931\u6557
IngestJob.cancelReason.outOfDiskSpace.text=\u30c7\u30a3\u30b9\u30af\u30b9\u30da\u30fc\u30b9\u304c\u8db3\u308a\u307e\u305b\u3093
IngestJob.cancelReason.caseClosed.text=\u30b1\u30fc\u30b9\u3092\u9589\u3058\u307e\u3057\u305f
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,8 +39,10 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.python.util.PythonObjectInputStream;
/**
* Encapsulates the ingest job settings for a particular context such as the Add
* Data Source wizard or the Run Ingest Modules dialog.
* Encapsulates the ingest job settings for a particular execution context.
* Examples of execution contexts include the add data source wizard and the run
* ingest modules dialog. Different execution conterxts may have different
* ingest job settings.
*/
public class IngestJobSettings {
@@ -60,19 +62,30 @@ public class IngestJobSettings {
private boolean processUnallocatedSpace;
private final List<String> warnings;
// Determines which modeules to run
/**
* The type of ingest modules to run.
*/
public enum IngestType {
// Run all modules
/**
* Run both data source level and file-level ingest modules.
*/
ALL_MODULES,
// Run only data source modules
/**
* Run only data source level ingest modules.
*/
DATA_SOURCE_ONLY,
// Run only files modules
/**
* Run only file level ingest modules.
*/
FILES_ONLY
}
/**
* Constructs an ingest job settings object for a given context.
* Constructs an ingest job settings object for a given execution context.
* Examples of execution contexts include the add data source wizard and the
* run ingest modules dialog. Different execution conterxts may have
* different ingest job settings.
*
* @param executionContext The ingest execution context identifier.
*/
@@ -87,7 +100,10 @@ public class IngestJobSettings {
}
/**
* Constructs an ingest job settings object for a given context.
* Constructs an ingest job settings object for a given context. Examples of
* execution contexts include the add data source wizard and the run ingest
* modules dialog. Different execution conterxts may have different ingest
* job settings.
*
* @param context The context identifier string.
* @param ingestType The type of modules ingest is running.
@@ -116,9 +132,12 @@ public class IngestJobSettings {
}
/**
* Get the ingest execution context identifier.
* Gets the ingest execution context identifier. Examples of execution
* contexts include the add data source wizard and the run ingest modules
* dialog. Different execution conterxts may have different ingest job
* settings.
*
* @return The context string.
* @return The execution context identifier.
*/
String getExecutionContext() {
return this.executionContext;
@@ -71,28 +71,27 @@ public class IngestManager {
private static IngestManager instance;
private final Object ingestMessageBoxLock = new Object();
/**
* The ingest manager maintains a mapping of ingest job IDs to running
/*
* The ingest manager maintains a mapping of ingest job ids to running
* ingest jobs.
*/
private final ConcurrentHashMap<Long, IngestJob> jobsById;
private final Map<Long, IngestJob> jobsById;
/**
/*
* Each runnable/callable task the ingest manager submits to its thread
* pools is given a unique thread/task ID.
*/
private final AtomicLong nextThreadId;
/**
* Ingest jobs may be queued to be started on a pool thread by ingest job
* starters. A mapping of thread/task IDs to the result objects associated
* with each ingest job starter is maintained to provide handles that can be
* used to cancel the ingest job starter.
/*
* Ingest jobs may be queued to be started on a pool thread by start ingest
* job tasks. A mapping of task ids to the Future objects for each task is
* maintained to allow for task cancellation.
*/
private final ConcurrentHashMap<Long, Future<Void>> ingestJobStarters;
private final Map<Long, Future<Void>> startIngestJobTasks;
private final ExecutorService startIngestJobsThreadPool;
/**
/*
* Ingest jobs use an ingest task scheduler to break themselves down into
* data source level and file level tasks. The ingest scheduler puts these
* ingest tasks into queues for execution on ingest manager pool threads by
@@ -118,14 +117,14 @@ public class IngestManager {
private AutopsyEventPublisher moduleEventPublisher;
private final ExecutorService eventPublishingExecutor;
/**
/*
* The ingest manager uses an ingest monitor to determine when system
* resources are under pressure. If the monitor detects such a situation, it
* calls back to the ingest manager to cancel all ingest jobs in progress.
*/
private final IngestMonitor ingestMonitor;
/**
/*
* The ingest manager provides access to a top component that is used by
* ingest module to post messages for the user. A count of the posts is used
* as a cap to avoid bogging down the application.
@@ -134,7 +133,7 @@ public class IngestManager {
private volatile IngestMessageTopComponent ingestMessageBox;
private final AtomicLong ingestErrorMessagePosts;
/**
/*
* The ingest manager supports reporting of ingest processing progress by
* collecting snapshots of the activities of the ingest threads, ingest job
* progress, and ingest module run times.
@@ -142,13 +141,13 @@ public class IngestManager {
private final ConcurrentHashMap<Long, IngestThreadActivitySnapshot> ingestThreadActivitySnapshots;
private final ConcurrentHashMap<String, Long> ingestModuleRunTimes;
/**
/*
* The ingest job creation capability of the ingest manager can be turned on
* and off to support an orderly shut down of the application.
*/
private volatile boolean jobCreationIsEnabled;
/**
/*
* Ingest manager subscribes to service outage notifications. If key
* services are down, ingest manager cancels all ingest jobs in progress.
*/
@@ -264,8 +263,8 @@ public class IngestManager {
this.dataSourceIngestThreadPool = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("IM-data-source-ingest-%d").build()); //NON-NLS
this.startIngestJobsThreadPool = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("IM-start-ingest-jobs-%d").build()); //NON-NLS
this.nextThreadId = new AtomicLong(0L);
this.jobsById = new ConcurrentHashMap<>();
this.ingestJobStarters = new ConcurrentHashMap<>();
this.jobsById = new HashMap<>();
this.startIngestJobTasks = new ConcurrentHashMap<>();
this.servicesMonitor = ServicesMonitor.getInstance();
subscribeToServiceMonitorEvents();
@@ -329,7 +328,7 @@ public class IngestManager {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue().equals(ServicesMonitor.ServiceStatus.DOWN.toString())) {
// check whether a milti-user case is currently being processed
// check whether a multi-user case is currently being processed
try {
if (!Case.isCaseOpen() || Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
return;
@@ -474,13 +473,13 @@ public class IngestManager {
* @param dataSources The data sources to process.
* @param settings The settings for the ingest job.
*/
public synchronized void queueIngestJob(Collection<Content> dataSources, IngestJobSettings settings) {
if (this.jobCreationIsEnabled) {
public void queueIngestJob(Collection<Content> dataSources, IngestJobSettings settings) {
if (jobCreationIsEnabled) {
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.coreComponentsAreActive());
if (job.hasIngestPipeline()) {
long taskId = nextThreadId.incrementAndGet();
Future<Void> task = startIngestJobsThreadPool.submit(new StartIngestJobTask(taskId, job));
ingestJobStarters.put(taskId, task);
startIngestJobTasks.put(taskId, task);
}
}
}
@@ -544,20 +543,18 @@ public class IngestManager {
ingestMonitor.start();
}
/**
* Add the job to the jobs map now so that isIngestRunning() will
* return true while the modules read global settings during start
* up. This works because the core global settings panels restrict
* changes while analysis is in progress.
*/
this.jobsById.put(job.getId(), job);
synchronized (jobsById) {
jobsById.put(job.getId(), job);
}
List<IngestModuleError> errors = job.start();
if (errors.isEmpty()) {
this.fireIngestJobStarted(job.getId());
IngestManager.logger.log(Level.INFO, "Ingest job {0} started", job.getId()); //NON-NLS
success = true;
} else {
this.jobsById.remove(job.getId());
synchronized (jobsById) {
this.jobsById.remove(job.getId());
}
for (IngestModuleError error : errors) {
logger.log(Level.SEVERE, String.format("Error starting %s ingest module", error.getModuleDisplayName()), error.getModuleError()); //NON-NLS
}
@@ -599,13 +596,15 @@ public class IngestManager {
synchronized void finishIngestJob(IngestJob job) {
long jobId = job.getId();
this.jobsById.remove(jobId);
synchronized (jobsById) {
jobsById.remove(jobId);
}
if (!job.isCancelled()) {
IngestManager.logger.log(Level.INFO, "Ingest job {0} completed", jobId); //NON-NLS
this.fireIngestJobCompleted(jobId);
fireIngestJobCompleted(jobId);
} else {
IngestManager.logger.log(Level.INFO, "Ingest job {0} cancelled", jobId); //NON-NLS
this.fireIngestJobCancelled(jobId);
fireIngestJobCancelled(jobId);
}
}
@@ -615,7 +614,9 @@ public class IngestManager {
* @return True or false.
*/
public boolean isIngestRunning() {
return !this.jobsById.isEmpty();
synchronized (jobsById) {
return !jobsById.isEmpty();
}
}
/**
@@ -625,7 +626,7 @@ public class IngestManager {
* instead.
*/
@Deprecated
public synchronized void cancelAllIngestJobs() {
public void cancelAllIngestJobs() {
cancelAllIngestJobs(IngestJob.CancellationReason.USER_CANCELLED);
}
@@ -634,15 +635,21 @@ public class IngestManager {
*
* @param reason The cancellation reason.
*/
public synchronized void cancelAllIngestJobs(IngestJob.CancellationReason reason) {
// Stop creating new ingest jobs.
for (Future<Void> handle : ingestJobStarters.values()) {
public void cancelAllIngestJobs(IngestJob.CancellationReason reason) {
/*
* Cancel the start job tasks.
*/
for (Future<Void> handle : startIngestJobTasks.values()) {
handle.cancel(true);
}
// Cancel all the jobs already created.
for (IngestJob job : this.jobsById.values()) {
job.cancel(reason);
/*
* Cancel the jobs in progress.
*/
synchronized (jobsById) {
for (IngestJob job : this.jobsById.values()) {
job.cancel(reason);
}
}
}
@@ -903,8 +910,10 @@ public class IngestManager {
*/
List<DataSourceIngestJob.Snapshot> getIngestJobSnapshots() {
List<DataSourceIngestJob.Snapshot> snapShots = new ArrayList<>();
for (IngestJob job : this.jobsById.values()) {
snapShots.addAll(job.getDataSourceIngestJobSnapshots());
synchronized (jobsById) {
for (IngestJob job : jobsById.values()) {
snapShots.addAll(job.getDataSourceIngestJobSnapshots());
}
}
return snapShots;
}
@@ -941,7 +950,9 @@ public class IngestManager {
public Void call() {
try {
if (Thread.currentThread().isInterrupted()) {
jobsById.remove(job.getId());
synchronized (jobsById) {
jobsById.remove(job.getId());
}
return null;
}
@@ -953,7 +964,7 @@ public class IngestManager {
if (progress != null) {
progress.setDisplayName(NbBundle.getMessage(this.getClass(), "IngestManager.StartIngestJobsTask.run.cancelling", displayName));
}
Future<?> handle = ingestJobStarters.remove(threadId);
Future<?> handle = startIngestJobTasks.remove(threadId);
handle.cancel(true);
return true;
}
@@ -968,7 +979,7 @@ public class IngestManager {
if (null != progress) {
progress.finish();
}
ingestJobStarters.remove(threadId);
startIngestJobTasks.remove(threadId);
}
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2015 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,11 +39,14 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.Directory;
/**
* Dialog box that allows a user to configure and run an ingest job on one or
* more data sources.
*
* A dialog box that allows a user to configure and execute analysis of one or
* more data sources with ingest modules or analysis of the contents of a
* directory with file-level ingest modules.
*/
public final class RunIngestModulesDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text");
private final IngestType ingestType;
private static Dimension DIMENSIONS = new Dimension(500, 300);
@@ -51,13 +54,13 @@ public final class RunIngestModulesDialog extends JDialog {
private IngestJobSettingsPanel ingestJobSettingsPanel;
/**
* Construct a dialog box that allows a user to configure and run an ingest
* job on one or more data sources.
* Constructs a dialog box that allows a user to configure and execute
* analysis of one or more data sources with ingest modules.
*
* @param frame The dialog parent window.
* @param title The title for the dialog.
* @param modal True if the dialog should be modal, false otherwise.
* @param dataSources The data sources to be processed.
* @param dataSources The data sources to be analyzed.
*/
public RunIngestModulesDialog(JFrame frame, String title, boolean modal, List<Content> dataSources) {
super(frame, title, modal);
@@ -66,60 +69,26 @@ public final class RunIngestModulesDialog extends JDialog {
}
/**
* Construct a dialog box that allows a user to configure and run an ingest
* job on one or more data sources.
* Constructs a dialog box that allows a user to configure and execute
* analysis of one or more data sources with ingest modules.
*
* @param dataSources The data sources to be processed.
*/
public RunIngestModulesDialog(List<Content> dataSources) {
this(new JFrame(TITLE), TITLE, true, dataSources);
}
/**
* Constructs a dialog box that allows a user to configure and execute
* analysis of the contents of a directory with file-level ingest modules.
*
* @param dir
*/
public RunIngestModulesDialog(Directory dir) {
this.dataSources.add(dir);
this.ingestType = IngestType.FILES_ONLY;
}
/**
* Construct a dialog box that allows a user to configure and run an ingest
* job on one or more data sources.
*
* @param frame The dialog parent window.
* @param title The title for the dialog.
* @param modal True if the dialog should be modal, false otherwise.
*
* @deprecated
*/
@Deprecated
public RunIngestModulesDialog(JFrame frame, String title, boolean modal) {
super(frame, title, modal);
this.ingestType = IngestType.ALL_MODULES;
}
/**
* Construct a dialog box that allows a user to configure and run an ingest
* job on one or more data sources.
*
* @deprecated
*/
@Deprecated
public RunIngestModulesDialog() {
this(new JFrame(TITLE), TITLE, true);
}
/**
* Set the data sources to be processed.
*
* @param dataSources The data sources.
*
* @deprecated
*/
@Deprecated
public void setDataSources(List<Content> dataSources) {
this.dataSources.clear();
this.dataSources.addAll(dataSources);
}
/**
* Displays this dialog.
*/
@@ -139,7 +108,7 @@ public final class RunIngestModulesDialog extends JDialog {
* Get the default or saved ingest job settings for this context and use
* them to create and add an ingest job settings panel.
*/
IngestJobSettings ingestJobSettings = new IngestJobSettings(RunIngestModulesDialog.class.getCanonicalName(), this.ingestType);
IngestJobSettings ingestJobSettings = new IngestJobSettings(RunIngestModulesDialog.class.getCanonicalName(), this.ingestType);
RunIngestModulesDialog.showWarnings(ingestJobSettings);
this.ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
add(this.ingestJobSettingsPanel, BorderLayout.PAGE_START);
@@ -227,4 +196,45 @@ public final class RunIngestModulesDialog extends JDialog {
JOptionPane.showMessageDialog(null, warningMessage.toString());
}
}
/**
* Constructs a dialog box that allows a user to configure and execute
* analysis of one or more data sources with ingest modules.
*
* @param frame The dialog parent window.
* @param title The title for the dialog.
* @param modal True if the dialog should be modal, false otherwise.
*
* @deprecated
*/
@Deprecated
public RunIngestModulesDialog(JFrame frame, String title, boolean modal) {
super(frame, title, modal);
this.ingestType = IngestType.ALL_MODULES;
}
/**
* Constructs a dialog box that allows a user to configure and run an ingest
* job on one or more data sources.
*
* @deprecated
*/
@Deprecated
public RunIngestModulesDialog() {
this(new JFrame(TITLE), TITLE, true);
}
/**
* Sets the data sources to be processed.
*
* @param dataSources The data sources.
*
* @deprecated
*/
@Deprecated
public void setDataSources(List<Content> dataSources) {
this.dataSources.clear();
this.dataSources.addAll(dataSources);
}
}
@@ -1,2 +0,0 @@
UserArtifactIngestModuleFactory.moduleName=Custom Artifact Adder
UserArtifactIngestModuleFactory.moduleDescription=Adds custom artifact types
@@ -1,2 +0,0 @@
UserArtifactIngestModuleFactory.moduleName=\u30AB\u30B9\u30BF\u30E0\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u8FFD\u52A0\u30C4\u30FC\u30EB
UserArtifactIngestModuleFactory.moduleDescription=\u30AB\u30B9\u30BF\u30E0\u306E\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u30BF\u30A4\u30D7\u3092\u8FFD\u52A0
@@ -1,93 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.UserArtifacts;
import com.sun.media.jfxmedia.logging.Logger;
import java.util.List;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard.BlackboardException;
import org.sleuthkit.autopsy.casemodule.services.FileManager;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Test module that creates new artifact and attribute types.
*/
public class UserArtifactIngestModule implements DataSourceIngestModule {
private BlackboardArtifact.Type type1, type2;
@Override
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
progressBar.switchToDeterminate(2);
try {
FileManager manager = Case.getCurrentCase().getServices().getFileManager();
List<AbstractFile> file1 = manager.findFiles("Sunset.jpg"); //NON-NLS
List<AbstractFile> file2 = manager.findFiles("Winter.jpg"); //NON-NLS
BlackboardArtifact art1;
BlackboardArtifact art2;
if (!file1.isEmpty()) {
art1 = file1.get(0).newArtifact(type1.getTypeID());
} else {
art1 = dataSource.newArtifact(type1.getTypeID());
}
if (!file2.isEmpty()) {
art2 = file2.get(0).newArtifact(type2.getTypeID());
} else {
art2 = dataSource.newArtifact(type2.getTypeID());
}
BlackboardAttribute.Type attributeType = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("Test", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG, "2"); //NON-NLS
BlackboardAttribute.Type attributeType2 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("Test2", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE, "3"); //NON-NLS
art1.addAttribute(new BlackboardAttribute(attributeType,
UserArtifactIngestModuleFactory.getModuleName(), -1L));
progressBar.progress(1);
art2.addAttribute(new BlackboardAttribute(attributeType2,
UserArtifactIngestModuleFactory.getModuleName(), new byte[7]));
progressBar.progress(1);
IngestServices.getInstance().postMessage(IngestMessage.createDataMessage(
"name", // NON-NLS
UserArtifactIngestModuleFactory.getModuleName(),
"Test Results", //NON-NLS
"Test", //NON-NLS
art1));
return ProcessResult.OK;
} catch (TskCoreException | BlackboardException ex) {
return ProcessResult.ERROR;
}
}
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
try {
type1 = Case.getCurrentCase().getServices().getBlackboard().addArtifactType("This is", "a test"); //NON-NLS
type2 = Case.getCurrentCase().getServices().getBlackboard().addArtifactType("Another", "kinda test"); //NON-NLS
} catch (BlackboardException ex) {
Logger.logMsg(Logger.ERROR, "Startup failed"); //NON-NLS
}
}
}
@@ -1,61 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.UserArtifacts;
import org.openide.util.NbBundle;
import org.python.apache.xmlcommons.Version;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
/**
* Factory for test module that creates new artifact and attribute types.
*/
//@ServiceProvider(service = IngestModuleFactory.class)
public class UserArtifactIngestModuleFactory extends IngestModuleFactoryAdapter {
static String getModuleName() {
return NbBundle.getMessage(UserArtifactIngestModuleFactory.class, "UserArtifactIngestModuleFactory.moduleName");
}
@Override
public String getModuleDisplayName() {
return getModuleName();
}
@Override
public String getModuleDescription() {
return NbBundle.getMessage(UserArtifactIngestModuleFactory.class, "UserArtifactIngestModuleFactory.moduleDescription");
}
@Override
public String getModuleVersionNumber() {
return Version.getVersion();
}
@Override
public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings ingestOptions) {
return new UserArtifactIngestModule();
}
@Override
public boolean isDataSourceIngestModuleFactory() {
return true;
}
}
@@ -35,6 +35,7 @@ EmbeddedFileExtractorIngestModule.ImageExtractor.pptContainer.init.err=Ppt conta
EmbeddedFileExtractorIngestModule.ImageExtractor.pptxContainer.init.err=Pptx container could not be initialized while reading: {0}
EmbeddedFileExtractorIngestModule.ImageExtractor.xlsContainer.init.err=Xls container could not be initialized while reading: {0}
EmbeddedFileExtractorIngestModule.ImageExtractor.xlsxContainer.init.err=Xlsx container could not be initialized while reading: {0}
EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err=Embedded File Extractor is unable to read content of {0}
EmbeddedFileExtractorIngestModule.ImageExtractor.extractImage.addToDB.exception.msg=Unable to add the derived files to the database.
EmbeddedFileExtractorIngestModule.ImageExtractor.getOutputFolderPath.exception.msg=Could not get path for image extraction from Abstract File\: {0}
EmbeddedFileExtractorIngestModule.ImageExtractor.getOutputFolderPath.exception.msg=Could not get path for image extraction from Abstract File: {0}
@@ -79,7 +79,7 @@ public final class EmbeddedFileExtractorIngestModule implements FileIngestModule
} catch (SecurityException ex) {
logger.log(Level.SEVERE, "Error initializing output dir: " + moduleDirAbsolute, ex); //NON-NLS
services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), "Error initializing", "Error initializing output dir: " + moduleDirAbsolute)); //NON-NLS
throw new IngestModuleException(ex.getMessage());
throw new IngestModuleException(ex.getMessage(), ex);
}
}
@@ -87,7 +87,7 @@ public final class EmbeddedFileExtractorIngestModule implements FileIngestModule
try {
fileTypeDetector = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
throw new IngestModuleException(ex.getMessage());
throw new IngestModuleException(ex.getMessage(), ex);
}
// initialize the extraction modules.
@@ -25,7 +25,6 @@ import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.apache.poi.OldFileFormatException;
import org.apache.poi.hslf.model.Picture;
import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow;
@@ -210,13 +209,23 @@ class ImageExtractor {
HWPFDocument doc = null;
try {
doc = new HWPFDocument(new ReadContentInputStream(af));
} catch (Throwable ex) {
} catch (Throwable ignore) {
// instantiating POI containers throw RuntimeExceptions
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.docContainer.init.err", af.getName())); //NON-NLS
return null;
}
PicturesTable pictureTable = doc.getPicturesTable();
List<org.apache.poi.hwpf.usermodel.Picture> listOfAllPictures = pictureTable.getAllPictures();
PicturesTable pictureTable = null;
List<org.apache.poi.hwpf.usermodel.Picture> listOfAllPictures = null;
try {
pictureTable = doc.getPicturesTable();
listOfAllPictures = pictureTable.getAllPictures();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
String outputFolderPath;
if (listOfAllPictures.isEmpty()) {
return null;
@@ -227,9 +236,17 @@ class ImageExtractor {
return null;
}
listOfExtractedImages = new ArrayList<>();
byte[] data = null;
for (org.apache.poi.hwpf.usermodel.Picture picture : listOfAllPictures) {
String fileName = picture.suggestFullFileName();
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), picture.getContent());
try {
data = picture.getContent();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), data);
// TODO Extract more info from the Picture viz ctime, crtime, atime, mtime
listOfExtractedImages.add(new ExtractedImage(fileName, getFileRelativePath(fileName), picture.getSize(), af));
}
@@ -250,12 +267,19 @@ class ImageExtractor {
XWPFDocument docx = null;
try {
docx = new XWPFDocument(new ReadContentInputStream(af));
} catch (Throwable ex) {
} catch (Throwable ignore) {
// instantiating POI containers throw RuntimeExceptions
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.docxContainer.init.err", af.getName())); //NON-NLS
return null;
}
List<XWPFPictureData> listOfAllPictures = docx.getAllPictures();
List<XWPFPictureData> listOfAllPictures = null;
try {
listOfAllPictures = docx.getAllPictures();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
// if no images are extracted from the PPT, return null, else initialize
// the output folder for image extraction.
@@ -270,9 +294,17 @@ class ImageExtractor {
return null;
}
listOfExtractedImages = new ArrayList<>();
byte[] data = null;
for (XWPFPictureData xwpfPicture : listOfAllPictures) {
String fileName = xwpfPicture.getFileName();
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), xwpfPicture.getData());
try {
data = xwpfPicture.getData();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), data);
listOfExtractedImages.add(new ExtractedImage(fileName, getFileRelativePath(fileName), xwpfPicture.getData().length, af));
}
return listOfExtractedImages;
@@ -291,14 +323,21 @@ class ImageExtractor {
SlideShow ppt = null;
try {
ppt = new SlideShow(new ReadContentInputStream(af));
} catch (Throwable ex) {
} catch (Throwable ignore) {
// instantiating POI containers throw RuntimeExceptions
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.pptContainer.init.err", af.getName())); //NON-NLS
return null;
}
//extract all pictures contained in the presentation
PictureData[] listOfAllPictures = ppt.getPictureData();
PictureData[] listOfAllPictures = null;
try {
listOfAllPictures = ppt.getPictureData();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
// if no images are extracted from the PPT, return null, else initialize
// the output folder for image extraction.
@@ -317,6 +356,7 @@ class ImageExtractor {
// extraction path - outputFolder/image_number.ext
int i = 0;
listOfExtractedImages = new ArrayList<>();
byte[] data = null;
for (PictureData pictureData : listOfAllPictures) {
// Get image extension, generate image name, write image to the module
@@ -343,7 +383,14 @@ class ImageExtractor {
continue;
}
String imageName = UNKNOWN_NAME_PREFIX + i + ext; //NON-NLS
writeExtractedImage(Paths.get(outputFolderPath, imageName).toString(), pictureData.getData());
try {
data = pictureData.getData();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
writeExtractedImage(Paths.get(outputFolderPath, imageName).toString(), data);
listOfExtractedImages.add(new ExtractedImage(imageName, getFileRelativePath(imageName), pictureData.getData().length, af));
i++;
}
@@ -363,12 +410,19 @@ class ImageExtractor {
XMLSlideShow pptx;
try {
pptx = new XMLSlideShow(new ReadContentInputStream(af));
} catch (Throwable ex) {
} catch (Throwable ignore) {
// instantiating POI containers throw RuntimeExceptions
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.pptxContainer.init.err", af.getName())); //NON-NLS
return null;
}
List<XSLFPictureData> listOfAllPictures = pptx.getAllPictures();
List<XSLFPictureData> listOfAllPictures = null;
try {
listOfAllPictures = pptx.getAllPictures();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
// if no images are extracted from the PPT, return null, else initialize
// the output folder for image extraction.
@@ -384,12 +438,20 @@ class ImageExtractor {
}
listOfExtractedImages = new ArrayList<>();
byte[] data = null;
for (XSLFPictureData xslsPicture : listOfAllPictures) {
// get image file name, write it to the module outputFolder, and add
// it to the listOfExtractedImageAbstractFiles.
String fileName = xslsPicture.getFileName();
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), xslsPicture.getData());
try {
data = xslsPicture.getData();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), data);
listOfExtractedImages.add(new ExtractedImage(fileName, getFileRelativePath(fileName), xslsPicture.getData().length, af));
}
@@ -412,13 +474,21 @@ class ImageExtractor {
Workbook xls;
try {
xls = new HSSFWorkbook(new ReadContentInputStream(af));
} catch (Throwable ex) {
} catch (Throwable ignore) {
// instantiating POI containers throw RuntimeExceptions
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.xlsContainer.init.err", af.getName()) + af.getName()); //NON-NLS
logger.log(Level.WARNING, "{0}{1}", new Object[]{NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.xlsContainer.init.err", af.getName()), af.getName()}); //NON-NLS
return null;
}
List<? extends org.apache.poi.ss.usermodel.PictureData> listOfAllPictures = xls.getAllPictures();
List<? extends org.apache.poi.ss.usermodel.PictureData> listOfAllPictures = null;
try {
listOfAllPictures = xls.getAllPictures();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
// if no images are extracted from the PPT, return null, else initialize
// the output folder for image extraction.
String outputFolderPath;
@@ -434,9 +504,17 @@ class ImageExtractor {
int i = 0;
listOfExtractedImages = new ArrayList<>();
byte[] data = null;
for (org.apache.poi.ss.usermodel.PictureData pictureData : listOfAllPictures) {
String imageName = UNKNOWN_NAME_PREFIX + i + "." + pictureData.suggestFileExtension(); //NON-NLS
writeExtractedImage(Paths.get(outputFolderPath, imageName).toString(), pictureData.getData());
try {
data = pictureData.getData();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
writeExtractedImage(Paths.get(outputFolderPath, imageName).toString(), data);
listOfExtractedImages.add(new ExtractedImage(imageName, getFileRelativePath(imageName), pictureData.getData().length, af));
i++;
}
@@ -457,13 +535,21 @@ class ImageExtractor {
Workbook xlsx;
try {
xlsx = new XSSFWorkbook(new ReadContentInputStream(af));
} catch (Throwable ex) {
} catch (Throwable ignore) {
// instantiating POI containers throw RuntimeExceptions
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.xlsxContainer.init.err", af.getName())); //NON-NLS
return null;
}
List<? extends org.apache.poi.ss.usermodel.PictureData> listOfAllPictures = xlsx.getAllPictures();
List<? extends org.apache.poi.ss.usermodel.PictureData> listOfAllPictures = null;
try {
listOfAllPictures = xlsx.getAllPictures();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
// if no images are extracted from the PPT, return null, else initialize
// the output folder for image extraction.
String outputFolderPath;
@@ -479,9 +565,17 @@ class ImageExtractor {
int i = 0;
listOfExtractedImages = new ArrayList<>();
byte[] data = null;
for (org.apache.poi.ss.usermodel.PictureData pictureData : listOfAllPictures) {
String imageName = UNKNOWN_NAME_PREFIX + i + "." + pictureData.suggestFileExtension();
writeExtractedImage(Paths.get(outputFolderPath, imageName).toString(), pictureData.getData());
try {
data = pictureData.getData();
} catch (Exception ignore) {
// log internal Java and Apache errors as WARNING
logger.log(Level.WARNING, NbBundle.getMessage(this.getClass(), "EmbeddedFileExtractorIngestModule.ImageExtractor.processing.err", af.getName())); //NON-NLS
return null;
}
writeExtractedImage(Paths.get(outputFolderPath, imageName).toString(), data);
listOfExtractedImages.add(new ExtractedImage(imageName, getFileRelativePath(imageName), pictureData.getData().length, af));
i++;
}
@@ -133,7 +133,7 @@ class SevenZipExtractor {
String details = NbBundle.getMessage(SevenZipExtractor.class, "EmbeddedFileExtractorIngestModule.ArchiveExtractor.init.errCantInitLib",
e.getMessage());
services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
throw new IngestModuleException(e.getMessage());
throw new IngestModuleException(e.getMessage(), e);
}
}
this.context = context;
@@ -91,7 +91,7 @@ public final class ExifParserFileIngestModule implements FileIngestModule {
try {
fileTypeDetector = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "ExifParserFileIngestModule.startUp.fileTypeDetectorInitializationException.msg"));
throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "ExifParserFileIngestModule.startUp.fileTypeDetectorInitializationException.msg"), ex);
}
}
@@ -4,7 +4,6 @@ OptionsCategory_FileExtMismatch=File Extension Mismatch
AddFileExtensionAction.msgDlg.msg=Writing XML configuration file failed.
AddFileExtensionAction.msgDlg.title=Add Mismatch Extension Error
AddFileExtensionAction.extHeaderLbl.text=Allowed Extensions for
FileExtMismatchConfigPanel.name.text=Advanced File Extension Mismatch Configuration
FileExtMismatchConfigPanel.addExtButton.errLabel.empty=Extension text is empty\!
FileExtMismatchConfigPanel.addExtButton.errLabel.noMimeType=No MIME type selected\!
FileExtMismatchConfigPanel.addExtButton.errLabel.extExists=Extension already exists\!
@@ -52,3 +51,4 @@ FileExtMismatchSettingsPanel.removeExtButton.text=Remove Selected Extension
FileExtMismatchSettingsPanel.userTypeTextField.text=
FileExtMismatchDetectorModuleFactory.getIngestJobSettingsPanel.exception.msg=Expected settings argument to be instanceof FileExtMismatchDetectorModuleSettings
FileExtMismatchDetectorModuleFactory.createFileIngestModule.exception.msg=Expected settings argument to be instanceof FileExtMismatchDetectorModuleSettings
FileExtMismatchModuleSettingsPanel.skipKnownFiles.text=Skip known files
@@ -1,47 +1,46 @@
OpenIDE-Module-Name=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4
OptionsCategory_Name_FileExtMismatchOptions=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4
OptionsCategory_FileExtMismatch=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4
AddFileExtensionAction.msgDlg.msg=XML\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304F\u306E\u3092\u5931\u6557\u3057\u307E\u3057\u305F\u3002
AddFileExtensionAction.msgDlg.title=\u4E0D\u4E00\u81F4\u62E1\u5F35\u5B50\u306E\u30A8\u30E9\u30FC\u3092\u8FFD\u52A0
FileExtMismatchConfigPanel.name.text=\u30A2\u30C9\u30D0\u30F3\u30B9\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4\u306E\u8A2D\u5B9A
FileExtMismatchConfigPanel.addExtButton.errLabel.empty=\u62E1\u5F35\u5B50\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u767D\u3067\u3059\uFF01
FileExtMismatchConfigPanel.addExtButton.errLabel.noMimeType=MIME\u30BF\u30A4\u30D7\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01
FileExtMismatchConfigPanel.addExtButton.errLabel.extExists=\u62E1\u5F35\u5B50\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\uFF01
FileExtMismatchConfigPanel.addExtButton.errLabel.extAdded=\u62E1\u5F35\u5B50{0}\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\u3002
FileExtMismatchConfigPanel.addTypeButton.empty=MIME\u30BF\u30A4\u30D7\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u767D\u3067\u3059\uFF01
FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotSupported=MIME\u30BF\u30A4\u30D7\u304C\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01
FileExtMismatchConfigPanel.addTypeButton.mimeTypeExists=MIME\u30BF\u30A4\u30D7\u304C\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\uFF01
FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable=MIME\u30BF\u30A4\u30D7\u304C\u3053\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u306F\u691C\u51FA\u3067\u304D\u307E\u305B\u3093\u3002
FileExtMismatchConfigPanel.addTypeButton.mimeTypeAdded=MIME\u30BF\u30A4\u30D7{0}\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\u3002
FileExtMismatchConfigPanel.removeTypeButton.noneSelected=MIME\u30BF\u30A4\u30D7\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01
FileExtMismatchConfigPanel.remoteTypeButton.deleted=MIME\u30BF\u30A4\u30D7{0}\u304C\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002
FileExtMismatchConfigPanel.removeExtButton.noneSelected=\u62E1\u5F35\u5B50\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01
FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected=MIME\u30BF\u30A4\u30D7\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF01
FileExtMismatchConfigPanel.removeExtButton.deleted=\u62E1\u5F35\u5B50{0}\u304C\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002
FileExtMismatchConfigPanel.store.msg=\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F\u3002
FileExtMismatchConfigPanel.store.msgDlg.msg=XML\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304F\u306E\u3092\u5931\u6557\u3057\u307E\u3057\u305F\u3002
FileExtMismatchConfigPanel.save.msgDlg.title=\u4FDD\u5B58\u30A8\u30E9\u30FC
FileExtMismatchConfigPanel.ok.confDlg.msg=\u8A2D\u5B9A\u5909\u66F4\u3092\u4FDD\u5B58\u3057\u307E\u3059\u304B\uFF1F
FileExtMismatchConfigPanel.confDlg.title=\u4FDD\u5B58\u3055\u308C\u3066\u3044\u306A\u3044\u5909\u66F4
FileExtMismatchConfigPanel.mimeTableModel.colName=MIME\u30BF\u30A4\u30D7
FileExtMismatchConfigPanel.extTableModel.colName=\u62E1\u5F35\u5B50
FileExtMismatchContextMenuActionsProvider.menuItemStr=\u62E1\u5F35\u5B50{0}\u3092MIME\u30BF\u30A4\u30D7{1}\u306E\u4E00\u81F4\u3068\u3057\u3066\u8FFD\u52A0
FileExtMismatchIngestModule.moduleName=\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4\u30C7\u30A3\u30C6\u30AF\u30BF\u30FC
FileExtMismatchIngestModule.moduleDesc.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306B\u57FA\u3065\u3044\u3066\u3001\u6A19\u6E96\u7684\u3067\u306F\u306A\u3044\u62E1\u5F35\u5B50\u3092\u6301\u3064\u30D5\u30A1\u30A4\u30EB\u3092\u30D5\u30E9\u30B0\u3057\u307E\u3059\u3002d
FileExtMismatchIngestModule.complete.totalProcTime=\u5408\u8A08\u51E6\u7406\u6642\u9593
FileExtMismatchIngestModule.complete.totalFiles=\u5408\u8A08\u51E6\u7406\u30D5\u30A1\u30A4\u30EB\u6570
FileExtMismatchIngestModule.complete.svcMsg.text=\u30D5\u30A1\u30A4\u30EB\u62E1\u5F35\u5B50\u4E0D\u4E00\u81F4\u7D50\u679C
FileExtMismatchOptionsPanelController.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
FileExtMismatchOptionsPanelController.moduleErr.msg=FileExtMismatchOptionsPanelController\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u306E\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u4E0D\u5B8C\u5168\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002
AddFileExtensionAction.extHeaderLbl.text=\u4E0B\u8A18\u7528\u306B\u8A31\u53EF\u3059\u308B\u62E1\u5F35\u5B50
FileExtMismatchModuleSettingsPanel.skipTextPlain.text=\u30C6\u30AD\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u3092\u30B9\u30AD\u30C3\u30D7
FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text=\u62E1\u5F35\u5B50\u306E\u7121\u3044\u30D5\u30A1\u30A4\u30EB\u3092\u30B9\u30AD\u30C3\u30D7
FileExtMismatchSettingsPanel.addTypeButton.text=\u30BF\u30A4\u30D7\u3092\u8FFD\u52A0
FileExtMismatchSettingsPanel.extHeaderLabel.text=\u8A31\u53EF\u3059\u308B\u62E1\u5F35\u5B50\uFF1A
FileExtMismatchSettingsPanel.removeTypeButton.text=\u9078\u629E\u3057\u305F\u30BF\u30A4\u30D7\u3092\u524A\u9664
FileExtMismatchSettingsPanel.saveButton.text=\u8A2D\u5B9A\u3092\u4FDD\u5B58
FileExtMismatchSettingsPanel.jLabel1.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\uFF1A
FileExtMismatchSettingsPanel.addExtButton.text=\u62E1\u5F35\u5B50\u3092\u8FFD\u52A0
FileExtMismatchSettingsPanel.removeExtButton.text=\u9078\u629E\u3057\u305F\u62E1\u5F35\u5B50\u3092\u524A\u9664
FileExtMismatchDetectorModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof FileExtMismatchDetectorModuleSettings\u3067\u3059\u3002
FileExtMismatchDetectorModuleFactory.createFileIngestModule.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof FileExtMismatchDetectorModuleSettings\u3067\u3059\u3002
OpenIDE-Module-Name=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4
OptionsCategory_Name_FileExtMismatchOptions=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4
OptionsCategory_FileExtMismatch=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4
AddFileExtensionAction.msgDlg.msg=XML\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304f\u306e\u3092\u5931\u6557\u3057\u307e\u3057\u305f\u3002
AddFileExtensionAction.msgDlg.title=\u4e0d\u4e00\u81f4\u62e1\u5f35\u5b50\u306e\u30a8\u30e9\u30fc\u3092\u8ffd\u52a0
FileExtMismatchConfigPanel.addExtButton.errLabel.empty=\u62e1\u5f35\u5b50\u30c6\u30ad\u30b9\u30c8\u304c\u7a7a\u767d\u3067\u3059\uff01
FileExtMismatchConfigPanel.addExtButton.errLabel.noMimeType=MIME\u30bf\u30a4\u30d7\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.addExtButton.errLabel.extExists=\u62e1\u5f35\u5b50\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\uff01
FileExtMismatchConfigPanel.addExtButton.errLabel.extAdded=\u62e1\u5f35\u5b50{0}\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.addTypeButton.empty=MIME\u30bf\u30a4\u30d7\u30c6\u30ad\u30b9\u30c8\u304c\u7a7a\u767d\u3067\u3059\uff01
FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotSupported=MIME\u30bf\u30a4\u30d7\u304c\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.addTypeButton.mimeTypeExists=MIME\u30bf\u30a4\u30d7\u304c\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059\uff01
FileExtMismatchConfigPanel.addTypeButton.mimeTypeNotDetectable=MIME\u30bf\u30a4\u30d7\u304c\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u306f\u691c\u51fa\u3067\u304d\u307e\u305b\u3093\u3002
FileExtMismatchConfigPanel.addTypeButton.mimeTypeAdded=MIME\u30bf\u30a4\u30d7{0}\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.removeTypeButton.noneSelected=MIME\u30bf\u30a4\u30d7\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.remoteTypeButton.deleted=MIME\u30bf\u30a4\u30d7{0}\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.removeExtButton.noneSelected=\u62e1\u5f35\u5b50\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.removeExtButton.noMimeTypeSelected=MIME\u30bf\u30a4\u30d7\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01
FileExtMismatchConfigPanel.removeExtButton.deleted=\u62e1\u5f35\u5b50{0}\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.store.msg=\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.store.msgDlg.msg=XML\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304f\u306e\u3092\u5931\u6557\u3057\u307e\u3057\u305f\u3002
FileExtMismatchConfigPanel.save.msgDlg.title=\u4fdd\u5b58\u30a8\u30e9\u30fc
FileExtMismatchConfigPanel.ok.confDlg.msg=\u8a2d\u5b9a\u5909\u66f4\u3092\u4fdd\u5b58\u3057\u307e\u3059\u304b\uff1f
FileExtMismatchConfigPanel.confDlg.title=\u4fdd\u5b58\u3055\u308c\u3066\u3044\u306a\u3044\u5909\u66f4
FileExtMismatchConfigPanel.mimeTableModel.colName=MIME\u30bf\u30a4\u30d7
FileExtMismatchConfigPanel.extTableModel.colName=\u62e1\u5f35\u5b50
FileExtMismatchContextMenuActionsProvider.menuItemStr=\u62e1\u5f35\u5b50{0}\u3092MIME\u30bf\u30a4\u30d7{1}\u306e\u4e00\u81f4\u3068\u3057\u3066\u8ffd\u52a0
FileExtMismatchIngestModule.moduleName=\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4\u30c7\u30a3\u30c6\u30af\u30bf\u30fc
FileExtMismatchIngestModule.moduleDesc.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306b\u57fa\u3065\u3044\u3066\u3001\u6a19\u6e96\u7684\u3067\u306f\u306a\u3044\u62e1\u5f35\u5b50\u3092\u6301\u3064\u30d5\u30a1\u30a4\u30eb\u3092\u30d5\u30e9\u30b0\u3057\u307e\u3059\u3002d
FileExtMismatchIngestModule.complete.totalProcTime=\u5408\u8a08\u51e6\u7406\u6642\u9593
FileExtMismatchIngestModule.complete.totalFiles=\u5408\u8a08\u51e6\u7406\u30d5\u30a1\u30a4\u30eb\u6570
FileExtMismatchIngestModule.complete.svcMsg.text=\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50\u4e0d\u4e00\u81f4\u7d50\u679c
FileExtMismatchOptionsPanelController.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
FileExtMismatchOptionsPanelController.moduleErr.msg=FileExtMismatchOptionsPanelController\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306e\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
AddFileExtensionAction.extHeaderLbl.text=\u4e0b\u8a18\u7528\u306b\u8a31\u53ef\u3059\u308b\u62e1\u5f35\u5b50
FileExtMismatchModuleSettingsPanel.skipTextPlain.text=\u30c6\u30ad\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u30b9\u30ad\u30c3\u30d7
FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text=\u62e1\u5f35\u5b50\u306e\u7121\u3044\u30d5\u30a1\u30a4\u30eb\u3092\u30b9\u30ad\u30c3\u30d7
FileExtMismatchSettingsPanel.addTypeButton.text=\u30bf\u30a4\u30d7\u3092\u8ffd\u52a0
FileExtMismatchSettingsPanel.extHeaderLabel.text=\u8a31\u53ef\u3059\u308b\u62e1\u5f35\u5b50\uff1a
FileExtMismatchSettingsPanel.removeTypeButton.text=\u9078\u629e\u3057\u305f\u30bf\u30a4\u30d7\u3092\u524a\u9664
FileExtMismatchSettingsPanel.saveButton.text=\u8a2d\u5b9a\u3092\u4fdd\u5b58
FileExtMismatchSettingsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\uff1a
FileExtMismatchSettingsPanel.addExtButton.text=\u62e1\u5f35\u5b50\u3092\u8ffd\u52a0
FileExtMismatchSettingsPanel.removeExtButton.text=\u9078\u629e\u3057\u305f\u62e1\u5f35\u5b50\u3092\u524a\u9664
FileExtMismatchDetectorModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof FileExtMismatchDetectorModuleSettings\u3067\u3059\u3002
FileExtMismatchDetectorModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof FileExtMismatchDetectorModuleSettings\u3067\u3059\u3002
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +18,8 @@
*/
package org.sleuthkit.autopsy.modules.fileextmismatch;
import java.io.IOException;
import java.io.ObjectInputStream;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
/**
@@ -26,15 +28,21 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
final class FileExtMismatchDetectorModuleSettings implements IngestModuleIngestJobSettings {
private static final long serialVersionUID = 1L;
private boolean skipFilesWithNoExtension = true;
private boolean skipFilesWithTextPlainMimeType = true;
private long versionNumber;
private boolean skipFilesWithNoExtension;
private boolean skipFilesWithTextPlainMimeType;
private boolean skipKnownFiles;
FileExtMismatchDetectorModuleSettings() {
this.skipFilesWithNoExtension = true;
this.skipFilesWithTextPlainMimeType = true;
this.skipKnownFiles = true;
}
FileExtMismatchDetectorModuleSettings(boolean skipKnownFiles, boolean skipFilesWithNoExtension, boolean skipFilesWithTextPlainMimeType) {
this.skipFilesWithNoExtension = skipFilesWithNoExtension;
this.skipFilesWithTextPlainMimeType = skipFilesWithTextPlainMimeType;
this.skipKnownFiles = skipKnownFiles;
}
@Override
@@ -42,19 +50,41 @@ final class FileExtMismatchDetectorModuleSettings implements IngestModuleIngestJ
return serialVersionUID;
}
void setSkipFilesWithNoExtension(boolean enabled) {
skipFilesWithNoExtension = enabled;
void setSkipFilesWithNoExtension(boolean skipFilesWithNoExtension) {
this.skipFilesWithNoExtension = skipFilesWithNoExtension;
}
boolean skipFilesWithNoExtension() {
return skipFilesWithNoExtension;
}
void setSkipFilesWithTextPlainMimeType(boolean enabled) {
skipFilesWithTextPlainMimeType = enabled;
void setSkipFilesWithTextPlainMimeType(boolean skipFilesWithTextPlainMimeType) {
this.skipFilesWithTextPlainMimeType = skipFilesWithTextPlainMimeType;
}
boolean skipFilesWithTextPlainMimeType() {
return skipFilesWithTextPlainMimeType;
}
boolean skipKnownFiles() {
return skipKnownFiles;
}
void setSkipKnownFiles(boolean skipKnownFiles) {
this.skipKnownFiles = skipKnownFiles;
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
if (0L == versionNumber) {
/*
* If the version number is set to the Java field default value of
* zero, then skipKnownFiles is a new field. Change this to the
* desired default value of true.
*/
skipKnownFiles = true;
}
versionNumber = 1;
}
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,13 +18,11 @@
*/
package org.sleuthkit.autopsy.modules.fileextmismatch;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
@@ -40,9 +38,9 @@ import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskData.FileKnown;
import org.sleuthkit.datamodel.TskException;
/**
@@ -58,6 +56,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
private static Blackboard blackboard;
private FileTypeDetector detector;
private static class IngestJobTotals {
@@ -94,12 +93,20 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault();
SigTypeToExtMap = xmlLoader.load();
try {
this.detector = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
throw new IngestModuleException("Could not create file type detector.", ex);
}
}
@Override
public ProcessResult process(AbstractFile abstractFile) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
if(this.settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
return ProcessResult.OK;
}
// skip non-files
if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
@@ -157,7 +164,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
if (settings.skipFilesWithNoExtension() && currActualExt.isEmpty()) {
return false;
}
String currActualSigType = abstractFile.getMIMEType();
String currActualSigType = detector.getFileType(abstractFile);
if (currActualSigType == null) {
return false;
}
@@ -21,6 +21,7 @@
<Group type="103" groupAlignment="0" attributes="0">
<Component id="skipTextPlain" min="-2" max="-2" attributes="0"/>
<Component id="skipNoExtCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="skipKnownFiles" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="138" max="32767" attributes="0"/>
</Group>
@@ -32,7 +33,9 @@
<Component id="skipNoExtCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="skipTextPlain" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="51" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="skipKnownFiles" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="28" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -62,5 +65,16 @@
<AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="skipTextPlain.setSelected(true);"/>
</AuxValues>
</Component>
<Component class="javax.swing.JCheckBox" name="skipKnownFiles">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties" key="FileExtMismatchModuleSettingsPanel.skipKnownFiles.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="skipKnownFilesActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>
@@ -38,6 +38,7 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
private void customizeComponents() {
skipNoExtCheckBox.setSelected(settings.skipFilesWithNoExtension());
skipTextPlain.setSelected(settings.skipFilesWithTextPlainMimeType());
skipKnownFiles.setSelected(settings.skipKnownFiles());
}
@Override
@@ -56,6 +57,7 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
skipNoExtCheckBox = new javax.swing.JCheckBox();
skipTextPlain = new javax.swing.JCheckBox();
skipKnownFiles = new javax.swing.JCheckBox();
skipNoExtCheckBox.setSelected(true);
skipNoExtCheckBox.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchModuleSettingsPanel.class, "FileExtMismatchModuleSettingsPanel.skipNoExtCheckBox.text")); // NOI18N
@@ -73,6 +75,14 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
}
});
skipKnownFiles.setSelected(true);
skipKnownFiles.setText(org.openide.util.NbBundle.getMessage(FileExtMismatchModuleSettingsPanel.class, "FileExtMismatchModuleSettingsPanel.skipKnownFiles.text")); // NOI18N
skipKnownFiles.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
skipKnownFilesActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@@ -81,7 +91,8 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(skipTextPlain)
.addComponent(skipNoExtCheckBox))
.addComponent(skipNoExtCheckBox)
.addComponent(skipKnownFiles))
.addGap(0, 138, Short.MAX_VALUE))
);
layout.setVerticalGroup(
@@ -90,7 +101,9 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
.addComponent(skipNoExtCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(skipTextPlain)
.addContainerGap(51, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(skipKnownFiles)
.addContainerGap(28, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@@ -102,7 +115,12 @@ final class FileExtMismatchModuleSettingsPanel extends IngestModuleIngestJobSett
settings.setSkipFilesWithTextPlainMimeType(skipTextPlain.isSelected());
}//GEN-LAST:event_skipTextPlainActionPerformed
private void skipKnownFilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipKnownFilesActionPerformed
settings.setSkipKnownFiles(skipKnownFiles.isSelected());
}//GEN-LAST:event_skipKnownFilesActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox skipKnownFiles;
private javax.swing.JCheckBox skipNoExtCheckBox;
private javax.swing.JCheckBox skipTextPlain;
// End of variables declaration//GEN-END:variables
@@ -69,8 +69,9 @@ final class FileExtMismatchSettingsPanel extends IngestModuleGlobalSettingsPanel
customizeComponents();
}
@NbBundle.Messages({"FileExtMismatchSettingsPanel.Title=Global File Extension Mismatch Identification Settings"})
private void customizeComponents() {
setName(NbBundle.getMessage(this.getClass(), "FileExtMismatchConfigPanel.name.text"));
setName(Bundle.FileExtMismatchSettingsPanel_Title());
// Handle selections on the left table
lsm = mimeTable.getSelectionModel();
@@ -44,9 +44,8 @@ FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text=Cannot make changes
UserDefinedFileTypesManager.loadFileTypes.errorMessage=Failed to load existing file type definitions.
UserDefinedFileTypesManager.saveFileTypes.errorMessage=Failed to save file type definitions.
FileTypeIdGlobalSettingsPanel.newTypeButton.text=New
FileTypeIdGlobalSettingsPanel.jLabel1.text=Custom File Types
FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME Types:
FileTypeIdGlobalSettingsPanel.jLabel2.text=Custom MIME Types:
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here.
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=Offset is relative to
FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=Offset is relative to
@@ -1,47 +1,46 @@
OpenIDE-Module-Name=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7ID
FileTypeIdIngestModule.moduleName.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306E\u7279\u5B9A
FileTypeIdIngestModule.moduleDesc.text=\u30D0\u30A4\u30CA\u30EA\u30B7\u30B0\u30CD\u30C1\u30E3\u306B\u57FA\u3065\u3044\u3066\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u3092\u4E00\u81F4\u3057\u307E\u3059\u3002
FileTypeIdIngestModule.complete.totalProcTime=\u5408\u8A08\u51E6\u7406\u6642\u9593
FileTypeIdIngestModule.complete.totalFiles=\u5408\u8A08\u51E6\u7406\u30D5\u30A1\u30A4\u30EB\u6570
FileTypeIdIngestModule.complete.srvMsg.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7ID\u306E\u7D50\u679C
FileTypeIdModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof FileTypeIdModuleSettings\u3067\u3059\u3002
FileTypeIdModuleFactory.createFileIngestModule.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof FileTypeIdModuleSettings\u3067\u3059\u3002
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u6301\u3064\u30D5\u30A1\u30A4\u30EB\u6570\u306B\u3088\u3063\u3066\u306F\u3001\u3053\u306E\u30DC\u30C3\u30AF\u30B9\u3092\u9078\u629E\u3059\u308B\u3053\u3068\u306B\u3088\u308A\u3001\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u306E\u7279\u5B9A\u3092\u52A0\u901F\u3057\u307E\u3059\u3002
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=\u65E2\u77E5\u30D5\u30A1\u30A4\u30EB\uFF08NSRL\uFF09\u3092\u30B9\u30AD\u30C3\u30D7
FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=\u524A\u9664
FileTypeIdGlobalSettingsPanel.filesSetNameLabel.text=\u30BB\u30C3\u30C8\u540D
FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u5B9F\u884C\u4E2D\u306B\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u5B9A\u7FA9\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093\uFF01
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.title=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8\u540D\u304C\u6B20\u3051\u3066\u3044\u307E\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message=MIME\u30BF\u30A4\u30D7\u304C\u5FC5\u8981\u3067\u3059\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title=MIME\u30BF\u30A4\u30D7\u304C\u6B20\u3051\u3066\u3044\u307E\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message=\u30AA\u30D5\u30BB\u30C3\u30C8\u306F\u6B63\u6574\u6570\u3067\u306A\u3051\u308C\u3070\u3044\u3051\u307E\u305B\u3093\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title=\u7121\u52B9\u306A\u30AA\u30D5\u30BB\u30C3\u30C8
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message=\u3053\u306E\u30B7\u30B0\u30CD\u30C1\u30E3\u306B\u4E00\u3064\u4EE5\u4E0A\u306E\u7121\u52B9\u306A16\u9032\u6570\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C\u5FC5\u8981\u3067\u3059\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C\u6B20\u3051\u3066\u3044\u307E\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C\u7121\u52B9\u3067\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title=\u8AAD\u307F\u8FBC\u307F\u304C\u5931\u6557\u3057\u307E\u3057\u305F
FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title=\u4FDD\u5B58\u304C\u5931\u6557\u3057\u307E\u3057\u305F
FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME\u30BF\u30A4\u30D7
FileTypeIdGlobalSettingsPanel.newTypeButton.text=\u65B0\u898F\u30BF\u30A4\u30D7
FileTypeIdGlobalSettingsPanel.offsetLabel.text=\u30D0\u30A4\u30C8\u30AA\u30D5\u30BB\u30C3\u30C8
FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=\u767A\u898B\u3057\u305F\u969B\u306B\u300C\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u300D\u3068\u8B66\u544A
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=\u4FDD\u5B58\u30BF\u30A4\u30D7
FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=\u30B9\u30C8\u30EA\u30F3\u30B0\uFF08ASCII\uFF09
FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=\u30D0\u30A4\u30C8\uFF08HEX\uFF09
FileTypeIdGlobalSettingsPanel.signatureLabel.text=\u30B7\u30B0\u30CD\u30C1\u30E3
FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=\u30B7\u30B0\u30CD\u30C1\u30E3\u30BF\u30A4\u30D7
OptionsCategory_Keywords_FileTypeId=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7ID
OptionsCategory_Name_FileTypeId=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7
UserDefinedFileTypesManager.loadFileTypes.errorMessage=\u65E2\u5B58\u306E\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u5B9A\u7FA9\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F
UserDefinedFileTypesManager.saveFileTypes.errorMessage=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u5B9A\u7FA9\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message=\u30A2\u30E9\u30FC\u30C8\u3092\u8A2D\u5B9A\u3059\u308B\u306B\u306F\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8\u540D\u304C\u5FC5\u8981\u3067\u3059\u3002
FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem=\u958B\u59CB
FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem=\u505C\u6B62
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length=\u30AA\u30D5\u30BB\u30C3\u30C8\u306F\u30B7\u30B0\u30CD\u30C1\u30E3\u30B5\u30A4\u30BA\u3088\u308A\u5C0F\u3055\u304F\u3066\u306F\u3044\u3051\u307E\u305B\u3093\u3002
FileTypeIdGlobalSettingsPanel.jLabel1.text=\u30AB\u30B9\u30BF\u30E0\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7
FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME\u30BF\u30A4\u30D7\uFF1A
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy\u306F\u81EA\u52D5\u7684\u306B\u591A\u304F\u306E\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u3092\u691C\u77E5\u3067\u304D\u307E\u3059\u3002\u3053\u3053\u306B\u306F\u3042\u306A\u305F\u306E\u30AB\u30B9\u30BF\u30E0\u306E\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u30C7\u30A3\u30C6\u30AF\u30BF\u3092\u8D77\u52D5\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\u30C7\u30A3\u30C6\u30AF\u30BF\u3092\u8D77\u52D5\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=\u30AA\u30D5\u30BB\u30C3\u30C8\u306F\u6B21\u3068\u76F8\u5BFE\u7684
OpenIDE-Module-Name=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7ID
FileTypeIdIngestModule.moduleName.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306e\u7279\u5b9a
FileTypeIdIngestModule.moduleDesc.text=\u30d0\u30a4\u30ca\u30ea\u30b7\u30b0\u30cd\u30c1\u30e3\u306b\u57fa\u3065\u3044\u3066\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u4e00\u81f4\u3057\u307e\u3059\u3002
FileTypeIdIngestModule.complete.totalProcTime=\u5408\u8a08\u51e6\u7406\u6642\u9593
FileTypeIdIngestModule.complete.totalFiles=\u5408\u8a08\u51e6\u7406\u30d5\u30a1\u30a4\u30eb\u6570
FileTypeIdIngestModule.complete.srvMsg.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7ID\u306e\u7d50\u679c
FileTypeIdModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof FileTypeIdModuleSettings\u3067\u3059\u3002
FileTypeIdModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof FileTypeIdModuleSettings\u3067\u3059\u3002
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u6301\u3064\u30d5\u30a1\u30a4\u30eb\u6570\u306b\u3088\u3063\u3066\u306f\u3001\u3053\u306e\u30dc\u30c3\u30af\u30b9\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u306e\u7279\u5b9a\u3092\u52a0\u901f\u3057\u307e\u3059\u3002
FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NSRL\uff09\u3092\u30b9\u30ad\u30c3\u30d7
FileTypeIdGlobalSettingsPanel.deleteTypeButton.text=\u524a\u9664
FileTypeIdGlobalSettingsPanel.filesSetNameLabel.text=\u30bb\u30c3\u30c8\u540d
FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c\u4e2d\u306b\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u5b9a\u7fa9\u3092\u5909\u66f4\u3067\u304d\u307e\u305b\u3093\uff01
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.title=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u540d\u304c\u6b20\u3051\u3066\u3044\u307e\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message=MIME\u30bf\u30a4\u30d7\u304c\u5fc5\u8981\u3067\u3059\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title=MIME\u30bf\u30a4\u30d7\u304c\u6b20\u3051\u3066\u3044\u307e\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b63\u6574\u6570\u3067\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title=\u7121\u52b9\u306a\u30aa\u30d5\u30bb\u30c3\u30c8
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message=\u3053\u306e\u30b7\u30b0\u30cd\u30c1\u30e3\u306b\u4e00\u3064\u4ee5\u4e0a\u306e\u7121\u52b9\u306a16\u9032\u6570\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message=\u30b7\u30b0\u30cd\u30c1\u30e3\u304c\u5fc5\u8981\u3067\u3059\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title=\u30b7\u30b0\u30cd\u30c1\u30e3\u304c\u6b20\u3051\u3066\u3044\u307e\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignatureBytes.title=\u30b7\u30b0\u30cd\u30c1\u30e3\u304c\u7121\u52b9\u3067\u3059
FileTypeIdGlobalSettingsPanel.JOptionPane.loadFailed.title=\u8aad\u307f\u8fbc\u307f\u304c\u5931\u6557\u3057\u307e\u3057\u305f
FileTypeIdGlobalSettingsPanel.JOptionPane.storeFailed.title=\u4fdd\u5b58\u304c\u5931\u6557\u3057\u307e\u3057\u305f
FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME\u30bf\u30a4\u30d7
FileTypeIdGlobalSettingsPanel.newTypeButton.text=\u65b0\u898f\u30bf\u30a4\u30d7
FileTypeIdGlobalSettingsPanel.offsetLabel.text=\u30d0\u30a4\u30c8\u30aa\u30d5\u30bb\u30c3\u30c8
FileTypeIdGlobalSettingsPanel.postHitCheckBox.text=\u767a\u898b\u3057\u305f\u969b\u306b\u300c\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u300d\u3068\u8b66\u544a
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=\u4fdd\u5b58\u30bf\u30a4\u30d7
FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=\u30b9\u30c8\u30ea\u30f3\u30b0\uff08ASCII\uff09
FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=\u30d0\u30a4\u30c8\uff08HEX\uff09
FileTypeIdGlobalSettingsPanel.signatureLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3
FileTypeIdGlobalSettingsPanel.signatureTypeLabel.text=\u30b7\u30b0\u30cd\u30c1\u30e3\u30bf\u30a4\u30d7
OptionsCategory_Keywords_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7ID
OptionsCategory_Name_FileTypeId=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7
UserDefinedFileTypesManager.loadFileTypes.errorMessage=\u65e2\u5b58\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u5b9a\u7fa9\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f
UserDefinedFileTypesManager.saveFileTypes.errorMessage=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u5b9a\u7fa9\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidInterestingFilesSetName.message=\u30a2\u30e9\u30fc\u30c8\u3092\u8a2d\u5b9a\u3059\u308b\u306b\u306f\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u540d\u304c\u5fc5\u8981\u3067\u3059\u3002
FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem=\u958b\u59cb
FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem=\u505c\u6b62
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u30b7\u30b0\u30cd\u30c1\u30e3\u30b5\u30a4\u30ba\u3088\u308a\u5c0f\u3055\u304f\u3066\u306f\u3044\u3051\u307e\u305b\u3093\u3002
FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME\u30bf\u30a4\u30d7\uff1a
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy\u306f\u81ea\u52d5\u7684\u306b\u591a\u304f\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u691c\u77e5\u3067\u304d\u307e\u3059\u3002\u3053\u3053\u306b\u306f\u3042\u306a\u305f\u306e\u30ab\u30b9\u30bf\u30e0\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u30c7\u30a3\u30c6\u30af\u30bf\u3092\u8d77\u52d5\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=\u30aa\u30d5\u30bb\u30c3\u30c8\u306f\u6b21\u3068\u76f8\u5bfe\u7684
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014-2016 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,10 +35,10 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskDataException;
/**
* Detects the type of a file by an inspection of its contents.
* Detects the MIME type of a file by an inspection of its contents, using both
* user-defined type definitions and Tika.
*/
public class FileTypeDetector {
@@ -49,11 +49,14 @@ public class FileTypeDetector {
private static final Logger logger = Logger.getLogger(FileTypeDetector.class.getName());
/**
* Constructs an object that detects the type of a file by an inspection of
* its contents.
* Constructs an object that detects the MIME type of a file by an
* inspection of its contents, using both user-defined type definitions and
* Tika.
*
* @throws FileTypeDetector.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.
*/
public FileTypeDetector() throws FileTypeDetectorInitException {
try {
@@ -63,13 +66,28 @@ public class FileTypeDetector {
}
}
/**
* Gets the names of the user-defined MIME types.
*
* @return A list of the user-defined MIME types.
*/
public List<String> getUserDefinedTypes() {
List<String> list = new ArrayList<>();
if (userDefinedFileTypes != null) {
for (FileType fileType : userDefinedFileTypes) {
list.add(fileType.getMimeType());
}
}
return list;
}
/**
* Determines whether or not a given MIME type is detectable by this
* detector.
*
* @param mimeType The MIME type name, e.g. "text/html", to look up.
* @param mimeType The MIME type name (e.g., "text/html").
*
* @return True if MIME type is detectable.
* @return True or false.
*/
public boolean isDetectable(String mimeType) {
return isDetectableAsUserDefinedType(mimeType) || isDetectableByTika(mimeType);
@@ -77,11 +95,11 @@ public class FileTypeDetector {
/**
* Determines whether or not a given MIME type is detectable as a
* user-defined file type.
* user-defined MIME type by this detector.
*
* @param mimeType The MIME type name, e.g. "text/html", to look up.
* @param mimeType The MIME type name (e.g., "text/html").
*
* @return True if MIME type is detectable.
* @return True or false.
*/
private boolean isDetectableAsUserDefinedType(String mimeType) {
for (FileType fileType : userDefinedFileTypes) {
@@ -95,9 +113,9 @@ public class FileTypeDetector {
/**
* Determines whether or not a given MIME type is detectable by Tika.
*
* @param mimeType The MIME type name, e.g. "text/html", to look up.
* @param mimeType The MIME type name (e.g., "text/html").
*
* @return True if MIME type is detectable.
* @return True or false.
*/
private boolean isDetectableByTika(String mimeType) {
String[] split = mimeType.split("/");
@@ -112,70 +130,70 @@ public class FileTypeDetector {
}
/**
* Look up the MIME type of a file using the blackboard. If it is not
* already posted, detect the type of the file, posting it to the blackboard
* if detection succeeds.
* 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.
*
* @param file The file to test.
* IMPORTANT: This method should not be called except by ingest modules; all
* other clients should call AbstractFile.getMIMEType, and may call
* FileTypeDetector.detect, if AbstractFile.getMIMEType returns null.
*
* @return The MIME type name if detection was successful, null otherwise.
* @param file The file.
*
* @throws TskCoreException
*/
public String getFileType(AbstractFile file) throws TskCoreException {
String fileType = file.getMIMEType();
if (null != fileType) {
return fileType;
}
return detectAndPostToBlackboard(file);
}
/**
* Detect the MIME type of a file, posting it to the blackboard if detection
* succeeds. Note that this method should currently be called at most once
* per file.
* @return A MIME type name.
*
* @param file The file to test.
*
* @return The MIME type name id detection was successful, null otherwise.
*
* @throws TskCoreException
* @throws TskCoreException if detection is required and there is a problem
* writing the result to the case database.
*/
@SuppressWarnings("deprecation")
public String detectAndPostToBlackboard(AbstractFile file) throws TskCoreException {
String mimeType = detect(file);
public String getFileType(AbstractFile file) throws TskCoreException {
String mimeType = file.getMIMEType();
if (null != mimeType) {
/**
* Add the file type attribute to the general info artifact. Note
* that no property change is fired for this blackboard posting
* because general info artifacts are different from other
* artifacts, e.g., they are not displayed in the results tree.
*/
try {
file.setMIMEType(mimeType);
BlackboardArtifact getInfoArt = file.getGenInfoArtifact();
BlackboardAttribute batt = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG, FileTypeIdModuleFactory.getModuleName(), mimeType);
getInfoArt.addAttribute(batt);
} catch (TskDataException ex) {
//Swallowing exception so that the logs aren't clogged in the case that ingest is run multiple times.
}
return mimeType;
}
mimeType = detect(file);
Case.getCurrentCase().getSleuthkitCase().setFileMIMEType(file, mimeType);
/*
* Add the file type attribute to the general info artifact. Note that
* no property change is fired for this blackboard posting because
* general info artifacts are different from other artifacts, e.g., they
* are not displayed in the results tree.
*
* SPECIAL NOTE: Adding a file type attribute to the general info
* artifact is meant to be replaced by the use of the MIME type field of
* the AbstractFile class (tsk_files.mime_type in the case database).
* The attribute is still added here to support backward compatibility,
* but it introduces a check-then-act race condition that can lead to
* duplicate attributes. Various mitigation strategies were considered.
* It was decided to go with the policy that this method would not be
* called outside of ingest (see note in method docs), at least until
* such time as the attribute is no longer created.
*/
BlackboardArtifact getInfoArt = file.getGenInfoArtifact();
BlackboardAttribute batt = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG, FileTypeIdModuleFactory.getModuleName(), mimeType);
getInfoArt.addAttribute(batt);
return mimeType;
}
/**
* Detect the MIME type of a file.
* Detects the MIME type of a file. The result is not added to the case
* database.
*
* @param file The file to test.
*
* @return The MIME type name if detection was successful, null otherwise.
* @return A MIME type name. If file type could not be detected or results
* were uncertain, octet-stream is returned.
*
* @throws TskCoreException
*/
public String detect(AbstractFile file) throws TskCoreException {
// consistently mark non-regular files (refer TskData.TSK_FS_META_TYPE_ENUM),
// 0 sized files, unallocated, and unused blocks (refer TskData.TSK_DB_FILES_TYPE_ENUM)
// as octet-stream.
/*
* Mark non-regular files (refer to TskData.TSK_FS_META_TYPE_ENUM),
* zero-sized files, unallocated space, and unused blocks (refer to
* TskData.TSK_DB_FILES_TYPE_ENUM) as octet-stream.
*/
if (!file.isFile() || file.getSize() <= 0
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
@@ -183,8 +201,15 @@ public class FileTypeDetector {
return MimeTypes.OCTET_STREAM;
}
String fileType = detectUserDefinedType(file);
if (null == fileType) {
/*
* Give precedence to user-defined types.
*/
String mimeType = detectUserDefinedType(file);
if (null == mimeType) {
/*
* The file does not match a user-defined type. Send the initial
* bytes to Tika.
*/
try {
byte buf[];
int len = file.read(buffer, 0, BUFFER_SIZE);
@@ -194,24 +219,25 @@ public class FileTypeDetector {
} else {
buf = buffer;
}
String tikaType = tika.detect(buf, file.getName());
String mimetype = tika.detect(buf, file.getName());
/**
* Strip out any Tika enhancements to the MIME type name.
/*
* Remove the Tika suffix from the MIME type name.
*/
return mimetype.replace("tika-", ""); //NON-NLS
mimeType = tikaType.replace("tika-", ""); //NON-NLS
} catch (Exception ignored) {
/**
* This exception is swallowed rather than propagated because
* files in images are not always consistent with their file
* system meta data making for read errors, and Tika can be a
* bit flaky at times, making this a best effort endeavor.
/*
* This exception is swallowed and not logged rather than
* propagated because files in data sources are not always
* consistent with their file system metadata, making for read
* errors. Also, Tika can be a bit flaky at times, making this a
* best effort endeavor. Default to octet-stream.
*/
mimeType = MimeTypes.OCTET_STREAM;
}
}
return fileType;
return mimeType;
}
/**
@@ -230,21 +256,26 @@ public class FileTypeDetector {
for (FileType fileType : userDefinedFileTypes) {
if (fileType.matches(file)) {
if (fileType.alertOnMatch()) {
/*
* Create an interesting file hit artifact.
*/
BlackboardArtifact artifact;
artifact = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, FileTypeIdModuleFactory.getModuleName(), fileType.getFilesSetName());
artifact.addAttribute(setNameAttribute);
/**
* Use the MIME type as the category, i.e., the rule that
* determined this file belongs to the interesting files
* set.
/*
* Use the MIME type as the category attribute, i.e., the
* rule that determined this file belongs to the interesting
* files set.
*/
BlackboardAttribute ruleNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, FileTypeIdModuleFactory.getModuleName(), fileType.getMimeType());
artifact.addAttribute(ruleNameAttribute);
/*
* Index the artifact for keyword search.
*/
try {
// index the artifact for keyword search
Case.getCurrentCase().getServices().getBlackboard().indexArtifact(artifact);
} catch (Blackboard.BlackboardException | IllegalStateException ex) {
logger.log(Level.SEVERE, String.format("Unable to index blackboard artifact %d", artifact.getArtifactID()), ex); //NON-NLS
@@ -258,30 +289,54 @@ public class FileTypeDetector {
return null;
}
/*
* Exception thrown when a file type detector experiences an error
* condition.
*/
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.
*
* @param message The exception message,
*/
FileTypeDetectorInitException(String message) {
super(message);
}
/**
* Constructs an exception to throw when a file type detector
* experiences an error condition.
*
* @param message The exception message,
* @param throwable The underlying cause of the exception.
*/
FileTypeDetectorInitException(String message, Throwable throwable) {
super(message, throwable);
}
}
/**
* Gets the list of user defined file types (MIME types)
* 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.
*
* @return the List<String> of user defined file types
* @param file The file.
*
* @return A MIME type name.
*
* @throws TskCoreException if detection is required and there is a problem
* writing the result to the case database.
* @deprecated Use getFileType instead and use AbstractFile.getMIMEType
* instead of querying the blackboard.
*/
public List<String> getUserDefinedTypes() {
List<String> list = new ArrayList<>();
if (userDefinedFileTypes != null) {
for (FileType fileType : userDefinedFileTypes) {
list.add(fileType.getMimeType());
}
}
return list;
@Deprecated
@SuppressWarnings("deprecation")
public String detectAndPostToBlackboard(AbstractFile file) throws TskCoreException {
return getFileType(file);
}
}
@@ -95,10 +95,9 @@
</Group>
</Group>
</Group>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace pref="28" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
@@ -107,7 +106,6 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@@ -167,7 +165,7 @@
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="saveTypeButton" linkSize="2" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<EmptySpace min="0" pref="21" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
@@ -426,18 +424,6 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="jLabel1" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
@@ -84,7 +84,9 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
* Does child component initialization in addition to that done by the
* Matisse generated code.
*/
@NbBundle.Messages({"FileTypeIdGlobalSettingsPanel.Title=Global File Type Identification Settings"})
private void customizeComponents() {
setName(Bundle.FileTypeIdGlobalSettingsPanel_Title());
setFileTypesListModel();
setSignatureTypeComboBoxModel();
setOffsetRealtiveToComboBoxModel();
@@ -352,7 +354,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private void initComponents() {
typesScrollPane = new javax.swing.JScrollPane();
typesList = new javax.swing.JList<>();
typesList = new javax.swing.JList<FileType>();
separator = new javax.swing.JSeparator();
mimeTypeLabel = new javax.swing.JLabel();
mimeTypeTextField = new javax.swing.JTextField();
@@ -364,16 +366,15 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
deleteTypeButton = new javax.swing.JButton();
saveTypeButton = new javax.swing.JButton();
hexPrefixLabel = new javax.swing.JLabel();
signatureTypeComboBox = new javax.swing.JComboBox<>();
signatureTypeComboBox = new javax.swing.JComboBox<String>();
signatureLabel = new javax.swing.JLabel();
postHitCheckBox = new javax.swing.JCheckBox();
filesSetNameLabel = new javax.swing.JLabel();
filesSetNameTextField = new javax.swing.JTextField();
ingestRunningWarningLabel = new javax.swing.JLabel();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
offsetRelativeToComboBox = new javax.swing.JComboBox<>();
offsetRelativeToComboBox = new javax.swing.JComboBox<String>();
offsetRelativeToLabel = new javax.swing.JLabel();
setMaximumSize(new java.awt.Dimension(500, 300));
@@ -464,9 +465,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
ingestRunningWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/filetypeid/warning16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(ingestRunningWarningLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.ingestRunningWarningLabel.text")); // NOI18N
jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel1.text")); // NOI18N
jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel2.text")); // NOI18N
@@ -538,15 +536,13 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addComponent(offsetRelativeToLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addComponent(jLabel1)
.addComponent(jLabel3))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap(28, Short.MAX_VALUE))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addContainerGap()
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -594,7 +590,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(saveTypeButton)
.addGap(0, 0, Short.MAX_VALUE))))
.addGap(0, 21, Short.MAX_VALUE))))
);
layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deleteTypeButton, newTypeButton, saveTypeButton});
@@ -735,7 +731,6 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private javax.swing.JTextField filesSetNameTextField;
private javax.swing.JLabel hexPrefixLabel;
private javax.swing.JLabel ingestRunningWarningLabel;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel mimeTypeLabel;
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="skipKnownCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="46" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
<Component id="skipKnownCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="86" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="skipKnownCheckBox">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="skipKnownCheckBoxActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>
@@ -1,99 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 - 2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.filetypeid;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/**
* UI component used to set ingest job options for file type identifier ingest
* modules.
*/
class FileTypeIdIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel {
private final FileTypeIdModuleSettings settings;
FileTypeIdIngestJobSettingsPanel(FileTypeIdModuleSettings settings) {
this.settings = settings;
initComponents();
customizeComponents();
}
/**
* @inheritDoc
*/
@Override
public IngestModuleIngestJobSettings getSettings() {
return settings;
}
/**
* Does child component initialization in addition to that done by the
* Matisse generated code.
*/
private void customizeComponents() {
skipKnownCheckBox.setSelected(settings.skipKnownFiles());
}
/**
* 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
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
skipKnownCheckBox = new javax.swing.JCheckBox();
skipKnownCheckBox.setSelected(true);
skipKnownCheckBox.setText(org.openide.util.NbBundle.getMessage(FileTypeIdIngestJobSettingsPanel.class, "FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.text")); // NOI18N
skipKnownCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(FileTypeIdIngestJobSettingsPanel.class, "FileTypeIdIngestJobSettingsPanel.skipKnownCheckBox.toolTipText")); // NOI18N
skipKnownCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
skipKnownCheckBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(skipKnownCheckBox)
.addContainerGap(46, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(11, 11, 11)
.addComponent(skipKnownCheckBox)
.addContainerGap(86, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void skipKnownCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_skipKnownCheckBoxActionPerformed
settings.setSkipKnownFiles(skipKnownCheckBox.isSelected());
}//GEN-LAST:event_skipKnownCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox skipKnownCheckBox;
// End of variables declaration//GEN-END:variables
}
@@ -27,7 +27,6 @@ import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskData.FileKnown;
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
@@ -38,7 +37,6 @@ import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
public class FileTypeIdIngestModule implements FileIngestModule {
private static final Logger logger = Logger.getLogger(FileTypeIdIngestModule.class.getName());
private final FileTypeIdModuleSettings settings;
private long jobId;
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
@@ -66,11 +64,8 @@ public class FileTypeIdIngestModule implements FileIngestModule {
/**
* Creates an ingest module that detects the type of a file based on
* signature (magic) values. Posts results to the blackboard.
*
* @param settings The ingest module settings.
*/
FileTypeIdIngestModule(FileTypeIdModuleSettings settings) {
this.settings = settings;
FileTypeIdIngestModule() {
}
/**
@@ -83,7 +78,7 @@ public class FileTypeIdIngestModule implements FileIngestModule {
try {
fileTypeDetector = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg"));
throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg"), ex);
}
}
@@ -93,13 +88,6 @@ public class FileTypeIdIngestModule implements FileIngestModule {
@Override
public ProcessResult process(AbstractFile file) {
/**
* Skip known files if configured to do so.
*/
if (settings.skipKnownFiles() && (file.getKnown() == FileKnown.KNOWN)) {
return ProcessResult.OK;
}
/**
* Attempt to detect the file type. Do it within an exception firewall,
* so that any issues with reading file content or complaints from tika
@@ -153,7 +141,7 @@ public class FileTypeIdIngestModule implements FileIngestModule {
* Update the match time total and increment number of files processed for
* this ingest job.
*
* @param jobId The ingest job identifier.
* @param jobId The ingest job identifier.
* @param matchTimeInc Amount of time to add.
*/
private static synchronized void addToTotals(long jobId, long matchTimeInc) {
@@ -26,7 +26,6 @@ import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
/**
* A factory that creates file ingest modules that determine the types of files.
@@ -92,35 +91,6 @@ public class FileTypeIdModuleFactory extends IngestModuleFactoryAdapter {
return globalSettingsPanel;
}
/**
* @inheritDoc
*/
@Override
public IngestModuleIngestJobSettings getDefaultIngestJobSettings() {
return new FileTypeIdModuleSettings();
}
/**
* @inheritDoc
*/
@Override
public boolean hasIngestJobSettingsPanel() {
return true;
}
/**
* @inheritDoc
*/
@Override
public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) {
assert settings instanceof FileTypeIdModuleSettings;
if (!(settings instanceof FileTypeIdModuleSettings)) {
throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(),
"FileTypeIdModuleFactory.getIngestJobSettingsPanel.exception.msg"));
}
return new FileTypeIdIngestJobSettingsPanel((FileTypeIdModuleSettings) settings);
}
/**
* @inheritDoc
*/
@@ -134,11 +104,6 @@ public class FileTypeIdModuleFactory extends IngestModuleFactoryAdapter {
*/
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
assert settings instanceof FileTypeIdModuleSettings;
if (!(settings instanceof FileTypeIdModuleSettings)) {
throw new IllegalArgumentException(
NbBundle.getMessage(this.getClass(), "FileTypeIdModuleFactory.createFileIngestModule.exception.msg"));
}
return new FileTypeIdIngestModule((FileTypeIdModuleSettings) settings);
return new FileTypeIdIngestModule();
}
}
}
@@ -1,56 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.filetypeid;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
/**
* Ingest job options for the file type identifier ingest module instances.
*/
// TODO: This class does not need to be public.
public class FileTypeIdModuleSettings implements IngestModuleIngestJobSettings {
private static final long serialVersionUID = 1L;
private boolean skipKnownFiles = true;
private boolean skipSmallFiles = false; // No longer used.
FileTypeIdModuleSettings() {
}
FileTypeIdModuleSettings(boolean skipKnownFiles) {
this.skipKnownFiles = skipKnownFiles;
}
/**
* @inheritDoc
*/
@Override
public long getVersionNumber() {
return serialVersionUID;
}
void setSkipKnownFiles(boolean enabled) {
skipKnownFiles = enabled;
}
boolean skipKnownFiles() {
return skipKnownFiles;
}
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -59,7 +59,6 @@ import org.xml.sax.SAXException;
final class UserDefinedFileTypesManager {
private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName());
private static final String FILE_TYPE_DEFINITIONS_SCHEMA_FILE = "FileTypes.xsd"; //NON-NLS
private static final String USER_DEFINED_TYPE_DEFINITIONS_FILE = "UserFileTypeDefinitions.xml"; //NON-NLS
private static final String FILE_TYPES_TAG_NAME = "FileTypes"; //NON-NLS
private static final String FILE_TYPE_TAG_NAME = "FileType"; //NON-NLS
@@ -72,7 +71,6 @@ final class UserDefinedFileTypesManager {
private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS
private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS
private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS
private static final String ASCII_ENCODING = "US-ASCII"; //NON-NLS
private static UserDefinedFileTypesManager instance;
/**
@@ -181,7 +179,7 @@ final class UserDefinedFileTypesManager {
private void loadPredefinedFileTypes() throws UserDefinedFileTypesException {
byte[] byteArray;
FileType fileType;
try {
// Add rule for xml
fileType = new FileType("text/xml", new Signature("<?xml", 0L), "", false); //NON-NLS
@@ -228,13 +226,12 @@ final class UserDefinedFileTypesManager {
fileTypes.add(fileType);
fileType = new FileType("image/x-portable-floatmap", new Signature("Pf", 0L), "", false); //NON-NLS
fileTypes.add(fileType);
// Add rule for .tga
byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS
fileType = new FileType("image/x-tga", new Signature(byteArray, 17, false), "", false); //NON-NLS
fileTypes.add(fileType);
}
// parseHexBinary() throws this if the argument passed in is not Hex
} // parseHexBinary() throws this if the argument passed in is not Hex
catch (IllegalArgumentException e) {
throw new UserDefinedFileTypesException("Error creating predefined file types", e); //
}
@@ -282,7 +279,7 @@ final class UserDefinedFileTypesManager {
* Sets the user-defined file types.
*
* @param newFileTypes A mapping of file type names to user-defined file
* types.
* types.
*/
synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
try {
@@ -317,7 +314,7 @@ final class UserDefinedFileTypesManager {
* Writes a set of file type definitions to an XML file.
*
* @param fileTypes A collection of file types.
* @param filePath The path to the destination file.
* @param filePath The path to the destination file.
*
* @throws ParserConfigurationException
* @throws IOException
@@ -340,7 +337,7 @@ final class UserDefinedFileTypesManager {
* Creates an XML representation of a file type.
*
* @param fileType The file type object.
* @param doc The WC3 DOM object to use to create the XML.
* @param doc The WC3 DOM object to use to create the XML.
*
* @return An XML element.
*/
@@ -356,9 +353,9 @@ final class UserDefinedFileTypesManager {
/**
* Add a MIME type child element to a file type XML element.
*
* @param fileType The file type to use as a content source.
* @param fileType The file type to use as a content source.
* @param fileTypeElem The parent file type element.
* @param doc The WC3 DOM object to use to create the XML.
* @param doc The WC3 DOM object to use to create the XML.
*/
private static void addMimeTypeElement(FileType fileType, Element fileTypeElem, Document doc) {
Element typeNameElem = doc.createElement(MIME_TYPE_TAG_NAME);
@@ -369,9 +366,9 @@ final class UserDefinedFileTypesManager {
/**
* Add a signature child element to a file type XML element.
*
* @param fileType The file type to use as a content source.
* @param fileType The file type to use as a content source.
* @param fileTypeElem The parent file type element.
* @param doc The WC3 DOM object to use to create the XML.
* @param doc The WC3 DOM object to use to create the XML.
*/
private static void addSignatureElement(FileType fileType, Element fileTypeElem, Document doc) {
Signature signature = fileType.getSignature();
@@ -393,9 +390,9 @@ final class UserDefinedFileTypesManager {
/**
* Add an interesting files set element to a file type XML element.
*
* @param fileType The file type to use as a content source.
* @param fileType The file type to use as a content source.
* @param fileTypeElem The parent file type element.
* @param doc The WC3 DOM object to use to create the XML.
* @param doc The WC3 DOM object to use to create the XML.
*/
private static void addInterestingFilesSetElement(FileType fileType, Element fileTypeElem, Document doc) {
if (!fileType.getFilesSetName().isEmpty()) {
@@ -408,13 +405,20 @@ final class UserDefinedFileTypesManager {
/**
* Add an alert attribute to a file type XML element.
*
* @param fileType The file type to use as a content source.
* @param fileType The file type to use as a content source.
* @param fileTypeElem The parent file type element.
*/
private static void addAlertAttribute(FileType fileType, Element fileTypeElem) {
fileTypeElem.setAttribute(ALERT_ATTRIBUTE, Boolean.toString(fileType.alertOnMatch()));
}
/**
* Private constructor suppresses creation of instanmces of this utility
* class.
*/
private XmlWriter() {
}
}
/**
@@ -432,7 +436,17 @@ final class UserDefinedFileTypesManager {
*/
private static List<FileType> readFileTypes(String filePath) throws IOException, ParserConfigurationException, SAXException {
List<FileType> fileTypes = new ArrayList<>();
Document doc = XMLUtil.loadDocument(filePath, UserDefinedFileTypesManager.class, FILE_TYPE_DEFINITIONS_SCHEMA_FILE);
/*
* RC: Commenting out the loadDocument overload that validates
* against the XSD is a temp fix for a failure to provide an upgrade
* path when the RelativeToStart attribute was added to the
* Signature element. The upgrade path can be supplied, but the plan
* is to replace the use of XML with object serialization for the
* settings, so it may not be worth the effort.
*/
// private static final String FILE_TYPE_DEFINITIONS_SCHEMA_FILE = "FileTypes.xsd"; //NON-NLS
// Document doc = XMLUtil.loadDocument(filePath, UserDefinedFileTypesManager.class, FILE_TYPE_DEFINITIONS_SCHEMA_FILE);
Document doc = XMLUtil.loadDocument(filePath);
if (doc != null) {
Element fileTypesElem = doc.getDocumentElement();
if (fileTypesElem != null && fileTypesElem.getNodeName().equals(FILE_TYPES_TAG_NAME)) {
@@ -496,14 +510,16 @@ final class UserDefinedFileTypesManager {
Element offsetElem = (Element) signatureElem.getElementsByTagName(OFFSET_TAG_NAME).item(0);
String offsetString = offsetElem.getTextContent();
long offset = DatatypeConverter.parseLong(offsetString);
String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
if(relativeString == null || relativeString.equals(""))
return new Signature(signatureBytes, offset, signatureType);
boolean isRelative = DatatypeConverter.parseBoolean(relativeString);
return new Signature(signatureBytes, offset, signatureType, isRelative);
boolean isRelativeToStart;
String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
if (null == relativeString || relativeString.equals("")) {
isRelativeToStart = true;
} else {
isRelativeToStart = DatatypeConverter.parseBoolean(relativeString);
}
return new Signature(signatureBytes, offset, signatureType, isRelativeToStart);
}
/**
@@ -538,7 +554,7 @@ final class UserDefinedFileTypesManager {
/**
* Gets the text content of a single child element.
*
* @param elem The parent element.
* @param elem The parent element.
* @param tagName The tag name of the child element.
*
* @return The text content or null if the tag doesn't exist.
@@ -546,21 +562,29 @@ final class UserDefinedFileTypesManager {
private static String getChildElementTextContent(Element elem, String tagName) {
NodeList childElems = elem.getElementsByTagName(tagName);
Node childNode = childElems.item(0);
if(childNode == null)
if (childNode == null) {
return null;
}
Element childElem = (Element) childNode;
return childElem.getTextContent();
}
/**
* Private constructor suppresses creation of instanmces of this utility
* class.
*/
private XmlReader() {
}
}
/**
* Logs an exception, bundles the exception with a simple message in a
* uniform exception type, and throws the wrapper exception.
*
* @param ex The exception to wrap.
* @param ex The exception to wrap.
* @param messageKey A key into the bundle file that maps to the desired
* message.
* message.
*
* @throws
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
@@ -578,6 +602,8 @@ final class UserDefinedFileTypesManager {
*/
static class UserDefinedFileTypesException extends Exception {
private static final long serialVersionUID = 1L;
UserDefinedFileTypesException(String message) {
super(message);
}
@@ -56,7 +56,6 @@ HashDatabaseOptionsPanelController.moduleErrMsg=A module caused an error listeni
HashDbConfigPanel.noSelectionText=No database selected
HashDbConfigPanel.errorGettingPathText=Error occurred getting path
HashDbConfigPanel.errorGettingIndexStatusText=Error occurred getting status
HashDbConfigPanel.setName.hashSetConfig=Hash Set Configuration
HashDbConfigPanel.indexButtonText.index=Index
HashDbConfigPanel.indexButtonText.indexing=Indexing
HashDbConfigPanel.indexStatusText.indexGen=Index is currently being generated
@@ -1,213 +1,212 @@
OpenIDE-Module-Display-Category=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB
OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
OpenIDE-Module-Long-Description=\
\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB \n\n\
\u30C7\u30A3\u30B9\u30AF\u30A4\u30E1\u30FC\u30B8\u306B\u3042\u308B\u30D5\u30A1\u30A4\u30EB\u3092\u89E3\u6790\u3057\u3001\u300C\u65E2\u77E5\u300D\uFF08NSRL\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u300C\u65E2\u77E5\u300D\u30D5\u30A1\u30A4\u30EB\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u3092\u57FA\u306B\uFF09\u307E\u305F\u306F\u300C\u60AA\u8CEA\uFF0F\u7591\u308F\u3057\u3044\u300D\uFF08\u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\u5358\u6570\u307E\u305F\u306F\u8907\u6570\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u57FA\u306B\uFF09\u3068\u30DE\u30FC\u30AF\u3057\u307E\u3059\u3002\n\n\
\u30CF\u30C3\u30B7\u30E5\u3084\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u8A2D\u5B9A\u306B\u57FA\u3065\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u306A\u3069\u3001\u3053\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u306FGUI\u306B\u9023\u643A\u3057\u3066\u3044\u308B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3057\u306A\u3044\u3001\u8FFD\u52A0\u306E\u30C4\u30FC\u30EB\u304C\u542B\u307E\u308C\u307E\u3059\u3002
OpenIDE-Module-Name=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbSearchPanel.hashTable.columnModel.title0=MD5\u30CF\u30C3\u30B7\u30E5
HashDbSearchPanel.addButton.text=\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
HashDbSearchPanel.hashLabel.text=MD5\u30CF\u30C3\u30B7\u30E5\uFF1A
HashDbSearchPanel.searchButton.text=\u691C\u7D22
HashDbSearchPanel.removeButton.text=\u9078\u629E\u3057\u305F\u3082\u306E\u3092\u524A\u9664
HashDbSearchPanel.titleLabel.text=\u6B21\u306EMD5\u30CF\u30C3\u30B7\u30E5\u4ED8\u304D\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\uFF1A
HashDbSearchPanel.errorField.text=\u30A8\u30E9\u30FC\uFF1A\u5168\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u30CF\u30C3\u30B7\u30E5\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002
HashDbSearchPanel.saveBox.text=\u30CF\u30C3\u30B7\u30E5\u3092\u8A18\u61B6
HashDbSearchPanel.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
OpenIDE-Module-Short-Description=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u304A\u3088\u3073\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30C4\u30FC\u30EB
HashDbImportDatabaseDialog.jLabel1.text=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\uFF1A
HashDbImportDatabaseDialog.knownBadRadioButton.text=\u65E2\u77E5\u306E\u60AA\u8CEA
HashDbImportDatabaseDialog.jLabel2.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30BF\u30A4\u30D7\uFF1A
\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb \n\n\
\u30c7\u30a3\u30b9\u30af\u30a4\u30e1\u30fc\u30b8\u306b\u3042\u308b\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u3057\u3001\u300c\u65e2\u77e5\u300d\uff08NSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u300c\u65e2\u77e5\u300d\u30d5\u30a1\u30a4\u30eb\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u57fa\u306b\uff09\u307e\u305f\u306f\u300c\u60aa\u8cea\uff0f\u7591\u308f\u3057\u3044\u300d\uff08\u30e6\u30fc\u30b6\u30fc\u304c\u6307\u5b9a\u3057\u305f\u5358\u6570\u307e\u305f\u306f\u8907\u6570\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u57fa\u306b\uff09\u3068\u30de\u30fc\u30af\u3057\u307e\u3059\u3002\n\n\
\u30cf\u30c3\u30b7\u30e5\u3084\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a\u306b\u57fa\u3065\u3044\u305f\u30d5\u30a1\u30a4\u30eb\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u306a\u3069\u3001\u3053\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u306fGUI\u306b\u9023\u643a\u3057\u3066\u3044\u308b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3057\u306a\u3044\u3001\u8ffd\u52a0\u306e\u30c4\u30fc\u30eb\u304c\u542b\u307e\u308c\u307e\u3059\u3002
OpenIDE-Module-Name=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbSearchPanel.hashTable.columnModel.title0=MD5\u30cf\u30c3\u30b7\u30e5
HashDbSearchPanel.addButton.text=\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
HashDbSearchPanel.hashLabel.text=MD5\u30cf\u30c3\u30b7\u30e5\uff1a
HashDbSearchPanel.searchButton.text=\u691c\u7d22
HashDbSearchPanel.removeButton.text=\u9078\u629e\u3057\u305f\u3082\u306e\u3092\u524a\u9664
HashDbSearchPanel.titleLabel.text=\u6b21\u306eMD5\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\uff1a
HashDbSearchPanel.errorField.text=\u30a8\u30e9\u30fc\uff1a\u5168\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u30cf\u30c3\u30b7\u30e5\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002
HashDbSearchPanel.saveBox.text=\u30cf\u30c3\u30b7\u30e5\u3092\u8a18\u61b6
HashDbSearchPanel.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
OpenIDE-Module-Short-Description=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u304a\u3088\u3073\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c4\u30fc\u30eb
HashDbImportDatabaseDialog.jLabel1.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\uff1a
HashDbImportDatabaseDialog.knownBadRadioButton.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbImportDatabaseDialog.jLabel2.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30bf\u30a4\u30d7\uff1a
HashDbImportDatabaseDialog.okButton.text=OK
HashDbImportDatabaseDialog.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
HashDbCreateDatabaseDialog.jLabel2.text=\u30BF\u30A4\u30D7\uFF1A
HashDbCreateDatabaseDialog.knownBadRadioButton.text=\u65E2\u77E5\u306E\u60AA\u8CEA
HashDbCreateDatabaseDialog.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB
ModalNoButtons.CURRENTLYON_LABEL.text=y\u306Ex\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.GO_GET_COFFEE_LABEL.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D\u3067\u3059\u3002\u6642\u9593\u304C\u304B\u304B\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002
ModalNoButtons.CANCEL_BUTTON.text=\u30AD\u30E3\u30F3\u30BB\u30EB
HashDbImportDatabaseDialog.knownRadioButton.text=\u65E2\u77E5\uFF08NSRL\u307E\u305F\u306F\u305D\u306E\u4ED6\uFF09
HashDbCreateDatabaseDialog.knownRadioButton.text=\u65E2\u77E5
HashDbCreateDatabaseDialog.jLabel1.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\uFF1A
HashDbCreateDatabaseDialog.saveAsButton.text=\u540D\u524D\u3092\u3064\u3051\u3066\u4FDD\u5B58\u2026
HashDbImportDatabaseDialog.jLabel3.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\uFF1A
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=\u30D2\u30C3\u30C8\u6BCE\u306B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u9001\u308B
HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=\u30D2\u30C3\u30C8\u6BCE\u306B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u9001\u308B
HashDbImportDatabaseDialog.openButton.text=\u958B\u304F...
HashDbCreateDatabaseDialog.jLabel3.text=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\uFF1A
HashDbImportDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbCreateDatabaseDialog.jLabel2.text=\u30bf\u30a4\u30d7\uff1a
HashDbCreateDatabaseDialog.knownBadRadioButton.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbCreateDatabaseDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb
ModalNoButtons.CURRENTLYON_LABEL.text=y\u306ex\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.GO_GET_COFFEE_LABEL.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u3067\u3059\u3002\u6642\u9593\u304c\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002
ModalNoButtons.CANCEL_BUTTON.text=\u30ad\u30e3\u30f3\u30bb\u30eb
HashDbImportDatabaseDialog.knownRadioButton.text=\u65e2\u77e5\uff08NSRL\u307e\u305f\u306f\u305d\u306e\u4ed6\uff09
HashDbCreateDatabaseDialog.knownRadioButton.text=\u65e2\u77e5
HashDbCreateDatabaseDialog.jLabel1.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashDbCreateDatabaseDialog.saveAsButton.text=\u540d\u524d\u3092\u3064\u3051\u3066\u4fdd\u5b58\u2026
HashDbImportDatabaseDialog.jLabel3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashDbCreateDatabaseDialog.sendIngestMessagesCheckbox.text=\u30d2\u30c3\u30c8\u6bce\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashDbImportDatabaseDialog.sendIngestMessagesCheckbox.text=\u30d2\u30c3\u30c8\u6bce\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashDbImportDatabaseDialog.openButton.text=\u958b\u304f...
HashDbCreateDatabaseDialog.jLabel3.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\uff1a
HashDbCreateDatabaseDialog.okButton.text=OK
AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
AddContentToHashDbAction.ContentMenu.createDbItem=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4F5C\u6210...
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr1.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A8\u30E9\u30FC\u306B\u8FFD\u52A0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr2.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A8\u30E9\u30FC\u306B\u8FFD\u52A0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr3.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A8\u30E9\u30FC\u306B\u8FFD\u52A0
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B{0}\u3092\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileSzMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B{0}\u3092\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30CF\u30C3\u30B7\u30E5\u304C\u8A08\u7B97\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u9069\u5207\u306A\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u8A2D\u5B9A\u3057\u3001\u5B9F\u884C\u3057\u3066\u4E0B\u3055\u3044\u3002
HashDatabaseOptionsPanelController.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
HashDatabaseOptionsPanelController.moduleErrMsg=HashDatabaseOptionsPanelController\u306E\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u5B8C\u5168\u3067\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
HashDbConfigPanel.noSelectionText=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashDbConfigPanel.errorGettingPathText=\u30D1\u30B9\u306E\u53D6\u5F97\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
HashDbConfigPanel.errorGettingIndexStatusText=\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u78BA\u8A8D\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
HashDbConfigPanel.setName.hashSetConfig=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u8A2D\u5B9A
HashDbConfigPanel.indexButtonText.index=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9
HashDbConfigPanel.indexButtonText.indexing=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
HashDbConfigPanel.indexStatusText.indexGen=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3092\u4F5C\u6210\u4E2D\u3067\u3059
HashDbConfigPanel.indexStatusText.indexOnly=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306E\u307F
HashDbConfigPanel.indexStatusText.indexed=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u6E08\u307F
HashDbConfigPanel.indexButtonText.reIndex=\u518D\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9
HashDbConfigPanel.indexStatusText.noIndex=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u7121\u3057
HashDbConfigPanel.dbsNotIndexedMsg=\u6B21\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3057\u307E\u3059\u304B\uFF1F\n {0}
HashDbConfigPanel.unindexedDbsMsg=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbConfigPanel.allUnindexedDbsRmFromListMsg=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u30EA\u30B9\u30C8\u304B\u3089\u524A\u9664\u3055\u308C\u307E\u3059
HashDbConfigPanel.nameColLbl=\u540D\u524D
HashDbConfigPanel.editingCellsNotSupportedMsg=\u30BB\u30EB\u306F\u7DE8\u96C6\u4E0D\u53EF\u3067\u3059
HashDbConfigPanel.deleteDbActionConfirmMsg=\u5168\u3066\u306E\u30B1\u30FC\u30B9\u306B\u304A\u3051\u308B\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u524A\u9664\u3057\u307E\u3059\u3002\u5B9F\u884C\u3057\u307E\u3059\u304B\uFF1F
HashDbConfigPanel.deleteDbActionMsg=\u8A2D\u5B9A\u304B\u3089\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u524A\u9664
HashDbCreateDatabaseDialog.createHashDbMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4F5C\u6210
HashDbCreateDatabaseDialog.hashDbMustHaveFileExtensionMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u306F .{0} \u306E\u62E1\u5F35\u5B50\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.fileNameErr=\u30D5\u30A1\u30A4\u30EB\u540D\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.fileNameAlreadyExistsMsg=\u540C\u540D\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u8A2D\u5B9A\u3057\u3066\u4E0B\u3055\u3044\u3002
HashDbCreateDatabaseDialog.fileExistsErr=\u30D5\u30A1\u30A4\u30EB\u304C\u65E2\u306B\u5B58\u5728\u3057\u3066\u3044\u308B\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.mustEnterHashSetNameMsg=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\u306E\u5165\u529B\u304C\u5FC5\u8981\u3067\u3059
HashDbCreateDatabaseDialog.createHashDbErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u4F5C\u6210\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.mustEnterHashDbPathMsg=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\u306E\u5165\u529B\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.errMsg.hashDbCreationErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u4F5C\u6210\u30A8\u30E9\u30FC
HashDbCreateDatabaseDialog.cannotCreateFileAtLocMsg=\u6307\u5B9A\u3055\u308C\u305F\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\u3067\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002
HashDbCreateDatabaseDialog.failedToCreateHashDbMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
HashDbImportDatabaseDialog.importHashDbMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashDbImportDatabaseDialog.fileNameExtFilter.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB
HashDbImportDatabaseDialog.failedToGetDbPathMsg=\u9078\u629E\u3057\u305F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30D1\u30B9\u306E\u5165\u624B\u3092\u5931\u6557\u3057\u307E\u3057\u305F\u3002
HashDbImportDatabaseDialog.importHashDbErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A8\u30E9\u30FC\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30D5\u30A1\u30A4\u30EB\u30D1\u30B9\u306E\u9078\u629E\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629E\u3055\u308C\u305F\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u5B58\u5728\u3057\u307E\u305B\u3093\u3002
HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u958B\u304F\u306E\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.moduleName=\u30CF\u30C3\u30B7\u30E5\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7
HashDbIngestModule.moduleDescription=\u6A19\u6E96\u306ENSRL\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306A\u3069\u3001\u63D0\u4F9B\u3055\u308C\u305F\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u5229\u7528\u3057\u3066\u3001\u65E2\u77E5\u307E\u305F\u306F\u7591\u308F\u3057\u3044\u3082\u306E\u3092\u691C\u77E5\u3057\u307E\u3059\u3002
HashDbIngestModule.noKnownHashDbSetMsg=\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002
HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65E2\u77E5\u306E\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\u304C\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002
HashDbIngestModule.noKnownBadHashDbSetMsg=\u65E2\u77E5\u306E\u60AA\u8CEA\u306A\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30BB\u30C3\u30C8\u306F\u3042\u308A\u307E\u305B\u3093\u3002
HashDbConfigPanel.dbNotIndexedMsg=\u6B21\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3057\u307E\u3059\u304B\uFF1F\n{0}
HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65E2\u77E5\u306E\u60AA\u8CEA\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\u306F\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002
HashDbIngestModule.fileReadErrorMsg=\u8AAD\u307F\u8FBC\u307F\u30A8\u30E9\u30FC\uFF1A {0}
HashDbIngestModule.calcHashValueErr={0}\u306E\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u8A08\u7B97\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.hashLookupErrorMsg=\u30CF\u30C3\u30B7\u30E5\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u30A8\u30E9\u30FC\uFF1A {0}
HashDbIngestModule.settingKnownBadStateErr={0}\u306E\u65E2\u77E5\u306E\u60AA\u8CEA\u30B9\u30C6\u30FC\u30BF\u30B9\u3092\u8A2D\u5B9A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306E\u65E2\u77E5\u306E\u60AA\u8CEA\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306E\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashDbIngestModule.postToBB.fileName=\u30D5\u30A1\u30A4\u30EB\u540D
HashDbIngestModule.postToBB.md5Hash=MD5\u30CF\u30C3\u30B7\u30E5
HashDbIngestModule.postToBB.hashsetName=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D
HashDbIngestModule.postToBB.knownBadMsg=\u65E2\u77E5\u306E\u60AA\u8CEA\: {0}
HashDbIngestModule.complete.knownBadsFound=\u767A\u898B\u3055\u308C\u305F\u65E2\u77E5\u306E\u60AA\u8CEA\uFF1A
HashDbIngestModule.complete.totalCalcTime=\u8A08\u7B97\u6642\u9593\u306E\u5408\u8A08
HashDbIngestModule.complete.totalLookupTime=\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u6642\u9593\u306E\u5408\u8A08
HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\uFF1A
HashDbIngestModule.complete.hashLookupResults=\u30CF\u30C3\u30B7\u30E5\u30EB\u30C3\u30AF\u30A2\u30C3\u30D7\u7D50\u679C
HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u539F\u56E0\u306A\u306E\u304B\u3092\u30ED\u30B0\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u5B8C\u5168\u3067\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002
HashDbManager.replacingDuplicateHashsetNameMsg=\u91CD\u8907\u306E\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D {0} \u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002\n {1}\u306B\u66F8\u304D\u63DB\u3048\u307E\u3059\u3002
HashDbManager.openHashDbErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u958B\u304F\u30A8\u30E9\u30FC
HashDbManager.unableToOpenHashDbMsg=\ {0} \u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u958B\u3051\u307E\u305B\u3093\u3002
HashDbManager.savedBackupOfOldConfigMsg={0}\n\u53E4\u3044\u8A2D\u5B9A\u306E\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u30B3\u30D4\u30FC\u304C\u6B21\u306E\u901A\u308A\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F\u3002\n{1}
HashDbManager.baseMessage.updatedFormatHashDbConfig=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306E\u5F62\u5F0F\u304C\u66F4\u65B0\u3055\u308C\u307E\u3057\u305F\u3002
HashDbManager.msgBoxTitle.confFileFmtChanged=\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u306E\u5909\u66F4\u5B8C\u4E86
HashDbManager.dlgMsg.dbNotFoundAtLoc=\ {0} \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u6B21\u306E\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\u306B\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\n {1}\n \u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3057\u307E\u3059\u304B\uFF1F
HashDbManager.dlgTitle.MissingDb=\u6B20\u843D\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbManager.progress.indexingHashSet=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D {0}
HashDbManager.dlgMsg.errorIndexingHashSet=\ {0} \u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D\u306E\u30A8\u30E9\u30FC
HashDbManager.hashDbIndexingErr=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D\u306E\u30A8\u30E9\u30FC
HashDbPanelSearchAction.actionName=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u57FA\u3065\u304F\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
HashDbSearchAction.dlgMsg.noFilesHaveMD5Calculated=MD5\u30CF\u30C3\u30B7\u30E5\u304C\u8A08\u7B97\u3055\u308C\u3066\u3044\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u307E\u305A\u306FHashDB\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3057\u3066\u4E0B\u3055\u3044\u3002
HashDbSearchManager.MD5HashSearch=MD5\u30CF\u30C3\u30B7\u30E5\u691C\u7D22
HashDbSearchManager.noResultsFoundMsg=\u4E00\u81F4\u3059\u308B\u3082\u306E\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
HashDbSearchPanel.titleText.ingestOngoing=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u4E2D\uFF1B\u5B8C\u4E86\u3059\u308B\u307E\u3067\u3053\u306E\u30B5\u30FC\u30D3\u30B9\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
HashDbSearchPanel.noFilesHaveMD5HashMsg=MD5\u30CF\u30C3\u30B7\u30E5\u4ED8\u304D\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093\u3002
HashDbSearchPanel.errorText.noHashesAddedMsg=\u30A8\u30E9\u30FC\uFF1A\u30CF\u30C3\u30B7\u30E5\u304C\u8FFD\u52A0\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
HashDbSearchPanel.errorText.hashAlreadyAddedMsg=\u30A8\u30E9\u30FC\uFF1A\u30CF\u30C3\u30B7\u30E5\u304C\u65E2\u306B\u8FFD\u52A0\u3055\u308C\u3066\u3044\u307E\u3059\u3002
HashDbSearchPanel.errorText.invalidMD5HashMsg=\u30A8\u30E9\u30FC\uFF1A\u6709\u52B9\u306AMD5\u30CF\u30C3\u30B7\u30E5\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
HashDbSearchThread.progress.cancellingSearch={0}\uFF08\u30AD\u30E3\u30F3\u30BB\u30EB\u4E2D\u2026\uFF09
HashDbSearchThread.name.searching=\u691C\u7D22\u4E2D
HashDbSearchThread.noMoreFilesWithMD5Msg=\u540C\u3058MD5\u30CF\u30C3\u30B7\u30E5\u4ED8\u304D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u4ED6\u306B\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002
ModalNoButtons.indexingDbsTitle=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.indexingDbTitle=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.exitHashDbIndexingMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3092\u4E2D\u6B62\u3057\u307E\u3059\u3002\n\
\u4F5C\u6210\u3055\u308C\u305F\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306F\u5229\u7528\u4E0D\u53EF\u3068\u306A\u308A\u307E\u3059\u3002\u7D9A\u884C\u3059\u308B\u5834\u5408\u306F\n\
\u30CF\u30C3\u30B7\u30E5\u30D5\u30A9\u30EB\u30C0\u5185\u306B\u3042\u308B\u3001\u5BFE\u5FDC\u3059\u308B-md5.idx \u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664\u3057\u3066\u4E0B\u3055\u3044\u3002\n\
\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u3092\u4E2D\u6B62\u3057\u307E\u3059\u304B\uFF1F
ModalNoButtons.dlgTitle.unfinishedIndexing=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u672A\u5B8C\u4E86
ModalNoButtons.indexThis.currentlyIndexing1Db=\uFF11\u3064\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=\uFF11\uFF0F {0}\u3064\u76EE\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
ModalNoButtons.propChg.currentlyIndexingXofN={0}\uFF0F {1}\u3064\u76EE\u3092\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u5316\u4E2D
HashDbManager.duplicateHashSetNameExceptionMsg=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D''{0}''\u306F\u65E2\u306B\u5225\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u4F7F\u308F\u308C\u3066\u3044\u307E\u3059\u3002
HashDbManager.hashDbDoesNotExistExceptionMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u6B21\u3067\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\n{0}
HashDbManager.hashDbFileExistsExceptionMsg=\u65E2\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u6B21\u306B\u5B58\u5728\u3057\u307E\u3059\n{0}
HashDbManager.hashDbAlreadyAddedExceptionMsg=\u6B21\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\n{0}\n\u306F\u65E2\u306B\u4F5C\u6210\u307E\u305F\u306F\u30A4\u30F3\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\u3002
HashDbManager.illegalHashDbFileNameExtensionMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u540D\u306F.{0}\u306E\u62E1\u5F35\u5B50\u304C\u5FC5\u8981\u3067\u3059\u3002
HashDbManager.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC
HashDbManager.knownBad.text=\u65E2\u77E5\u306E\u60AA\u8CEA
HashDbManager.known.text=\u65E2\u77E5
HashDbManager.fileNameExtensionFilter.title=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB
HashDbSearchAction.dlgMsg.title=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u57FA\u3065\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
HashDbSearchAction.getName.text=\u30CF\u30C3\u30B7\u30E5\u691C\u7D22
HashDbSearchPanel.dlgMsg.title=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u57FA\u3065\u304F\u30D5\u30A1\u30A4\u30EB\u691C\u7D22
AddContentToHashDbAction.singleSelectionName=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0
AddContentToHashDbAction.multipleSelectionName=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0
OptionsCategory_Name_HashDatabase=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
OptionsCategory_Keywords_HashDatabase=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9
HashDbManager.ingestRunningExceptionMsg=\u51E6\u7406\u4E2D\uFF1B\u5B8C\u4E86\u3059\u308B\u307E\u3067\u3053\u306E\u30B5\u30FC\u30D3\u30B9\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
ModalNoButtons.CURRENTDB_LABEL.text=\uFF08\u73FE\u5728\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\uFF09
HashDbCreateDatabaseDialog.defaultFileName=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8
HashDbManager.saveErrorExceptionMsg=\u30CF\u30C3\u30B7\u30E5\u8A2D\u5B9A\u306E\u4FDD\u5B58\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
AddContentToHashDbAction.addFilesToHashSet.files=\u30D5\u30A1\u30A4\u30EB
AddContentToHashDbAction.addFilesToHashSet.file=\u30D5\u30A1\u30A4\u30EB
HashDbManager.errCreatingIndex.title=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306E\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F
HashDbManager.errCreatingIndex.msg=\u6B21\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u306E\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF1A {0}
AddContentToHashDbAction.ContentMenu.noHashDbsConfigd=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
AddContentToHashDbAction.ContentMenu.createDbItem=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210...
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr1.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr2.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
AddContentToHashDbAction.addFilesToHashSet.addToHashDbErr3.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30e9\u30fc\u306b\u8ffd\u52a0
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileSzMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30cf\u30c3\u30b7\u30e5\u304c\u8a08\u7b97\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u9069\u5207\u306a\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u8a2d\u5b9a\u3057\u3001\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002
HashDatabaseOptionsPanelController.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
HashDatabaseOptionsPanelController.moduleErrMsg=HashDatabaseOptionsPanelController\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002
HashDbConfigPanel.noSelectionText=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashDbConfigPanel.errorGettingPathText=\u30d1\u30b9\u306e\u53d6\u5f97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
HashDbConfigPanel.errorGettingIndexStatusText=\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u78ba\u8a8d\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
HashDbConfigPanel.indexButtonText.index=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashDbConfigPanel.indexButtonText.indexing=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
HashDbConfigPanel.indexStatusText.indexGen=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3092\u4f5c\u6210\u4e2d\u3067\u3059
HashDbConfigPanel.indexStatusText.indexOnly=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u307f
HashDbConfigPanel.indexStatusText.indexed=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u6e08\u307f
HashDbConfigPanel.indexButtonText.reIndex=\u518d\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashDbConfigPanel.indexStatusText.noIndex=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u7121\u3057
HashDbConfigPanel.dbsNotIndexedMsg=\u6b21\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n {0}
HashDbConfigPanel.unindexedDbsMsg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbConfigPanel.allUnindexedDbsRmFromListMsg=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30ea\u30b9\u30c8\u304b\u3089\u524a\u9664\u3055\u308c\u307e\u3059
HashDbConfigPanel.nameColLbl=\u540d\u524d
HashDbConfigPanel.editingCellsNotSupportedMsg=\u30bb\u30eb\u306f\u7de8\u96c6\u4e0d\u53ef\u3067\u3059
HashDbConfigPanel.deleteDbActionConfirmMsg=\u5168\u3066\u306e\u30b1\u30fc\u30b9\u306b\u304a\u3051\u308b\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664\u3057\u307e\u3059\u3002\u5b9f\u884c\u3057\u307e\u3059\u304b\uff1f
HashDbConfigPanel.deleteDbActionMsg=\u8a2d\u5b9a\u304b\u3089\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664
HashDbCreateDatabaseDialog.createHashDbMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210
HashDbCreateDatabaseDialog.hashDbMustHaveFileExtensionMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306f .{0} \u306e\u62e1\u5f35\u5b50\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.fileNameErr=\u30d5\u30a1\u30a4\u30eb\u540d\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.fileNameAlreadyExistsMsg=\u540c\u540d\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002\u5225\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u8a2d\u5b9a\u3057\u3066\u4e0b\u3055\u3044\u3002
HashDbCreateDatabaseDialog.fileExistsErr=\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u3066\u3044\u308b\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.mustEnterHashSetNameMsg=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\u306e\u5165\u529b\u304c\u5fc5\u8981\u3067\u3059
HashDbCreateDatabaseDialog.createHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u4f5c\u6210\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.mustEnterHashDbPathMsg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\u306e\u5165\u529b\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbCreateDatabaseDialog.errMsg.hashDbCreationErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u4f5c\u6210\u30a8\u30e9\u30fc
HashDbCreateDatabaseDialog.cannotCreateFileAtLocMsg=\u6307\u5b9a\u3055\u308c\u305f\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002
HashDbCreateDatabaseDialog.failedToCreateHashDbMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
HashDbImportDatabaseDialog.importHashDbMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashDbImportDatabaseDialog.fileNameExtFilter.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
HashDbImportDatabaseDialog.failedToGetDbPathMsg=\u9078\u629e\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d1\u30b9\u306e\u5165\u624b\u3092\u5931\u6557\u3057\u307e\u3057\u305f\u3002
HashDbImportDatabaseDialog.importHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a8\u30e9\u30fc\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashDbImportDatabaseDialog.mustSelectHashDbFilePathMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u9078\u629e\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbImportDatabaseDialog.hashDbDoesNotExistMsg=\u9078\u629e\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
HashDbImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg={0}\u3067\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.moduleName=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7
HashDbIngestModule.moduleDescription=\u6a19\u6e96\u306eNSRL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u3001\u63d0\u4f9b\u3055\u308c\u305f\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u5229\u7528\u3057\u3066\u3001\u65e2\u77e5\u307e\u305f\u306f\u7591\u308f\u3057\u3044\u3082\u306e\u3092\u691c\u77e5\u3057\u307e\u3059\u3002
HashDbIngestModule.noKnownHashDbSetMsg=\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
HashDbIngestModule.knownFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u304c\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002
HashDbIngestModule.noKnownBadHashDbSetMsg=\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30bb\u30c3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002
HashDbConfigPanel.dbNotIndexedMsg=\u6b21\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3057\u307e\u3059\u304b\uff1f\n{0}
HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=\u65e2\u77e5\u306e\u60aa\u8cea\u30d5\u30a1\u30a4\u30eb\u691c\u7d22\u306f\u5b9f\u884c\u3055\u308c\u307e\u305b\u3093\u3002
HashDbIngestModule.fileReadErrorMsg=\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc\uff1a {0}
HashDbIngestModule.calcHashValueErr={0}\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.hashLookupErrorMsg=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u30a8\u30e9\u30fc\uff1a {0}
HashDbIngestModule.settingKnownBadStateErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u8a2d\u5b9a\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.lookingUpKnownBadHashValueErr={0}\u306e\u65e2\u77e5\u306e\u60aa\u8cea\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.lookingUpKnownHashValueErr={0}\u306e\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashDbIngestModule.postToBB.fileName=\u30d5\u30a1\u30a4\u30eb\u540d
HashDbIngestModule.postToBB.md5Hash=MD5\u30cf\u30c3\u30b7\u30e5
HashDbIngestModule.postToBB.hashsetName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d
HashDbIngestModule.postToBB.knownBadMsg=\u65e2\u77e5\u306e\u60aa\u8cea\: {0}
HashDbIngestModule.complete.knownBadsFound=\u767a\u898b\u3055\u308c\u305f\u65e2\u77e5\u306e\u60aa\u8cea\uff1a
HashDbIngestModule.complete.totalCalcTime=\u8a08\u7b97\u6642\u9593\u306e\u5408\u8a08
HashDbIngestModule.complete.totalLookupTime=\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u6642\u9593\u306e\u5408\u8a08
HashDbIngestModule.complete.databasesUsed=\u5229\u7528\u3057\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a
HashDbIngestModule.complete.hashLookupResults=\u30cf\u30c3\u30b7\u30e5\u30eb\u30c3\u30af\u30a2\u30c3\u30d7\u7d50\u679c
HashDbManager.moduleErrorListeningToUpdatesMsg=HashDbManager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u539f\u56e0\u306a\u306e\u304b\u3092\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u5b8c\u5168\u3067\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002
HashDbManager.replacingDuplicateHashsetNameMsg=\u91cd\u8907\u306e\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u3057\u305f\u3002\n {1}\u306b\u66f8\u304d\u63db\u3048\u307e\u3059\u3002
HashDbManager.openHashDbErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u304f\u30a8\u30e9\u30fc
HashDbManager.unableToOpenHashDbMsg=\ {0} \u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u958b\u3051\u307e\u305b\u3093\u3002
HashDbManager.savedBackupOfOldConfigMsg={0}\n\u53e4\u3044\u8a2d\u5b9a\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30b3\u30d4\u30fc\u304c\u6b21\u306e\u901a\u308a\u4fdd\u5b58\u3055\u308c\u307e\u3057\u305f\u3002\n{1}
HashDbManager.baseMessage.updatedFormatHashDbConfig=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u5f62\u5f0f\u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f\u3002
HashDbManager.msgBoxTitle.confFileFmtChanged=\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u306e\u5909\u66f4\u5b8c\u4e86
HashDbManager.dlgMsg.dbNotFoundAtLoc=\ {0} \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u6b21\u306e\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n {1}\n \u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3057\u307e\u3059\u304b\uff1f
HashDbManager.dlgTitle.MissingDb=\u6b20\u843d\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbManager.progress.indexingHashSet=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d {0}
HashDbManager.dlgMsg.errorIndexingHashSet=\ {0} \u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u306e\u30a8\u30e9\u30fc
HashDbManager.hashDbIndexingErr=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d\u306e\u30a8\u30e9\u30fc
HashDbPanelSearchAction.actionName=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
HashDbSearchAction.dlgMsg.noFilesHaveMD5Calculated=MD5\u30cf\u30c3\u30b7\u30e5\u304c\u8a08\u7b97\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002\u307e\u305a\u306fHashDB\u3092\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3057\u3066\u4e0b\u3055\u3044\u3002
HashDbSearchManager.MD5HashSearch=MD5\u30cf\u30c3\u30b7\u30e5\u691c\u7d22
HashDbSearchManager.noResultsFoundMsg=\u4e00\u81f4\u3059\u308b\u3082\u306e\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
HashDbSearchPanel.titleText.ingestOngoing=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\uff1b\u5b8c\u4e86\u3059\u308b\u307e\u3067\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashDbSearchPanel.noFilesHaveMD5HashMsg=MD5\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002
HashDbSearchPanel.errorText.noHashesAddedMsg=\u30a8\u30e9\u30fc\uff1a\u30cf\u30c3\u30b7\u30e5\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
HashDbSearchPanel.errorText.hashAlreadyAddedMsg=\u30a8\u30e9\u30fc\uff1a\u30cf\u30c3\u30b7\u30e5\u304c\u65e2\u306b\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u3059\u3002
HashDbSearchPanel.errorText.invalidMD5HashMsg=\u30a8\u30e9\u30fc\uff1a\u6709\u52b9\u306aMD5\u30cf\u30c3\u30b7\u30e5\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
HashDbSearchThread.progress.cancellingSearch={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
HashDbSearchThread.name.searching=\u691c\u7d22\u4e2d
HashDbSearchThread.noMoreFilesWithMD5Msg=\u540c\u3058MD5\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u4ed6\u306b\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002
ModalNoButtons.indexingDbsTitle=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.indexingDbTitle=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.exitHashDbIndexingMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3092\u4e2d\u6b62\u3057\u307e\u3059\u3002\n\
\u4f5c\u6210\u3055\u308c\u305f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f\u5229\u7528\u4e0d\u53ef\u3068\u306a\u308a\u307e\u3059\u3002\u7d9a\u884c\u3059\u308b\u5834\u5408\u306f\n\
\u30cf\u30c3\u30b7\u30e5\u30d5\u30a9\u30eb\u30c0\u5185\u306b\u3042\u308b\u3001\u5bfe\u5fdc\u3059\u308b-md5.idx \u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3057\u3066\u4e0b\u3055\u3044\u3002\n\
\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3092\u4e2d\u6b62\u3057\u307e\u3059\u304b\uff1f
ModalNoButtons.dlgTitle.unfinishedIndexing=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u672a\u5b8c\u4e86
ModalNoButtons.indexThis.currentlyIndexing1Db=\uff11\u3064\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=\uff11\uff0f {0}\u3064\u76ee\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
ModalNoButtons.propChg.currentlyIndexingXofN={0}\uff0f {1}\u3064\u76ee\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u4e2d
HashDbManager.duplicateHashSetNameExceptionMsg=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d''{0}''\u306f\u65e2\u306b\u5225\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u4f7f\u308f\u308c\u3066\u3044\u307e\u3059\u3002
HashDbManager.hashDbDoesNotExistExceptionMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u6b21\u3067\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\n{0}
HashDbManager.hashDbFileExistsExceptionMsg=\u65e2\u306b\u30d5\u30a1\u30a4\u30eb\u304c\u6b21\u306b\u5b58\u5728\u3057\u307e\u3059\n{0}
HashDbManager.hashDbAlreadyAddedExceptionMsg=\u6b21\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\n{0}\n\u306f\u65e2\u306b\u4f5c\u6210\u307e\u305f\u306f\u30a4\u30f3\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u3059\u3002
HashDbManager.illegalHashDbFileNameExtensionMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u540d\u306f.{0}\u306e\u62e1\u5f35\u5b50\u304c\u5fc5\u8981\u3067\u3059\u3002
HashDbManager.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
HashDbManager.knownBad.text=\u65e2\u77e5\u306e\u60aa\u8cea
HashDbManager.known.text=\u65e2\u77e5
HashDbManager.fileNameExtensionFilter.title=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb
HashDbSearchAction.dlgMsg.title=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u3044\u305f\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
HashDbSearchAction.getName.text=\u30cf\u30c3\u30b7\u30e5\u691c\u7d22
HashDbSearchPanel.dlgMsg.title=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u30d5\u30a1\u30a4\u30eb\u691c\u7d22
AddContentToHashDbAction.singleSelectionName=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u8ffd\u52a0
AddContentToHashDbAction.multipleSelectionName=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u8ffd\u52a0
OptionsCategory_Name_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
OptionsCategory_Keywords_HashDatabase=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9
HashDbManager.ingestRunningExceptionMsg=\u51e6\u7406\u4e2d\uff1b\u5b8c\u4e86\u3059\u308b\u307e\u3067\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
ModalNoButtons.CURRENTDB_LABEL.text=\uff08\u73fe\u5728\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff09
HashDbCreateDatabaseDialog.defaultFileName=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8
HashDbManager.saveErrorExceptionMsg=\u30cf\u30c3\u30b7\u30e5\u8a2d\u5b9a\u306e\u4fdd\u5b58\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
AddContentToHashDbAction.addFilesToHashSet.files=\u30d5\u30a1\u30a4\u30eb
AddContentToHashDbAction.addFilesToHashSet.file=\u30d5\u30a1\u30a4\u30eb
HashDbManager.errCreatingIndex.title=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
HashDbManager.errCreatingIndex.msg=\u6b21\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0}
HashLookupSettingsPanel.optionsLabel.text=\u30AA\u30D7\u30B7\u30E7\u30F3
HashLookupSettingsPanel.jButton3.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashLookupSettingsPanel.indexPathLabelLabel.text=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u30D1\u30B9\uFF1A
HashLookupSettingsPanel.createDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u4F5C\u6210
HashLookupSettingsPanel.jLabel6.text=\u30BF\u30A4\u30D7\uFF1A
HashLookupSettingsPanel.jLabel4.text=\u30ED\u30B1\u30FC\u30B7\u30E7\u30F3\uFF1A
HashLookupSettingsPanel.jLabel2.text=\u540D\u524D\uFF1A
HashLookupSettingsPanel.indexPathLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.ingestWarningLabel.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u4E2D\u3067\u3059\u3002\u5B8C\u4E86\u3059\u308B\u307E\u3067\u4E00\u90E8\u306E\u8A2D\u5B9A\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
HashLookupSettingsPanel.deleteDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u524A\u9664
HashLookupSettingsPanel.importDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30A4\u30F3\u30DD\u30FC\u30C8
HashLookupSettingsPanel.hashDatabasesLabel.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\uFF1A
HashLookupSettingsPanel.nameLabel.text=\u30CF\u30C3\u30B7\u30E5\u30BB\u30C3\u30C8\u540D\uFF1A
HashLookupSettingsPanel.informationLabel.text=\u60C5\u5831
HashLookupSettingsPanel.sendIngestMessagesCheckBox.text=\u30D2\u30C3\u30C8\u6BCE\u306B\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u9001\u308B
HashLookupSettingsPanel.hashDbLocationLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.hashDbNameLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.typeLabel.text=\u30BF\u30A4\u30D7\uFF1A
HashLookupSettingsPanel.locationLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D1\u30B9\uFF1A
HashLookupSettingsPanel.hashDbIndexStatusLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.hashDbTypeLabel.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093
HashLookupSettingsPanel.indexButton.text=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9
HashLookupSettingsPanel.indexLabel.text=\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u30B9\u30C6\u30FC\u30BF\u30B9\uFF1A
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u306A\u304F\u3066\u3082\u3001MD5\u3092\u8A08\u7B97
HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308B\u65E2\u77E5\u306E\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u9078\u629E\uFF1A
HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51E6\u7406\u306B\u5229\u7528\u3059\u308B\u65E2\u77E5\u306E\u60AA\u8CEA\u306A\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u9078\u629E\uFF1A
HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8A2D\u5B9A\u3092\u884C\u3046\u70BA\u306E\u60F3\u5B9A\u3055\u308C\u308B\u5F15\u6570\u306Finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u306A\u304F\u3066\u3082\u3001MD5\u3092\u8A08\u7B97
HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30CF\u30C3\u30B7\u30E5
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30CF\u30C3\u30B7\u30E5\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B{0}\u3092\u8FFD\u52A0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30D5\u30A1\u30A4\u30EB\u306B\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u3042\u308A\u307E\u305B\u3093\u3002
AddHashValuesToDatabaseDialog.JDialog.Title=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0\
HashLookupSettingsPanel.addHashesToDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
AddHashValuesToDatabaseDialog.instructionLabel.text_1=\u4E0B\u8A18\u306BMD5\u306E\u30CF\u30C3\u30B7\u30E5\u5024\u3092\u8CBC\u308A\u4ED8\u3051\u308B\uFF08\u30E9\u30A4\u30F3\u3054\u3068\u306B\u4E00\u3064\u305A\u3064\uFF09\uFF1A
AddHashValuesToDatabaseDialog.cancelButton.text_2=\u30AD\u30E3\u30F3\u30BB\u30EB
AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2=\u30AF\u30EA\u30C3\u30D7\u30DC\u30FC\u30C9\u304B\u3089\u8CBC\u308A\u4ED8\u3051\u308B
HashLookupSettingsPanel.optionsLabel.text=\u30aa\u30d7\u30b7\u30e7\u30f3
HashLookupSettingsPanel.jButton3.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashLookupSettingsPanel.indexPathLabelLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30d1\u30b9\uff1a
HashLookupSettingsPanel.createDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f5c\u6210
HashLookupSettingsPanel.jLabel6.text=\u30bf\u30a4\u30d7\uff1a
HashLookupSettingsPanel.jLabel4.text=\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\uff1a
HashLookupSettingsPanel.jLabel2.text=\u540d\u524d\uff1a
HashLookupSettingsPanel.indexPathLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u3067\u3059\u3002\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002
HashLookupSettingsPanel.deleteDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u524a\u9664
HashLookupSettingsPanel.importDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u30a4\u30f3\u30dd\u30fc\u30c8
HashLookupSettingsPanel.hashDatabasesLabel.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\uff1a
HashLookupSettingsPanel.nameLabel.text=\u30cf\u30c3\u30b7\u30e5\u30bb\u30c3\u30c8\u540d\uff1a
HashLookupSettingsPanel.informationLabel.text=\u60c5\u5831
HashLookupSettingsPanel.sendIngestMessagesCheckBox.text=\u30d2\u30c3\u30c8\u6bce\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30a4\u30f3\u30dc\u30c3\u30af\u30b9\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b
HashLookupSettingsPanel.hashDbLocationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.hashDbNameLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.typeLabel.text=\u30bf\u30a4\u30d7\uff1a
HashLookupSettingsPanel.locationLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d1\u30b9\uff1a
HashLookupSettingsPanel.hashDbIndexStatusLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.hashDbTypeLabel.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HashLookupSettingsPanel.indexButton.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9
HashLookupSettingsPanel.indexLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30b9\u30c6\u30fc\u30bf\u30b9\uff1a
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.text=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97
HashLookupModuleSettingsPanel.knownHashDbsLabel.text=\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a
HashLookupModuleSettingsPanel.knownBadHashDbsLabel.text=\u51e6\u7406\u306b\u5229\u7528\u3059\u308b\u65e2\u77e5\u306e\u60aa\u8cea\u306a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u9078\u629e\uff1a
HashLookupModuleFactory.createFileIngestModule.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleFactory.getIngestJobSettingsPanel.exception.msg=\u8a2d\u5b9a\u3092\u884c\u3046\u70ba\u306e\u60f3\u5b9a\u3055\u308c\u308b\u5f15\u6570\u306finstanceof HashLookupModuleSettings\u3067\u3059\u3002
HashLookupModuleSettingsPanel.alwaysCalcHashesCheckbox.toolTipText=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082\u3001MD5\u3092\u8a08\u7b97
HashDbSearchPanel.hashTable.defaultModel.title.text=MD5\u30cf\u30c3\u30b7\u30e5
AddContentToHashDbAction.addFilesToHashSet.unableToAddFileEmptyMsg=\u30cf\u30c3\u30b7\u30e5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b{0}\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u3042\u308a\u307e\u305b\u3093\u3002
AddHashValuesToDatabaseDialog.JDialog.Title=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0\
HashLookupSettingsPanel.addHashesToDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
AddHashValuesToDatabaseDialog.instructionLabel.text_1=\u4e0b\u8a18\u306bMD5\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8cbc\u308a\u4ed8\u3051\u308b\uff08\u30e9\u30a4\u30f3\u3054\u3068\u306b\u4e00\u3064\u305a\u3064\uff09\uff1a
AddHashValuesToDatabaseDialog.cancelButton.text_2=\u30ad\u30e3\u30f3\u30bb\u30eb
AddHashValuesToDatabaseDialog.AddValuesToHashDatabaseButton.text_2=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
AddHashValuesToDatabaseDialog.pasteFromClipboardButton.text_2=\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u304b\u3089\u8cbc\u308a\u4ed8\u3051\u308b
AddHashValuesToDatabaseProgressDialog.okButton.text=OK
AddHashValuesToDatabaseProgressDialog.statusLabel.text=\u30B9\u30C6\u30FC\u30BF\u30B9
AddHashValuesToDatabaseProgressDialog.title=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30D7\u30ED\u30B0\u30EC\u30B9\u306B\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
AddHashValuesToDatabaseDialog.title=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
AddHashValuesToDatabaseProgressDialog.showErrorsButton.text=\u30A8\u30E9\u30FC\u3092\u8868\u793A
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.parsing=MD5\u30CF\u30C3\u30B7\u30E5\u306B\u30C6\u30AD\u30B9\u30C8\u3092\u30D1\u30FC\u30B9\u4E2D...
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invalidHash=\u30A4\u30F3\u30D7\u30C3\u30C8\u306B\u7121\u52B9\u306A\u30CF\u30C3\u30B7\u30E5\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invaliHash.msg=\u7121\u52B9\u306A\u30CF\u30C3\u30B7\u30E5\uFF1A
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.noHashesToAdd=\u8FFD\u52A0\u3059\u308B\u30CF\u30C3\u30B7\u30E5\u304C\u3042\u308A\u307E\u305B\u3093\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.success={0}\u30CF\u30C3\u30B7\u30E5\u304C\u6B63\u3057\u304F\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash=\u6709\u52B9\u306A\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash.msg=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u6709\u52B9\u306A\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
HashLookupSettingsPanel.addHashesToDatabaseButton.text=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u30CF\u30C3\u30B7\u30E5\u3092\u8FFD\u52A0
AddHashValuesToDatabaseProgressDialog.statusLabel.text=\u30b9\u30c6\u30fc\u30bf\u30b9
AddHashValuesToDatabaseProgressDialog.title=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d7\u30ed\u30b0\u30ec\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
AddHashValuesToDatabaseDialog.title=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
AddHashValuesToDatabaseProgressDialog.showErrorsButton.text=\u30a8\u30e9\u30fc\u3092\u8868\u793a
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.parsing=MD5\u30cf\u30c3\u30b7\u30e5\u306b\u30c6\u30ad\u30b9\u30c8\u3092\u30d1\u30fc\u30b9\u4e2d...
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invalidHash=\u30a4\u30f3\u30d7\u30c3\u30c8\u306b\u7121\u52b9\u306a\u30cf\u30c3\u30b7\u30e5\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.invaliHash.msg=\u7121\u52b9\u306a\u30cf\u30c3\u30b7\u30e5\uff1a
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.noHashesToAdd=\u8ffd\u52a0\u3059\u308b\u30cf\u30c3\u30b7\u30e5\u304c\u3042\u308a\u307e\u305b\u3093\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.success={0}\u30cf\u30c3\u30b7\u30e5\u304c\u6b63\u3057\u304f\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash=\u6709\u52b9\u306a\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
AddHashValuesToDatabaseProgressDialog.addHashValuesToDatabase.errorAddingValidHash.msg=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u6709\u52b9\u306a\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002
HashLookupSettingsPanel.addHashesToDatabaseButton.text=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u8ffd\u52a0
@@ -30,6 +30,7 @@ import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import org.apache.commons.io.FilenameUtils;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFilesType;
@@ -46,6 +47,7 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
.getMessage(HashDbCreateDatabaseDialog.class, "HashDbCreateDatabaseDialog.defaultFileName");
private JFileChooser fileChooser = null;
private HashDb newHashDb = null;
private final static String LAST_FILE_PATH_KEY = "HashDbCreate_Path";
/**
* Displays a dialog that allows a user to create a new hash database and
@@ -273,17 +275,23 @@ final class HashDbCreateDatabaseDialog extends javax.swing.JDialog {
private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
try {
String lastBaseDirectory = "";
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
lastBaseDirectory = ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY);
}
StringBuilder path = new StringBuilder();
path.append(lastBaseDirectory);
if (!hashSetNameTextField.getText().isEmpty()) {
path.append(hashSetNameTextField.getText());
path.append(File.separator).append(hashSetNameTextField.getText());
} else {
path.append(DEFAULT_FILE_NAME);
path.append(File.separator).append(DEFAULT_FILE_NAME);
}
path.append(".").append(HashDbManager.getHashDatabaseFileExtension());
fileChooser.setSelectedFile(new File(path.toString()));
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
File databaseFile = fileChooser.getSelectedFile();
databasePathTextField.setText(databaseFile.getCanonicalPath());
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY, databaseFile.getParent());
}
} catch (IOException ex) {
Logger.getLogger(HashDbCreateDatabaseDialog.class.getName()).log(Level.WARNING, "Couldn't get selected file path.", ex); //NON-NLS
@@ -32,6 +32,7 @@ import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JFrame;
import org.sleuthkit.datamodel.TskCoreException;
import org.apache.commons.io.FilenameUtils;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb.KnownFilesType;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDbManagerException;
@@ -46,6 +47,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
private JFileChooser fileChooser = new JFileChooser();
private String selectedFilePath = "";
private HashDb selectedHashDb = null;
private final static String LAST_FILE_PATH_KEY = "HashDbImport_Path";
/**
* Displays a dialog that allows a user to select an existing hash database
@@ -249,6 +251,9 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
}// </editor-fold>//GEN-END:initComponents
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
if (ModuleSettings.settingExists(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)) {
fileChooser.setCurrentDirectory(new File(ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY)));
}
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
File databaseFile = fileChooser.getSelectedFile();
try {
@@ -259,6 +264,7 @@ final class HashDbImportDatabaseDialog extends javax.swing.JDialog {
knownRadioButton.setSelected(true);
knownRadioButtonActionPerformed(null);
}
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY, databaseFile.getParent());
} catch (IOException ex) {
Logger.getLogger(HashDbImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Failed to get path of selected database", ex); //NON-NLS
JOptionPane.showMessageDialog(this,
@@ -82,8 +82,9 @@ public final class HashLookupSettingsPanel extends IngestModuleGlobalSettingsPan
});
}
@NbBundle.Messages({"HashLookupSettingsPanel.Title=Global Hash Lookup Settings"})
private void customizeComponents() {
setName(NbBundle.getMessage(this.getClass(), "HashDbConfigPanel.setName.hashSetConfig"));
setName(Bundle.HashLookupSettingsPanel_Title());
this.ingestWarningLabel.setVisible(false);
this.hashSetTable.setModel(hashSetTableModel);
this.hashSetTable.setTableHeader(null);
@@ -6,14 +6,6 @@ OptionsCategory_Name_InterestingItemDefinitions=Interesting Files
OptionsCategory_Keywords_InterestingItemDefinitions=InterestingItemDefinitions
InterestingItemsIdentifierIngestModule.moduleName=Interesting Files Identifier
InterestingItemsIdentifierIngestModule.moduleDescription=Identifies interesting items as defined by interesting item rule sets.
InterestingItemDefsPanel.newSetButton.text=New Set
InterestingItemDefsPanel.editSetButton.text=Edit Set
InterestingItemDefsPanel.deleteSetButton.text=Delete Set
InterestingItemDefsPanel.newRuleButton.text=New Rule
InterestingItemDefsPanel.editRuleButton.text=Edit Rule
InterestingItemDefsPanel.deleteRuleButton.text=Delete Rule
InterestingItemDefsPanel.setsListLabel.text=Rule Sets
InterestingItemDefsPanel.rulesListLabel.text=Rules:
FilesSetPanel.title=Interesting Files Set
FilesSetPanel.messages.filesSetsMustBeNamed=Interesting files sets must be named.
FilesSetPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files
@@ -28,37 +20,48 @@ FilesSetRulePanel.fullNameRadioButton.text=Full Name
FilesSetRulePanel.nameRegexCheckbox.text=Regex
FilesSetRulePanel.ruleNameTextField.text=
FilesSetRulePanel.nameTextField.text=
FilesSetRulePanel.ruleNameLabel.text=Rule Name:
FilesSetRulePanel.messages.emptyNameFilter=You must specify a name pattern for this rule.
FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional):
FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule.
FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0}
FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression.
FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression.
FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0}
FilesSetRulePanel.dirsRadioButton.text=Directories
FilesSetRulePanel.filesRadioButton.text=Files
InterestingItemDefsPanel.bothRadioButton.text=Files and Directories
InterestingItemDefsPanel.dirsRadioButton.text=Directories
InterestingItemDefsPanel.filesRadioButton.text=Files
InterestingItemDefsPanel.fileNameRegexCheckbox.text=Regex
InterestingItemDefsPanel.fileNameExtensionRadioButton.text=Extension Only
InterestingItemDefsPanel.fileNameTextField.text=
InterestingItemDefsPanel.fileNameRadioButton.text=File Name
InterestingItemDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists.
FilesSetRulePanel.pathSeparatorInfoLabel.text=Use / as path separator
FilesSetRulePanel.filesAndDirsRadioButton.text=Files and Directories
InterestingItemDefsPanel.rulePathFilterTextField.text=
InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text=Regex
InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files
FilesIdentifierIngestJobSettingsPanel.border.title=Select interesting files sets to enable during ingest:
InterestingItemDefsPanel.jLabel1.text=Rule Details
InterestingItemDefsPanel.jLabel2.text=File Type:
InterestingItemDefsPanel.jLabel3.text=Name Pattern
InterestingItemDefsPanel.jLabel4.text=Path Pattern:
InterestingItemDefsPanel.jLabel5.text=Description:
InterestingItemDefsPanel.jLabel6.text=Set Details
FilesSetRulePanel.jLabel1.text=Type*\:
FilesSetRulePanel.jLabel2.text=Name Pattern*:
FilesSetRulePanel.jLabel3.text=Path Pattern:
InterestingItemDefsPanel.jTextArea1.text=This module allows you to find files that match specified criteria. Each set has a list of rules, which will match on file name and parent path patterns.
FilesSetRulePanel.jLabel4.text=* Required
FilesSetRulePanel.jLabel1.text=Type:
FilesSetRulePanel.jLabel5.text=Enter information about files that you want to find.
InterestingItemDefsPanel.jLabel6.text=Set Details
InterestingItemDefsPanel.jLabel8.text=File Size:
InterestingItemDefsPanel.jLabel7.text=MIME Type:
InterestingItemDefsPanel.jTextArea1.text=This module allows you to find files that match specified criteria. Each set has a list of rules, which will match on file name and parent path patterns.
InterestingItemDefsPanel.jLabel4.text=Path Pattern:
InterestingItemDefsPanel.jLabel1.text=Rule Details
InterestingItemDefsPanel.dirsRadioButton.text=Directories
InterestingItemDefsPanel.jLabel2.text=File Type:
InterestingItemDefsPanel.newSetButton.text=New Set
InterestingItemDefsPanel.deleteRuleButton.text=Delete Rule
InterestingItemDefsPanel.deleteSetButton.text=Delete Set
InterestingItemDefsPanel.bothRadioButton.text=Files and Directories
InterestingItemDefsPanel.setsListLabel.text=Rule Sets
InterestingItemDefsPanel.fileNameRegexCheckbox.text=Regex
InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text=Ignore Known Files
InterestingItemDefsPanel.fileNameRadioButton.text=File Name
InterestingItemDefsPanel.jLabel5.text=Description:
InterestingItemDefsPanel.fileNameTextField.text=
InterestingItemDefsPanel.jLabel3.text=Name Pattern:
InterestingItemDefsPanel.fileNameExtensionRadioButton.text=Extension Only
InterestingItemDefsPanel.editSetButton.text=Edit Set
InterestingItemDefsPanel.rulesListLabel.text=Rules:
InterestingItemDefsPanel.editRuleButton.text=Edit Rule
InterestingItemDefsPanel.filesRadioButton.text=Files
InterestingItemDefsPanel.newRuleButton.text=New Rule
InterestingItemDefsPanel.rulePathConditionTextField.text=
InterestingItemDefsPanel.rulePathConditionRegexCheckBox.text=Regex
FilesSetRulePanel.nameCheck.text=Name Pattern:
FilesSetRulePanel.pathCheck.text=Path Pattern:
FilesSetRulePanel.mimeCheck.text=MIME Type:
FilesSetRulePanel.fileSizeCheck.text=File Size:
FilesSetRulePanel.filesRadioButton.text=Files
FilesSetRulePanel.dirsRadioButton.text=Directories
FilesSetRulePanel.filesAndDirsRadioButton.text=Files and Directories
@@ -1,59 +1,74 @@
FilesIdentifierIngestJobSettingsPanel.border.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u4E2D\u306B\u6709\u52B9\u306B\u3059\u308B\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8\u3092\u9078\u629E\uFF1A
FilesIdentifierIngestJobSettingsPanel.border.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306b\u6709\u52b9\u306b\u3059\u308b\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u3092\u9078\u629e\uff1a
FilesSetPanel.descPanel.border.title=\u6982\u8981
FilesSetPanel.descriptionPanel.border.title=\u6982\u8981
FilesSetPanel.ignoreKnownFilesCheckbox.text=\u65E2\u77E5\u30D5\u30A1\u30A4\u30EB\u3092\u7121\u8996
FilesSetPanel.messages.filesSetsMustBeNamed=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8\u306F\u540D\u524D\u304C\u5FC5\u8981\u3067\u3059\u3002
FilesSetPanel.nameLabel.text=\u30BB\u30C3\u30C8\u540D\uFF1A
FilesSetPanel.title=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8
FilesSetRulePanel.dirsRadioButton.text=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
FilesSetRulePanel.extensionRadioButton.text=\u62E1\u5F35\u5B50\u306E\u307F
FilesSetRulePanel.filesAndDirsRadioButton.text=\u30D5\u30A1\u30A4\u30EB\u304A\u3088\u3073\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
FilesSetRulePanel.filesRadioButton.text=\u30D5\u30A1\u30A4\u30EB
FilesSetRulePanel.fullNameRadioButton.text=\u30D5\u30EB\u30CD\u30FC\u30E0
FilesSetRulePanel.jLabel1.text=\u30BF\u30A4\u30D7*\uFF1A
FilesSetRulePanel.jLabel2.text=\u30CD\u30FC\u30E0\u30D1\u30BF\u30FC\u30F3*\uFF1A
FilesSetRulePanel.jLabel3.text=\u30D1\u30B9\u30D1\u30BF\u30FC\u30F3\uFF1A
FilesSetRulePanel.messages.emptyNameFilter=\u3053\u306E\u30EB\u30FC\u30EB\u306F\u30CD\u30FC\u30E0\u30D1\u30BF\u30FC\u30F3\u3092\u7279\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
FilesSetRulePanel.messages.invalidCharInName=\u6B63\u898F\u8868\u73FE\u4EE5\u5916\u306F\\\u3001/\u3001\:\u3001*\u3001?\u3001"\u3001<\u3001>\u3092\u540D\u524D\u306B\u542B\u3081\u307E\u305B\u3093\u3002
FilesSetRulePanel.messages.invalidCharInPath=\u6B63\u898F\u8868\u73FE\u4EE5\u5916\u306F\\\u3001\:\u3001*\u3001?\u3001"\u3001<\u3001>\u3092\u30D1\u30B9\u306B\u542B\u3081\u307E\u305B\u3093\u3002
FilesSetRulePanel.messages.invalidNameRegex=\u6B63\u898F\u8868\u73FE\u306F\u6709\u52B9\u306A\u540D\u524D\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF1A\n\n{0}
FilesSetRulePanel.messages.invalidPathRegex=\u6B63\u898F\u8868\u73FE\u306F\u6709\u52B9\u306A\u30D1\u30B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF1A\n\n{0}
FilesSetRulePanel.nameRegexCheckbox.text=\u6B63\u898F\u8868\u73FE
FilesSetRulePanel.pathRegexCheckBox.text=\u6B63\u898F\u8868\u73FE
FilesSetRulePanel.pathSeparatorInfoLabel.text=/\u3092\u30D1\u30B9\u533A\u5207\u308A\u6587\u5B57\u3068\u3057\u3066\u5229\u7528
FilesSetRulePanel.ruleNameLabel.text=\u30EB\u30FC\u30EB\u540D\uFF1A
FilesSetRulePanel.title=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30BB\u30C3\u30C8\u30EB\u30FC\u30EB
InterestingItemDefsPanel.bothRadioButton.text=\u30D5\u30A1\u30A4\u30EB\u304A\u3088\u3073\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
InterestingItemDefsPanel.deleteRuleButton.text=\u30EB\u30FC\u30EB\u3092\u524A\u9664
InterestingItemDefsPanel.deleteSetButton.text=\u30BB\u30C3\u30C8\u3092\u524A\u9664
InterestingItemDefsPanel.dirsRadioButton.text=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
InterestingItemDefsPanel.editRuleButton.text=\u30EB\u30FC\u30EB\u3092\u7DE8\u96C6
InterestingItemDefsPanel.editSetButton.text=\u30BB\u30C3\u30C8\u3092\u7DE8\u96C6
InterestingItemDefsPanel.fileNameExtensionRadioButton.text=\u62E1\u5F35\u5B50\u306E\u307F
InterestingItemDefsPanel.fileNameRadioButton.text=\u30D5\u30A1\u30A4\u30EB\u540D
InterestingItemDefsPanel.fileNameRegexCheckbox.text=\u6B63\u898F\u8868\u73FE
InterestingItemDefsPanel.filesRadioButton.text=\u30D5\u30A1\u30A4\u30EB
InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text=\u65E2\u77E5\u30D5\u30A1\u30A4\u30EB\u3092\u7121\u8996
InterestingItemDefsPanel.jLabel1.text=\u30EB\u30FC\u30EB\u8A73\u7D30
InterestingItemDefsPanel.jLabel2.text=\u30D5\u30A1\u30A4\u30EB\u30BF\u30A4\u30D7\uFF1A
InterestingItemDefsPanel.jLabel3.text=\u30CD\u30FC\u30E0\u30D1\u30BF\u30FC\u30F3
InterestingItemDefsPanel.jLabel4.text=\u30D1\u30B9\u30D1\u30BF\u30FC\u30F3\uFF1A
InterestingItemDefsPanel.jLabel5.text=\u6982\u8981\uFF1A
InterestingItemDefsPanel.jLabel6.text=\u30BB\u30C3\u30C8\u8A73\u7D30
InterestingItemDefsPanel.jTextArea1.text=\u6307\u5B9A\u3055\u308C\u305F\u6761\u4EF6\u3068\u4E00\u81F4\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u306E\u304C\u53EF\u80FD\u306A\u30E2\u30B8\u30E5\u30FC\u30EB\u3067\u3059\u3002\u5404\u30BB\u30C3\u30C8\u306B\u306F\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30DA\u30A2\u30EC\u30F3\u30C8\u30D1\u30B9\u30D1\u30BF\u30FC\u30F3\u3092\u3082\u3068\u306B\u4E00\u81F4\u3059\u308B\u3001\u30EB\u30FC\u30EB\u30EA\u30B9\u30C8\u304C\u3042\u308A\u307E\u3059\u3002
InterestingItemDefsPanel.newRuleButton.text=\u65B0\u898F\u30EB\u30FC\u30EB
InterestingItemDefsPanel.newSetButton.text=\u65B0\u898F\u30BB\u30C3\u30C8
InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text=\u6B63\u898F\u8868\u73FE
InterestingItemDefsPanel.rulesListLabel.text=\u30EB\u30FC\u30EB\uFF1A
InterestingItemDefsPanel.setsListLabel.text=\u30EB\u30FC\u30EB\u30BB\u30C3\u30C8
InterestingItemsIdentifierIngestModule.moduleDescription=\u7591\u308F\u3057\u3044\u30A2\u30A4\u30C6\u30E0\u30EB\u30FC\u30EB\u30BB\u30C3\u30C8\u306E\u5B9A\u7FA9\u3092\u3082\u3068\u306B\u7591\u308F\u3057\u3044\u30A2\u30A4\u30C6\u30E0\u3092\u691C\u77E5\u3057\u307E\u3059\u3002
InterestingItemsIdentifierIngestModule.moduleName=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u691C\u77E5
OpenIDE-Module-Display-Category=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB
OpenIDE-Module-Long-Description=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u691C\u77E5\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3002\n\n\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u30EB\u30FC\u30EB\u30BB\u30C3\u30C8\u306E\u5B9A\u7FA9\u3092\u3082\u3068\u306B\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u77E5\u3057\u307E\u3059\u3002
OpenIDE-Module-Name=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u691C\u77E5
OpenIDE-Module-Short-Description=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u691C\u77E5\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB
OptionsCategory_Name_InterestingItemDefinitions=\u7591\u308F\u3057\u3044\u30D5\u30A1\u30A4\u30EB
OptionsCategory_Keywords_InterestingItemDefinitions=\u7591\u308F\u3057\u3044\u30A2\u30A4\u30C6\u30E0\u5B9A\u7FA9
InterestingItemDefsPanel.doFileSetsDialog.duplicateRuleSet.text=\u540D\u524D\u304C{0}\u306E\u30EB\u30FC\u30EB\u30BB\u30C3\u30C8\u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\u3002
FilesSetRulePanel.jLabel4.text=*\u5FC5\u9808
FilesSetRulePanel.jLabel5.text=\u898B\u3064\u3051\u305F\u3044\u30D5\u30A1\u30A4\u30EB\u306E\u60C5\u5831\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
FilesSetPanel.ignoreKnownFilesCheckbox.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\u3092\u7121\u8996
FilesSetPanel.messages.filesSetsMustBeNamed=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u306f\u540d\u524d\u304c\u5fc5\u8981\u3067\u3059\u3002
FilesSetPanel.nameLabel.text=\u30bb\u30c3\u30c8\u540d\uff1a
FilesSetPanel.title=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8
FilesSetRulePanel.extensionRadioButton.text=\u62e1\u5f35\u5b50\u306e\u307f
FilesSetRulePanel.fullNameRadioButton.text=\u30d5\u30eb\u30cd\u30fc\u30e0
FilesSetRulePanel.jLabel1.text=\u30bf\u30a4\u30d7*\uff1a
FilesSetRulePanel.messages.emptyNameCondition=\u3053\u306e\u30eb\u30fc\u30eb\u306f\u30cd\u30fc\u30e0\u30d1\u30bf\u30fc\u30f3\u3092\u7279\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
FilesSetRulePanel.messages.invalidCharInName=\u6b63\u898f\u8868\u73fe\u4ee5\u5916\u306f\\\u3001/\u3001\:\u3001*\u3001?\u3001"\u3001<\u3001>\u3092\u540d\u524d\u306b\u542b\u3081\u307e\u305b\u3093\u3002
FilesSetRulePanel.messages.invalidCharInPath=\u6b63\u898f\u8868\u73fe\u4ee5\u5916\u306f\\\u3001\:\u3001*\u3001?\u3001"\u3001<\u3001>\u3092\u30d1\u30b9\u306b\u542b\u3081\u307e\u305b\u3093\u3002
FilesSetRulePanel.messages.invalidNameRegex=\u6b63\u898f\u8868\u73fe\u306f\u6709\u52b9\u306a\u540d\u524d\u3067\u306f\u3042\u308a\u307e\u305b\u3093\uff1a\n\n{0}
FilesSetRulePanel.messages.invalidPathRegex=\u6b63\u898f\u8868\u73fe\u306f\u6709\u52b9\u306a\u30d1\u30b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\uff1a\n\n{0}
FilesSetRulePanel.nameRegexCheckbox.text=\u6b63\u898f\u8868\u73fe
FilesSetRulePanel.pathRegexCheckBox.text=\u6b63\u898f\u8868\u73fe
FilesSetRulePanel.pathSeparatorInfoLabel.text=/\u3092\u30d1\u30b9\u533a\u5207\u308a\u6587\u5b57\u3068\u3057\u3066\u5229\u7528
FilesSetRulePanel.ruleNameLabel.text=\u30eb\u30fc\u30eb\u540d\uff1a
FilesSetRulePanel.title=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u30eb\u30fc\u30eb
InterestingItemsIdentifierIngestModule.moduleDescription=\u7591\u308f\u3057\u3044\u30a2\u30a4\u30c6\u30e0\u30eb\u30fc\u30eb\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9\u3092\u3082\u3068\u306b\u7591\u308f\u3057\u3044\u30a2\u30a4\u30c6\u30e0\u3092\u691c\u77e5\u3057\u307e\u3059\u3002
InterestingItemsIdentifierIngestModule.moduleName=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u691c\u77e5
OpenIDE-Module-Display-Category=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
OpenIDE-Module-Long-Description=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u691c\u77e5\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3002\n\n\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u30eb\u30fc\u30eb\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9\u3092\u3082\u3068\u306b\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u77e5\u3057\u307e\u3059\u3002
OpenIDE-Module-Name=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u691c\u77e5
OpenIDE-Module-Short-Description=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb\u691c\u77e5\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb
OptionsCategory_Name_InterestingItemDefinitions=\u7591\u308f\u3057\u3044\u30d5\u30a1\u30a4\u30eb
OptionsCategory_Keywords_InterestingItemDefinitions=\u7591\u308f\u3057\u3044\u30a2\u30a4\u30c6\u30e0\u5b9a\u7fa9
InterestingItemDefsPanel.doFileSetsDialog.duplicateRuleSet.text=\u540d\u524d\u304c{0}\u306e\u30eb\u30fc\u30eb\u30bb\u30c3\u30c8\u306f\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002
FilesSetRulePanel.jLabel5.text=\u898b\u3064\u3051\u305f\u3044\u30d5\u30a1\u30a4\u30eb\u306e\u60c5\u5831\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
InterestingItemDefsPanel.jTextArea1.text=\u6307\u5b9a\u3055\u308c\u305f\u6761\u4ef6\u3068\u4e00\u81f4\u3059\u308b\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3059\u308b\u306e\u304c\u53ef\u80fd\u306a\u30e2\u30b8\u30e5\u30fc\u30eb\u3067\u3059\u3002\u5404\u30bb\u30c3\u30c8\u306b\u306f\u30d5\u30a1\u30a4\u30eb\u540d\u304a\u3088\u3073\u30da\u30a2\u30ec\u30f3\u30c8\u30d1\u30b9\u30d1\u30bf\u30fc\u30f3\u3092\u3082\u3068\u306b\u4e00\u81f4\u3059\u308b\u3001\u30eb\u30fc\u30eb\u30ea\u30b9\u30c8\u304c\u3042\u308a\u307e\u3059\u3002
InterestingItemDefsPanel.jLabel4.text=\u30d1\u30b9\u30d1\u30bf\u30fc\u30f3\uff1a
InterestingItemDefsPanel.jLabel1.text=\u30eb\u30fc\u30eb\u8a73\u7d30
InterestingItemDefsPanel.dirsRadioButton.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea
InterestingItemDefsPanel.jLabel2.text=\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\uff1a
InterestingItemDefsPanel.newSetButton.text=\u65b0\u898f\u30bb\u30c3\u30c8
InterestingItemDefsPanel.deleteRuleButton.text=\u30eb\u30fc\u30eb\u3092\u524a\u9664
InterestingItemDefsPanel.deleteSetButton.text=\u30bb\u30c3\u30c8\u3092\u524a\u9664
InterestingItemDefsPanel.bothRadioButton.text=\u30d5\u30a1\u30a4\u30eb\u304a\u3088\u3073\u30c7\u30a3\u30ec\u30af\u30c8\u30ea
InterestingItemDefsPanel.setsListLabel.text=\u30eb\u30fc\u30eb\u30bb\u30c3\u30c8
InterestingItemDefsPanel.fileNameRegexCheckbox.text=\u6b63\u898f\u8868\u73fe
InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\u3092\u7121\u8996
InterestingItemDefsPanel.fileNameRadioButton.text=\u30d5\u30a1\u30a4\u30eb\u540d
InterestingItemDefsPanel.jLabel5.text=\u6982\u8981\uff1a
InterestingItemDefsPanel.jLabel3.text=\u30cd\u30fc\u30e0\u30d1\u30bf\u30fc\u30f3
InterestingItemDefsPanel.fileNameExtensionRadioButton.text=\u62e1\u5f35\u5b50\u306e\u307f
InterestingItemDefsPanel.editSetButton.text=\u30bb\u30c3\u30c8\u3092\u7de8\u96c6
InterestingItemDefsPanel.rulesListLabel.text=\u30eb\u30fc\u30eb\uff1a
InterestingItemDefsPanel.editRuleButton.text=\u30eb\u30fc\u30eb\u3092\u7de8\u96c6
InterestingItemDefsPanel.filesRadioButton.text=\u30d5\u30a1\u30a4\u30eb
InterestingItemDefsPanel.newRuleButton.text=\u65b0\u898f\u30eb\u30fc\u30eb
InterestingItemDefsPanel.jLabel6.text=\u30bb\u30c3\u30c8\u8a73\u7d30
InterestingItemDefsPanel.rulePathConditionRegexCheckBox.text=\u6b63\u898f\u8868\u73fe
@@ -26,6 +26,9 @@ import java.util.TreeMap;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
@@ -33,6 +36,10 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
* Ingest job settings panel for interesting files identifier ingest modules.
*/
final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobSettingsPanel implements Observer {
@Messages({
"FilesIdentifierIngestJobSettingsPanel.updateError=Error updating interesting files sets settings file.",
"FilesIdentifierIngestJobSettingsPanel.getError=Error getting interesting files sets from settings file."
})
private final FilesSetsTableModel tableModel;
@@ -75,7 +82,12 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
* Observer.update().
*/
List<FilesSetRow> filesSetRows = new ArrayList<>();
this.filesSetSnapshot = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
try {
this.filesSetSnapshot = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
} catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
MessageNotifyUtil.Message.error(Bundle.FilesIdentifierIngestJobSettingsPanel_getError());
this.filesSetSnapshot = new TreeMap<>();
}
for (FilesSet set : this.filesSetSnapshot.values()) {
filesSetRows.add(new FilesSetRow(set, settings.interestingFilesSetIsEnabled(set.getName())));
}
@@ -130,7 +142,13 @@ final class FilesIdentifierIngestJobSettingsPanel extends IngestModuleIngestJobS
// Refresh the view of the interesting files set definitions.
List<FilesSetRow> rowModels = new ArrayList<>();
TreeMap<String, FilesSet> newFilesSetSnapshot = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
TreeMap<String, FilesSet> newFilesSetSnapshot;
try {
newFilesSetSnapshot = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
} catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
MessageNotifyUtil.Message.error(Bundle.FilesIdentifierIngestJobSettingsPanel_updateError());
return;
}
for (FilesSet set : newFilesSetSnapshot.values()) {
if (this.filesSetSnapshot.keySet().contains(set.getName())) {
// Preserve the current enabled/diabled state of the set.
@@ -24,7 +24,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
@@ -44,6 +46,9 @@ import org.sleuthkit.datamodel.TskCoreException;
* files that match interesting files set definitions.
*/
final class FilesIdentifierIngestModule implements FileIngestModule {
@Messages({
"FilesIdentifierIngestModule.getFilesError=Error getting interesting files sets from file."
})
private static final Object sharedResourcesLock = new Object();
private static final Logger logger = Logger.getLogger(FilesIdentifierIngestModule.class.getName());
@@ -77,10 +82,14 @@ final class FilesIdentifierIngestModule implements FileIngestModule {
// synchronized definitions manager method eliminates the need
// to disable the interesting files set definition UI during ingest.
List<FilesSet> filesSets = new ArrayList<>();
for (FilesSet set : InterestingItemDefsManager.getInstance().getInterestingFilesSets().values()) {
if (settings.interestingFilesSetIsEnabled(set.getName())) {
filesSets.add(set);
try {
for (FilesSet set : InterestingItemDefsManager.getInstance().getInterestingFilesSets().values()) {
if (settings.interestingFilesSetIsEnabled(set.getName())) {
filesSets.add(set);
}
}
} catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
throw new IngestModuleException(Bundle.FilesIdentifierIngestModule_getFilesError(), ex);
}
FilesIdentifierIngestModule.interestingFileSetsByJob.put(context.getJobId(), filesSets);
}
@@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.modules.interestingitems;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -35,8 +36,9 @@ import org.sleuthkit.datamodel.TskData;
* Interesting files set definition objects are immutable, so they may be safely
* published to multiple threads.
*/
final class FilesSet {
final class FilesSet implements Serializable {
private static final long serialVersionUID = 1L;
private final String name;
private final String description;
private final boolean ignoreKnownFiles;
@@ -135,51 +137,65 @@ final class FilesSet {
* A set membership rule for an interesting files set. The immutability of a
* rule object allows it to be safely published to multiple threads.
*/
static class Rule {
static class Rule implements Serializable {
private static final long serialVersionUID = 1L;
private final String uuid;
private final String ruleName;
private final FileNameFilter fileNameFilter;
private final MetaTypeFilter metaTypeFilter;
private final ParentPathFilter pathFilter;
private final List<FileAttributeFilter> filters = new ArrayList<>();
private final FileNameCondition fileNameCondition;
private final MetaTypeCondition metaTypeCondition;
private final ParentPathCondition pathCondition;
private final MimeTypeCondition mimeTypeCondition;
private final FileSizeCondition fileSizeCondition;
private final List<FileAttributeCondition> conditions = new ArrayList<>();
/**
* Construct an interesting files set membership rule.
*
* @param ruleName The name of the rule.
* @param fileNameFilter A file name filter.
* @param metaTypeFilter A file meta-type filter.
* @param pathFilter A file path filter, may be null.
* @param ruleName The name of the rule. Can be empty string.
* @param fileNameCondition A file name condition, may be null.
* @param metaTypeCondition A file meta-type condition.
* @param pathCondition A file path condition, may be null.
* @param mimeTypeCondition A file mime type condition, may be null.
* @param fileSizeCondition A file size condition, may be null.
*/
Rule(String ruleName, FileNameFilter fileNameFilter, MetaTypeFilter metaTypeFilter, ParentPathFilter pathFilter) {
Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition) {
// since ruleName is optional, ruleUUID can be used to uniquely identify a rule.
this.uuid = UUID.randomUUID().toString();
if (metaTypeCondition == null) {
throw new IllegalArgumentException("Interesting files set rule meta-type condition cannot be null");
}
if (pathCondition == null && fileNameCondition == null && mimeTypeCondition == null && fileSizeCondition == null) {
throw new IllegalArgumentException("Must have at least one condition on rule.");
}
if (ruleName == null) {
throw new IllegalArgumentException("Interesting files set rule name cannot be null");
}
if (fileNameFilter == null) {
throw new IllegalArgumentException("Interesting files set rule file name filter cannot be null");
}
if (metaTypeFilter == null) {
throw new IllegalArgumentException("Interesting files set rule meta-type filter cannot be null");
}
this.ruleName = ruleName;
/*
* The rules are evaluated in the order added. MetaType check is
* fastest, so do it first
*/
this.metaTypeFilter = metaTypeFilter;
this.filters.add(this.metaTypeFilter);
this.metaTypeCondition = metaTypeCondition;
this.conditions.add(this.metaTypeCondition);
this.fileNameFilter = fileNameFilter;
this.filters.add(fileNameFilter);
this.fileSizeCondition = fileSizeCondition;
if (this.fileSizeCondition != null) {
this.conditions.add(this.fileSizeCondition);
}
this.pathFilter = pathFilter;
if (this.pathFilter != null) {
this.filters.add(this.pathFilter);
this.fileNameCondition = fileNameCondition;
if (this.fileNameCondition != null) {
this.conditions.add(fileNameCondition);
}
this.mimeTypeCondition = mimeTypeCondition;
if (this.mimeTypeCondition != null) {
this.conditions.add(mimeTypeCondition);
}
this.pathCondition = pathCondition;
if (this.pathCondition != null) {
this.conditions.add(this.pathCondition);
}
}
@@ -193,30 +209,30 @@ final class FilesSet {
}
/**
* Get the file name filter for the rule.
* Get the file name condition for the rule.
*
* @return A file name filter.
* @return A file name condition. Can be null.
*/
FileNameFilter getFileNameFilter() {
return this.fileNameFilter;
FileNameCondition getFileNameCondition() {
return this.fileNameCondition;
}
/**
* Get the meta-type filter for the rule.
* Get the meta-type condition for the rule.
*
* @return A meta-type filter.
* @return A meta-type condition. Can be null.
*/
MetaTypeFilter getMetaTypeFilter() {
return this.metaTypeFilter;
MetaTypeCondition getMetaTypeCondition() {
return this.metaTypeCondition;
}
/**
* Get the path filter for the rule.
* Get the path condition for the rule.
*
* @return A path filter, may be null.
* @return A path condition, may be null.
*/
ParentPathFilter getPathFilter() {
return this.pathFilter;
ParentPathCondition getPathCondition() {
return this.pathCondition;
}
/**
@@ -227,8 +243,8 @@ final class FilesSet {
* @return True if the rule is satisfied, false otherwise.
*/
boolean isSatisfied(AbstractFile file) {
for (FileAttributeFilter filter : filters) {
if (!filter.passes(file)) {
for (FileAttributeCondition condition : conditions) {
if (!condition.passes(file)) {
return false;
}
}
@@ -242,7 +258,19 @@ final class FilesSet {
public String toString() {
// This override is designed to provide a display name for use with
// javax.swing.DefaultListModel<E>.
return this.ruleName + " (" + fileNameFilter.getTextToMatch() + ")";
if (fileNameCondition != null) {
return this.ruleName + " (" + fileNameCondition.getTextToMatch() + ")";
} else if (this.pathCondition != null) {
return this.ruleName + " (" + pathCondition.getTextToMatch() + ")";
} else if (this.mimeTypeCondition != null) {
return this.ruleName + " (" + mimeTypeCondition.getMimeType() + ")";
} else if (this.fileSizeCondition != null) {
return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue()
+ " " + fileSizeCondition.getUnit().getName() + ")";
} else {
return this.ruleName + " ()";
}
}
/**
@@ -253,13 +281,27 @@ final class FilesSet {
}
/**
* An interface for the file attribute filters of which interesting
* @return the mime type condition. Can be null.
*/
MimeTypeCondition getMimeTypeCondition() {
return mimeTypeCondition;
}
/**
* @return the file size condition. Can be null.
*/
FileSizeCondition getFileSizeCondition() {
return fileSizeCondition;
}
/**
* An interface for the file attribute conditions of which interesting
* files set membership rules are composed.
*/
static interface FileAttributeFilter {
static interface FileAttributeCondition extends Serializable {
/**
* Tests whether or not a file satisfies the conditions of a filter.
* Tests whether or not a file satisfies the condition.
*
* @param file The file to test.
*
@@ -269,11 +311,193 @@ final class FilesSet {
}
/**
* A file meta-type filter for an interesting files set membership rule.
* The immutability of a meta-type filter object allows it to be safely
* published to multiple threads.
* A class for checking files based upon their MIME types.
*/
static final class MetaTypeFilter implements FileAttributeFilter {
static final class MimeTypeCondition implements FileAttributeCondition {
private static final long serialVersionUID = 1L;
private final String mimeType;
/**
* Constructs a MimeTypeCondition
*
* @param mimeType The mime type to condition for
*/
MimeTypeCondition(String mimeType) {
this.mimeType = mimeType;
}
/**
* @inheritDoc
*/
@Override
public boolean passes(AbstractFile file) {
return this.mimeType.equals(file.getMIMEType());
}
/**
* Gets the mime type that is being checked
*
* @return the mime type
*/
String getMimeType() {
return this.mimeType;
}
}
/**
* A class for checking whether a file's size is within the
* specifications given (i.e. < N Bytes).
*/
static final class FileSizeCondition implements FileAttributeCondition {
private static final long serialVersionUID = 1L;
/**
* Represents a comparison item for file size
*/
static enum COMPARATOR {
LESS_THAN("<"),
LESS_THAN_EQUAL("≤"),
EQUAL("="),
GREATER_THAN(">"),
GREATER_THAN_EQUAL("≥");
private String symbol;
COMPARATOR(String symbol) {
this.symbol = symbol;
}
public static COMPARATOR fromSymbol(String symbol) {
if (symbol.equals("<=") || symbol.equals("≤")) {
return LESS_THAN_EQUAL;
} else if (symbol.equals("<")) {
return LESS_THAN;
} else if (symbol.equals("==") || symbol.equals("=")) {
return EQUAL;
} else if (symbol.equals(">")) {
return GREATER_THAN;
} else if (symbol.equals(">=") || symbol.equals("≥")) {
return GREATER_THAN_EQUAL;
} else {
throw new IllegalArgumentException("Invalid symbol");
}
}
/**
* @return the symbol
*/
public String getSymbol() {
return symbol;
}
}
/**
* Represents the units of size
*/
static enum SIZE_UNIT {
BYTE(1, "Bytes"),
KILOBYTE(1024, "Kilobytes"),
MEGABYTE(1024 * 1024, "Megabytes"),
GIGABYTE(1024 * 1024 * 1024, "Gigabytes");
private long size;
private String name;
private SIZE_UNIT(long size, String name) {
this.size = size;
this.name = name;
}
public long getSize() {
return this.size;
}
public static SIZE_UNIT fromName(String name) {
for (SIZE_UNIT unit : SIZE_UNIT.values()) {
if (unit.getName().equals(name)) {
return unit;
}
}
throw new IllegalArgumentException("Invalid name for size unit.");
}
/**
* @return the name
*/
public String getName() {
return name;
}
}
private final COMPARATOR comparator;
private final SIZE_UNIT unit;
private final int sizeValue;
FileSizeCondition(COMPARATOR comparator, SIZE_UNIT unit, int sizeValue) {
this.comparator = comparator;
this.unit = unit;
this.sizeValue = sizeValue;
}
/**
* Gets the comparator of this condition
*
* @return the comparator
*/
COMPARATOR getComparator() {
return comparator;
}
/**
* Gets the unit for the size of this condition
*
* @return the unit
*/
SIZE_UNIT getUnit() {
return unit;
}
/**
* Gets the size value of this condition
*
* @return the size value
*/
int getSizeValue() {
return sizeValue;
}
@Override
public boolean passes(AbstractFile file) {
long fileSize = file.getSize();
long conditionSize = this.getUnit().getSize() * this.getSizeValue();
switch (this.getComparator()) {
case GREATER_THAN:
return fileSize > conditionSize;
case GREATER_THAN_EQUAL:
return fileSize >= conditionSize;
case LESS_THAN_EQUAL:
return fileSize <= conditionSize;
case LESS_THAN:
return fileSize < conditionSize;
default:
return fileSize == conditionSize;
}
}
}
/**
* A file meta-type condition for an interesting files set membership
* rule. The immutability of a meta-type condition object allows it to
* be safely published to multiple threads.
*/
static final class MetaTypeCondition implements FileAttributeCondition {
private static final long serialVersionUID = 1L;
enum Type {
@@ -285,11 +509,11 @@ final class FilesSet {
private final Type type;
/**
* Construct a meta-type filter.
* Construct a meta-type condition.
*
* @param metaType The meta-type to match, must.
*/
MetaTypeFilter(Type type) {
MetaTypeCondition(Type type) {
this.type = type;
}
@@ -310,9 +534,9 @@ final class FilesSet {
}
/**
* Gets the meta-type the filter matches.
* Gets the meta-type the condition matches.
*
* @return A member of the MetaTypeFilter.Type enumeration.
* @return A member of the MetaTypeCondition.Type enumeration.
*/
Type getMetaType() {
return this.type;
@@ -320,20 +544,20 @@ final class FilesSet {
}
/**
* An interface for file attribute filters that do textual matching.
* An interface for file attribute conditions that do textual matching.
*/
static interface TextFilter extends FileAttributeFilter {
static interface TextCondition extends FileAttributeCondition {
/**
* Gets the text the filter matches.
* Gets the text the condition matches.
*
* @return The text.
*/
String getTextToMatch();
/**
* Queries whether or not the text the filter matches is a regular
* expression.
* Queries whether or not the text the condition matches is a
* regular expression.
*
* @return True if the text to be matched is a regular expression,
* false otherwise.
@@ -341,7 +565,7 @@ final class FilesSet {
boolean isRegex();
/**
* Determines whether a string of text matches the filter.
* Determines whether a string of text matches the condition.
*
* @param textToMatch The text string.
*
@@ -352,19 +576,19 @@ final class FilesSet {
}
/**
* An abstract base class for file attribute filters that do textual
* An abstract base class for file attribute conditions that do textual
* matching.
*/
private static abstract class AbstractTextFilter implements TextFilter {
private static abstract class AbstractTextCondition implements TextCondition {
private final TextMatcher textMatcher;
/**
* Construct a case-insensitive text filter.
* Construct a case-insensitive text condition.
*
* @param text The text to be matched.
*/
AbstractTextFilter(String text, Boolean partialMatch) {
AbstractTextCondition(String text, Boolean partialMatch) {
if (partialMatch) {
this.textMatcher = new FilesSet.Rule.CaseInsensitivePartialStringComparisionMatcher(text);
} else {
@@ -373,16 +597,16 @@ final class FilesSet {
}
/**
* Construct a regular expression text filter.
* Construct a regular expression text condition.
*
* @param regex The regular expression to be matched.
*/
AbstractTextFilter(Pattern regex) {
AbstractTextCondition(Pattern regex) {
this.textMatcher = new FilesSet.Rule.RegexMatcher(regex);
}
/**
* Get the text the filter matches.
* Get the text the condition matches.
*
* @return The text.
*/
@@ -392,8 +616,8 @@ final class FilesSet {
}
/**
* Queries whether or not the text the filter matches is a regular
* expression.
* Queries whether or not the text the condition matches is a
* regular expression.
*
* @return True if the text to be matched is a regular expression,
* false otherwise.
@@ -404,7 +628,7 @@ final class FilesSet {
}
/**
* Determines whether a string of text matches the filter.
* Determines whether a string of text matches the condition.
*
* @param textToMatch The text string.
*
@@ -424,27 +648,29 @@ final class FilesSet {
}
/**
* A file path filter for an interesting files set membership rule. The
* immutability of a path filter object allows it to be safely published
* to multiple threads.
* A file path condition for an interesting files set membership rule.
* The immutability of a path condition object allows it to be safely
* published to multiple threads.
*/
static final class ParentPathFilter extends AbstractTextFilter {
static final class ParentPathCondition extends AbstractTextCondition {
private static final long serialVersionUID = 1L;
/**
* Construct a case-insensitive file path filter.
* Construct a case-insensitive file path condition.
*
* @param path The path to be matched.
*/
ParentPathFilter(String path) {
ParentPathCondition(String path) {
super(path, true);
}
/**
* Construct a file path regular expression filter.
* Construct a file path regular expression condition.
*
* @param path The path regular expression to be matched.
*/
ParentPathFilter(Pattern path) {
ParentPathCondition(Pattern path) {
super(path);
}
@@ -459,34 +685,37 @@ final class FilesSet {
}
/**
* A "tagging" interface to group name and extension filters separately
* from path filters for type safety when constructing rules.
* A "tagging" interface to group name and extension conditions
* separately from path conditions for type safety when constructing
* rules.
*/
static interface FileNameFilter extends TextFilter {
static interface FileNameCondition extends TextCondition {
}
/**
* A file name filter for an interesting files set membership rule. The
* immutability of a file name filter object allows it to be safely
* published to multiple threads.
* A file name condition for an interesting files set membership rule.
* The immutability of a file name condition object allows it to be
* safely published to multiple threads.
*/
static final class FullNameFilter extends AbstractTextFilter implements FileNameFilter {
static final class FullNameCondition extends AbstractTextCondition implements FileNameCondition {
private static final long serialVersionUID = 1L;
/**
* Construct a case-insensitive full file name filter.
* Construct a case-insensitive full file name condition.
*
* @param name The file name to be matched.
*/
FullNameFilter(String name) {
FullNameCondition(String name) {
super(name, false);
}
/**
* Construct a full file name regular expression filter.
* Construct a full file name regular expression condition.
*
* @param name The file name regular expression to be matched.
*/
FullNameFilter(Pattern name) {
FullNameCondition(Pattern name) {
super(name);
}
@@ -501,18 +730,20 @@ final class FilesSet {
}
/**
* A file name extension filter for an interesting files set membership
* rule. The immutability of a file name extension filter object allows
* it to be safely published to multiple threads.
* A file name extension condition for an interesting files set
* membership rule. The immutability of a file name extension condition
* object allows it to be safely published to multiple threads.
*/
static final class ExtensionFilter extends AbstractTextFilter implements FileNameFilter {
static final class ExtensionCondition extends AbstractTextCondition implements FileNameCondition {
private static final long serialVersionUID = 1L;
/**
* Construct a case-insensitive file name extension filter.
* Construct a case-insensitive file name extension condition.
*
* @param extension The file name extension to be matched.
*/
ExtensionFilter(String extension) {
ExtensionCondition(String extension) {
// If there is a leading ".", strip it since
// AbstractFile.getFileNameExtension() returns just the
// extension chars and not the dot.
@@ -520,12 +751,12 @@ final class FilesSet {
}
/**
* Construct a file name extension regular expression filter.
* Construct a file name extension regular expression condition.
*
* @param extension The file name extension regular expression to be
* matched.
*/
ExtensionFilter(Pattern extension) {
ExtensionCondition(Pattern extension) {
super(extension.pattern(), false);
}
@@ -541,9 +772,9 @@ final class FilesSet {
/**
* An interface for objects that do textual matches, used to compose a
* text filter.
* text condition.
*/
private static interface TextMatcher {
private static interface TextMatcher extends Serializable {
/**
* Get the text the matcher examines.
@@ -577,6 +808,7 @@ final class FilesSet {
*/
private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
private static final long serialVersionUID = 1L;
private final String textToMatch;
/**
@@ -620,6 +852,7 @@ final class FilesSet {
*/
private static class CaseInsensitivePartialStringComparisionMatcher implements TextMatcher {
private static final long serialVersionUID = 1L;
private final String textToMatch;
private final Pattern pattern;
@@ -664,6 +897,7 @@ final class FilesSet {
*/
private static class RegexMatcher implements TextMatcher {
private static final long serialVersionUID = 1L;
private final Pattern regex;
/**
@@ -23,61 +23,82 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="ruleNameLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="ruleNameTextField" min="-2" pref="234" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="65" max="-2" attributes="0"/>
<Component id="filesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="filesAndDirsRadioButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="nameCheck" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="nameTextField" min="-2" pref="249" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="pathCheck" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="pathRegexCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="45" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="pathSeparatorInfoLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="pathTextField" alignment="0" min="-2" pref="239" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="ruleNameLabel" min="-2" pref="59" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="pathTextField" min="-2" pref="250" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
<Component id="fullNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="extensionRadioButton" min="-2" pref="114" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="nameRegexCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="filesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="filesAndDirsRadioButton" min="-2" max="-2" attributes="0"/>
<Component id="mimeCheck" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeCheck" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="equalitySymbolComboBox" min="-2" pref="36" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="fileSizeSpinner" min="-2" pref="94" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="fileSizeComboBox" min="-2" pref="82" max="-2" attributes="0"/>
</Group>
<Component id="ruleNameTextField" min="-2" pref="248" max="-2" attributes="0"/>
<Component id="mimeTypeComboBox" min="-2" pref="250" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="nameTextField" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="78" max="-2" attributes="0"/>
<Component id="fullNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="extensionRadioButton" min="-2" pref="114" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="nameRegexCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="jLabel4" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -85,17 +106,17 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" pref="19" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesAndDirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="nameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="nameCheck" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
@@ -106,20 +127,31 @@
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="pathTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="pathCheck" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="pathSeparatorInfoLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="pathRegexCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="pathSeparatorInfoLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace pref="8" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="mimeTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="mimeCheck" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="equalitySymbolComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeCheck" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="ruleNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ruleNameLabel" alignment="3" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -138,6 +170,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.ruleNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ruleNameTextFieldActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
@@ -146,17 +181,167 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="dirsRadioButton">
<Component class="javax.swing.JTextField" name="nameTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="fullNameRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="typeButtonGroup"/>
<ComponentRef name="nameButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.dirsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.fullNameRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fullNameRadioButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="extensionRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="nameButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.extensionRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="nameRegexCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameRegexCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="pathTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="pathRegexCheckBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathRegexCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="pathSeparatorInfoLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/info-icon-16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathSeparatorInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel5">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.jLabel5.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="mimeTypeComboBox">
<Properties>
<Property name="editable" type="boolean" value="true"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] {&quot;&quot;})" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox&lt;String&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JComboBox" name="equalitySymbolComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] { &quot;=&quot;, &quot;&gt;&quot;, &quot;&#x2265;&quot;, &quot;&lt;&quot;, &quot;&#x2264;&quot; })" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox&lt;String&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JComboBox" name="fileSizeComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] { Bundle.FilesSetRulePanel_bytes(), Bundle.FilesSetRulePanel_kiloBytes(), Bundle.FilesSetRulePanel_megaBytes(), Bundle.FilesSetRulePanel_gigaBytes() })" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox&lt;String&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JSpinner" name="fileSizeSpinner">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="0" minimum="0" numberType="java.lang.Integer" stepSize="1" type="number"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value=""/>
</AuxValues>
</Component>
<Component class="javax.swing.JCheckBox" name="nameCheck">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameCheck.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dirsRadioButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nameCheckActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="pathCheck">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathCheck.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pathCheckActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="mimeCheck">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.mimeCheck.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="mimeCheckActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="fileSizeCheck">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.fileSizeCheck.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileSizeCheckActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="filesRadioButton">
@@ -172,6 +357,19 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="filesRadioButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="dirsRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="typeButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.dirsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dirsRadioButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="filesAndDirsRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
@@ -185,91 +383,5 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="filesAndDirsRadioButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="nameTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="fullNameRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="nameButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.fullNameRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="extensionRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="nameButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.extensionRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="nameRegexCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.nameRegexCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="pathTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="pathRegexCheckBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathRegexCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="pathSeparatorInfoLabel">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/info-icon-16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.pathSeparatorInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel4">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel5">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.jLabel5.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -18,14 +18,27 @@
*/
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;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypes;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
/**
* A panel that allows a user to create and edit interesting files set
@@ -33,17 +46,34 @@ import org.sleuthkit.autopsy.coreutils.Logger;
*/
final class FilesSetRulePanel extends javax.swing.JPanel {
@Messages({
"FilesSetRulePanel.bytes=Bytes",
"FilesSetRulePanel.kiloBytes=Kilobytes",
"FilesSetRulePanel.megaBytes=Megabytes",
"FilesSetRulePanel.gigaBytes=Gigabytes",
"FilesSetRulePanel.NoConditionError=Must have at least one condition to make a rule.",
"FilesSetRulePanel.NoMimeTypeError=Please select a valid MIME type.",
"FilesSetRulePanel.NoNameError=Name cannot be empty",
"FilesSetRulePanel.NoPathError=Path cannot be empty",
"FilesSetRulePanel.ZeroFileSizeError=File size condition value must not be 0 (Unless = is selected)."
})
private static final SortedSet<MediaType> mediaTypes = MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry().getTypes();
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 = InterestingItemDefsManager.getIllegalFileNameChars();
private static final List<String> ILLEGAL_FILE_PATH_CHARS = InterestingItemDefsManager.getIllegalFilePathChars();
private JButton okButton;
private JButton cancelButton;
/**
* Constructs a files set rule panel in create rule mode.
*/
FilesSetRulePanel() {
FilesSetRulePanel(JButton okButton, JButton cancelButton) {
initComponents();
populateMimeTypesComboBox();
populateComponentsWithDefaultValues();
this.setButtons(okButton, cancelButton);
}
/**
@@ -51,12 +81,16 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
*
* @param rule The files set rule to be edited.
*/
FilesSetRulePanel(FilesSet.Rule rule) {
FilesSetRulePanel(FilesSet.Rule rule, JButton okButton, JButton cancelButton) {
initComponents();
populateMimeTypesComboBox();
populateRuleNameComponent(rule);
populateTypeFilterComponents(rule);
populateNameFilterComponents(rule);
populatePathFilterComponents(rule);
populateTypeConditionComponents(rule);
populateNameConditionComponents(rule);
populatePathConditionComponents(rule);
populateMimeConditionComponents(rule);
populateSizeConditionComponents(rule);
this.setButtons(okButton, cancelButton);
}
/**
@@ -65,6 +99,40 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
private void populateComponentsWithDefaultValues() {
this.filesRadioButton.setSelected(true);
this.fullNameRadioButton.setSelected(true);
this.equalitySymbolComboBox.setSelectedItem(FilesSet.Rule.FileSizeCondition.COMPARATOR.GREATER_THAN_EQUAL.getSymbol());
this.fileSizeComboBox.setSelectedItem(FilesSet.Rule.FileSizeCondition.SIZE_UNIT.KILOBYTE.getName());
this.mimeTypeComboBox.setSelectedIndex(0);
}
private void populateMimeTypesComboBox() {
Set<String> fileTypesCollated = new HashSet<>();
for (MediaType mediaType : mediaTypes) {
fileTypesCollated.add(mediaType.toString());
}
FileTypeDetector fileTypeDetector;
try {
fileTypeDetector = new FileTypeDetector();
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
fileTypesCollated.addAll(userDefinedFileTypes);
} 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);
}
this.setOkButton();
}
/**
@@ -76,14 +144,88 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
this.ruleNameTextField.setText(rule.getName());
}
private void populateMimeConditionComponents(FilesSet.Rule rule) {
FilesSet.Rule.MimeTypeCondition mimeTypeCondition = rule.getMimeTypeCondition();
if (mimeTypeCondition != null) {
this.mimeCheck.setSelected(true);
this.mimeCheckActionPerformed(null);
this.mimeTypeComboBox.setSelectedItem(mimeTypeCondition.getMimeType());
}
}
private void populateSizeConditionComponents(FilesSet.Rule rule) {
FilesSet.Rule.FileSizeCondition fileSizeCondition = rule.getFileSizeCondition();
if (fileSizeCondition != null) {
this.fileSizeCheck.setSelected(true);
this.fileSizeCheckActionPerformed(null);
this.fileSizeSpinner.setValue(fileSizeCondition.getSizeValue());
this.fileSizeComboBox.setSelectedItem(fileSizeCondition.getUnit().getName());
this.equalitySymbolComboBox.setSelectedItem(fileSizeCondition.getComparator().getSymbol());
}
}
/**
* Populates the UI components that display the meta-type filter for a rule.
* Sets whether or not the OK button should be enabled based upon other UI
* elements
*/
private void setOkButton() {
if (this.okButton != null) {
this.okButton.setEnabled(this.fileSizeCheck.isSelected() || this.mimeCheck.isSelected()
|| this.nameCheck.isSelected() || this.pathCheck.isSelected());
}
}
/**
* Gets the JOptionPane that is used to contain this panel if there is one
*
* @param parent
*
* @return
*/
private JOptionPane getOptionPane(JComponent parent) {
JOptionPane pane = null;
if (!(parent instanceof JOptionPane)) {
pane = getOptionPane((JComponent) parent.getParent());
} else {
pane = (JOptionPane) parent;
}
return pane;
}
/**
* Sets the buttons for ending the panel
*
* @param ok The ok button
* @param cancel The cancel button
*/
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);
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane(cancelButton);
pane.setValue(cancelButton);
}
});
this.setOkButton();
}
/**
* Populates the UI components that display the meta-type condition for a
* rule.
*
* @param rule The files set rule to be edited.
*/
private void populateTypeFilterComponents(FilesSet.Rule rule) {
FilesSet.Rule.MetaTypeFilter typeFilter = rule.getMetaTypeFilter();
switch (typeFilter.getMetaType()) {
private void populateTypeConditionComponents(FilesSet.Rule rule) {
FilesSet.Rule.MetaTypeCondition typeCondition = rule.getMetaTypeCondition();
switch (typeCondition.getMetaType()) {
case FILES:
this.filesRadioButton.setSelected(true);
break;
@@ -97,32 +239,38 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
/**
* Populates the UI components that display the name filter for a rule.
* Populates the UI components that display the name condition for a rule.
*
* @param rule The files set rule to be edited.
*/
private void populateNameFilterComponents(FilesSet.Rule rule) {
FilesSet.Rule.FileNameFilter nameFilter = rule.getFileNameFilter();
this.nameTextField.setText(nameFilter.getTextToMatch());
this.nameRegexCheckbox.setSelected(nameFilter.isRegex());
if (nameFilter instanceof FilesSet.Rule.FullNameFilter) {
this.fullNameRadioButton.setSelected(true);
} else {
this.extensionRadioButton.setSelected(true);
private void populateNameConditionComponents(FilesSet.Rule rule) {
FilesSet.Rule.FileNameCondition nameCondition = rule.getFileNameCondition();
if (nameCondition != null) {
this.nameCheck.setSelected(true);
this.nameCheckActionPerformed(null);
this.nameTextField.setText(nameCondition.getTextToMatch());
this.nameRegexCheckbox.setSelected(nameCondition.isRegex());
if (nameCondition instanceof FilesSet.Rule.FullNameCondition) {
this.fullNameRadioButton.setSelected(true);
} else {
this.extensionRadioButton.setSelected(true);
}
}
}
/**
* Populates the UI components that display the optional path filter for a
* rule.
* Populates the UI components that display the optional path condition for
* a rule.
*
* @param rule The files set rule to be edited.
*/
private void populatePathFilterComponents(FilesSet.Rule rule) {
FilesSet.Rule.ParentPathFilter pathFilter = rule.getPathFilter();
if (pathFilter != null) {
this.pathTextField.setText(pathFilter.getTextToMatch());
this.pathRegexCheckBox.setSelected(pathFilter.isRegex());
private void populatePathConditionComponents(FilesSet.Rule rule) {
FilesSet.Rule.ParentPathCondition pathCondition = rule.getPathCondition();
if (pathCondition != null) {
this.pathCheck.setSelected(true);
this.pathCheckActionPerformed(null);
this.pathTextField.setText(pathCondition.getTextToMatch());
this.pathRegexCheckBox.setSelected(pathCondition.isRegex());
}
}
@@ -135,40 +283,55 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
*/
boolean isValidRuleDefinition() {
// The rule must have name filter text.
if (this.nameTextField.getText().isEmpty()) {
if (!(this.mimeCheck.isSelected() || this.fileSizeCheck.isSelected() || this.pathCheck.isSelected() || this.nameCheck.isSelected())) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.emptyNameFilter"),
Bundle.FilesSetRulePanel_NoConditionError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
// The name filter must either be a regular expression that compiles or
// a string without illegal file name chars.
if (this.nameRegexCheckbox.isSelected()) {
try {
Pattern.compile(this.nameTextField.getText());
} catch (PatternSyntaxException ex) {
if (this.nameCheck.isSelected()) {
// The name condition must either be a regular expression that compiles or
// a string without illegal file name chars.
if (this.nameTextField.getText().isEmpty()) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidNameRegex", ex.getLocalizedMessage()),
Bundle.FilesSetRulePanel_NoNameError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
} else {
if (!FilesSetRulePanel.containsOnlyLegalChars(this.nameTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_NAME_CHARS)) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidCharInName"),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
if (this.nameRegexCheckbox.isSelected()) {
try {
Pattern.compile(this.nameTextField.getText());
} catch (PatternSyntaxException ex) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidNameRegex", ex.getLocalizedMessage()),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
} else {
if (this.nameTextField.getText().isEmpty() || !FilesSetRulePanel.containsOnlyLegalChars(this.nameTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_NAME_CHARS)) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidCharInName"),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
}
}
// The path filter, if specified, must either be a regular expression
// that compiles or a string without illegal file path chars.
if (!this.pathTextField.getText().isEmpty()) {
// The path condition, if specified, must either be a regular expression
// that compiles or a string without illegal file path chars.
if (this.pathCheck.isSelected()) {
if (this.pathTextField.getText().isEmpty()) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
Bundle.FilesSetRulePanel_NoPathError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
if (this.pathRegexCheckBox.isSelected()) {
try {
Pattern.compile(this.pathTextField.getText());
@@ -180,7 +343,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
return false;
}
} else {
if (!FilesSetRulePanel.containsOnlyLegalChars(this.pathTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_PATH_CHARS)) {
if (this.pathTextField.getText().isEmpty() || !FilesSetRulePanel.containsOnlyLegalChars(this.pathTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_PATH_CHARS)) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidCharInPath"),
NotifyDescriptor.WARNING_MESSAGE);
@@ -189,6 +352,24 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
}
}
if (this.mimeCheck.isSelected()) {
if (this.mimeTypeComboBox.getSelectedIndex() == 0) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
Bundle.FilesSetRulePanel_NoMimeTypeError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
}
if (this.fileSizeCheck.isSelected()) {
if ((Integer) this.fileSizeSpinner.getValue() == 0 && !((String)this.equalitySymbolComboBox.getSelectedItem()).equals("=")) {
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
Bundle.FilesSetRulePanel_ZeroFileSizeError(),
NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(notifyDesc);
return false;
}
}
return true;
}
@@ -203,76 +384,108 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
/**
* Gets the name filter for the rule that was created or edited. Should only
* be called if isValidDefintion() returns true.
* Gets the name condition for the rule that was created or edited. Should
* only be called if isValidDefintion() returns true.
*
* @return A name filter.
* @return A name condition.
*
* @throws IllegalStateException if the specified name filter is not valid.
* @throws IllegalStateException if the specified name condition is not
* valid.
*/
FilesSet.Rule.FileNameFilter getFileNameFilter() throws IllegalStateException {
FilesSet.Rule.FileNameFilter filter = null;
FilesSet.Rule.FileNameCondition getFileNameCondition() throws IllegalStateException {
FilesSet.Rule.FileNameCondition condition = null;
if (!this.nameTextField.getText().isEmpty()) {
if (this.nameRegexCheckbox.isSelected()) {
try {
Pattern pattern = Pattern.compile(this.nameTextField.getText());
if (this.fullNameRadioButton.isSelected()) {
filter = new FilesSet.Rule.FullNameFilter(pattern);
condition = new FilesSet.Rule.FullNameCondition(pattern);
} else {
filter = new FilesSet.Rule.ExtensionFilter(pattern);
condition = new FilesSet.Rule.ExtensionCondition(pattern);
}
} catch (PatternSyntaxException ex) {
logger.log(Level.SEVERE, "Attempt to get regex name filter that does not compile", ex); // NON-NLS
throw new IllegalStateException("The files set rule panel name filter is not in a valid state"); // NON-NLS
logger.log(Level.SEVERE, "Attempt to get regex name condition that does not compile", ex); // NON-NLS
throw new IllegalStateException("The files set rule panel name condition is not in a valid state"); // NON-NLS
}
} else {
if (FilesSetRulePanel.containsOnlyLegalChars(this.nameTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_NAME_CHARS)) {
if (this.fullNameRadioButton.isSelected()) {
filter = new FilesSet.Rule.FullNameFilter(this.nameTextField.getText());
condition = new FilesSet.Rule.FullNameCondition(this.nameTextField.getText());
} else {
filter = new FilesSet.Rule.ExtensionFilter(this.nameTextField.getText());
condition = new FilesSet.Rule.ExtensionCondition(this.nameTextField.getText());
}
} else {
logger.log(Level.SEVERE, "Attempt to get name filter with illegal chars"); // NON-NLS
throw new IllegalStateException("The files set rule panel name filter is not in a valid state"); // NON-NLS
logger.log(Level.SEVERE, "Attempt to get name condition with illegal chars"); // NON-NLS
throw new IllegalStateException("The files set rule panel name condition is not in a valid state"); // NON-NLS
}
}
}
return filter;
return condition;
}
/**
* Gets the file meta-type filter for the rule that was created or edited.
* Gets the mime type condition based upon the panel input
*
* @return A type filter.
* @return the mime type condition, null if no condition is specified
*/
FilesSet.Rule.MetaTypeFilter getMetaTypeFilter() {
FilesSet.Rule.MimeTypeCondition getMimeTypeCondition() {
FilesSet.Rule.MimeTypeCondition condition = null;
if (!this.mimeTypeComboBox.getSelectedItem().equals("")) {
condition = new FilesSet.Rule.MimeTypeCondition((String) this.mimeTypeComboBox.getSelectedItem());
}
return condition;
}
/**
* Gets the file size condition created based upon the panel input
*
* @return the file size condition, null if no condition is specified
*/
FilesSet.Rule.FileSizeCondition getFileSizeCondition() {
FilesSet.Rule.FileSizeCondition condition = null;
if ((Integer) this.fileSizeSpinner.getValue() != 0 || ((String)this.equalitySymbolComboBox.getSelectedItem()).equals("=")) {
FilesSet.Rule.FileSizeCondition.COMPARATOR comparator = FilesSet.Rule.FileSizeCondition.COMPARATOR.fromSymbol((String) this.equalitySymbolComboBox.getSelectedItem());
FilesSet.Rule.FileSizeCondition.SIZE_UNIT unit = FilesSet.Rule.FileSizeCondition.SIZE_UNIT.fromName((String) this.fileSizeComboBox.getSelectedItem());
int fileSizeValue = (Integer) this.fileSizeSpinner.getValue();
condition = new FilesSet.Rule.FileSizeCondition(comparator, unit, fileSizeValue);
}
return condition;
}
/**
* Gets the file meta-type condition for the rule that was created or
* edited.
*
* @return A type condition.
*/
FilesSet.Rule.MetaTypeCondition getMetaTypeCondition() {
if (this.filesRadioButton.isSelected()) {
return new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
return new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES);
} else if (this.dirsRadioButton.isSelected()) {
return new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.DIRECTORIES);
return new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.DIRECTORIES);
} else {
return new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES_AND_DIRECTORIES);
return new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES_AND_DIRECTORIES);
}
}
/**
* Gets the optional path filter for the rule that was created or edited.
* Gets the optional path condition for the rule that was created or edited.
* Should only be called if isValidDefintion() returns true.
*
* @return A path filter or null if no path filter was specified.
* @return A path condition or null if no path condition was specified.
*
* @throws IllegalStateException if the specified path filter is not valid.
* @throws IllegalStateException if the specified path condition is not
* valid.
*/
FilesSet.Rule.ParentPathFilter getPathFilter() throws IllegalStateException {
FilesSet.Rule.ParentPathFilter filter = null;
FilesSet.Rule.ParentPathCondition getPathCondition() throws IllegalStateException {
FilesSet.Rule.ParentPathCondition condition = null;
if (!this.pathTextField.getText().isEmpty()) {
if (this.pathRegexCheckBox.isSelected()) {
try {
filter = new FilesSet.Rule.ParentPathFilter(Pattern.compile(this.pathTextField.getText()));
condition = new FilesSet.Rule.ParentPathCondition(Pattern.compile(this.pathTextField.getText()));
} catch (PatternSyntaxException ex) {
logger.log(Level.SEVERE, "Attempt to get malformed path filter", ex); // NON-NLS
throw new IllegalStateException("The files set rule panel path filter is not in a valid state"); // NON-NLS
logger.log(Level.SEVERE, "Attempt to get malformed path condition", ex); // NON-NLS
throw new IllegalStateException("The files set rule panel path condition is not in a valid state"); // NON-NLS
}
} else {
String path = this.pathTextField.getText();
@@ -285,14 +498,14 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
if (!path.endsWith(FilesSetRulePanel.SLEUTHKIT_PATH_SEPARATOR)) {
path += FilesSetRulePanel.SLEUTHKIT_PATH_SEPARATOR;
}
filter = new FilesSet.Rule.ParentPathFilter(path);
condition = new FilesSet.Rule.ParentPathCondition(path);
} else {
logger.log(Level.SEVERE, "Attempt to get path filter with illegal chars"); // NON-NLS
throw new IllegalStateException("The files set rule panel path filter is not in a valid state"); // NON-NLS
logger.log(Level.SEVERE, "Attempt to get path condition with illegal chars"); // NON-NLS
throw new IllegalStateException("The files set rule panel path condition is not in a valid state"); // NON-NLS
}
}
}
return filter;
return condition;
}
/**
@@ -314,15 +527,28 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
/**
* Sets the state of the name filter UI components consistent with the state
* of the UI components in the type button group.
* Sets the state of the name condition UI components consistent with the
* state of the UI components in the type button group.
*/
private void setComponentsForSearchType() {
if (!this.filesRadioButton.isSelected()) {
this.fullNameRadioButton.setSelected(true);
this.extensionRadioButton.setEnabled(false);
this.mimeTypeComboBox.setEnabled(false);
this.mimeTypeComboBox.setSelectedIndex(0);
this.equalitySymbolComboBox.setEnabled(false);
this.fileSizeComboBox.setEnabled(false);
this.fileSizeSpinner.setEnabled(false);
this.fileSizeSpinner.setValue(0);
this.fileSizeCheck.setEnabled(false);
this.fileSizeCheck.setSelected(false);
this.mimeCheck.setEnabled(false);
this.mimeCheck.setSelected(false);
} else {
this.extensionRadioButton.setEnabled(true);
this.fileSizeCheck.setEnabled(true);
this.mimeCheck.setEnabled(true);
}
}
@@ -340,32 +566,106 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
ruleNameLabel = new javax.swing.JLabel();
ruleNameTextField = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
dirsRadioButton = new javax.swing.JRadioButton();
filesRadioButton = new javax.swing.JRadioButton();
filesAndDirsRadioButton = new javax.swing.JRadioButton();
jLabel2 = new javax.swing.JLabel();
nameTextField = new javax.swing.JTextField();
fullNameRadioButton = new javax.swing.JRadioButton();
extensionRadioButton = new javax.swing.JRadioButton();
nameRegexCheckbox = new javax.swing.JCheckBox();
jLabel3 = new javax.swing.JLabel();
pathTextField = new javax.swing.JTextField();
pathRegexCheckBox = new javax.swing.JCheckBox();
pathSeparatorInfoLabel = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
jLabel5 = new javax.swing.JLabel();
mimeTypeComboBox = new javax.swing.JComboBox<String>();
equalitySymbolComboBox = new javax.swing.JComboBox<String>();
fileSizeComboBox = new javax.swing.JComboBox<String>();
fileSizeSpinner = new javax.swing.JSpinner();
nameCheck = new javax.swing.JCheckBox();
pathCheck = new javax.swing.JCheckBox();
mimeCheck = new javax.swing.JCheckBox();
fileSizeCheck = new javax.swing.JCheckBox();
filesRadioButton = new javax.swing.JRadioButton();
dirsRadioButton = new javax.swing.JRadioButton();
filesAndDirsRadioButton = new javax.swing.JRadioButton();
org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameLabel.text")); // NOI18N
ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameTextField.text")); // NOI18N
ruleNameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ruleNameTextFieldActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel1.text")); // NOI18N
typeButtonGroup.add(dirsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(dirsRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.dirsRadioButton.text")); // NOI18N
dirsRadioButton.addActionListener(new java.awt.event.ActionListener() {
nameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameTextField.text")); // NOI18N
nameTextField.setEnabled(false);
nameButtonGroup.add(fullNameRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(fullNameRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.fullNameRadioButton.text")); // NOI18N
fullNameRadioButton.setEnabled(false);
fullNameRadioButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dirsRadioButtonActionPerformed(evt);
fullNameRadioButtonActionPerformed(evt);
}
});
nameButtonGroup.add(extensionRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(extensionRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.extensionRadioButton.text")); // NOI18N
extensionRadioButton.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(nameRegexCheckbox, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameRegexCheckbox.text")); // NOI18N
nameRegexCheckbox.setEnabled(false);
pathTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathTextField.text")); // NOI18N
pathTextField.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(pathRegexCheckBox, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathRegexCheckBox.text")); // NOI18N
pathRegexCheckBox.setEnabled(false);
pathSeparatorInfoLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/info-icon-16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(pathSeparatorInfoLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathSeparatorInfoLabel.text")); // NOI18N
pathSeparatorInfoLabel.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel5.text")); // NOI18N
mimeTypeComboBox.setEditable(true);
mimeTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] {""}));
mimeTypeComboBox.setEnabled(false);
equalitySymbolComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { "=", ">", "≥", "<", "≤" }));
equalitySymbolComboBox.setEnabled(false);
fileSizeComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { Bundle.FilesSetRulePanel_bytes(), Bundle.FilesSetRulePanel_kiloBytes(), Bundle.FilesSetRulePanel_megaBytes(), Bundle.FilesSetRulePanel_gigaBytes() }));
fileSizeComboBox.setEnabled(false);
fileSizeSpinner.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(0), Integer.valueOf(0), null, Integer.valueOf(1)));
fileSizeSpinner.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(nameCheck, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameCheck.text")); // NOI18N
nameCheck.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nameCheckActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(pathCheck, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathCheck.text")); // NOI18N
pathCheck.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pathCheckActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(mimeCheck, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.mimeCheck.text")); // NOI18N
mimeCheck.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
mimeCheckActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(fileSizeCheck, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.fileSizeCheck.text")); // NOI18N
fileSizeCheck.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
fileSizeCheckActionPerformed(evt);
}
});
@@ -377,6 +677,14 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
});
typeButtonGroup.add(dirsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(dirsRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.dirsRadioButton.text")); // NOI18N
dirsRadioButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dirsRadioButtonActionPerformed(evt);
}
});
typeButtonGroup.add(filesAndDirsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(filesAndDirsRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.filesAndDirsRadioButton.text")); // NOI18N
filesAndDirsRadioButton.addActionListener(new java.awt.event.ActionListener() {
@@ -385,93 +693,85 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
}
});
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel2.text")); // NOI18N
nameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameTextField.text")); // NOI18N
nameButtonGroup.add(fullNameRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(fullNameRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.fullNameRadioButton.text")); // NOI18N
nameButtonGroup.add(extensionRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(extensionRadioButton, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.extensionRadioButton.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(nameRegexCheckbox, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.nameRegexCheckbox.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel3.text")); // NOI18N
pathTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathTextField.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(pathRegexCheckBox, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathRegexCheckBox.text")); // NOI18N
pathSeparatorInfoLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/info-icon-16.png"))); // NOI18N NON-NLS
org.openide.awt.Mnemonics.setLocalizedText(pathSeparatorInfoLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.pathSeparatorInfoLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel4.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel5.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel3)
.addGap(18, 18, 18)
.addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 234, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(65, 65, 65)
.addComponent(filesRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dirsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filesAndDirsRadioButton)))
.addGap(0, 0, Short.MAX_VALUE))))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(nameCheck)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(pathCheck)
.addGap(4, 4, 4)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(pathRegexCheckBox)
.addGap(45, 45, 45)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pathSeparatorInfoLabel))
.addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 239, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(ruleNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18))
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(27, 27, 27)))
.addComponent(fullNameRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(nameRegexCheckbox)
.addGap(0, 0, Short.MAX_VALUE))))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(mimeCheck)
.addComponent(fileSizeCheck))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(filesRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dirsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(filesAndDirsRadioButton))
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 248, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(nameTextField))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(78, 78, 78)
.addComponent(fullNameRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(nameRegexCheckbox)))
.addComponent(jLabel4)
.addComponent(jLabel5))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(equalitySymbolComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, 19, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(dirsRadioButton)
.addComponent(filesRadioButton)
.addComponent(dirsRadioButton)
.addComponent(filesAndDirsRadioButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGap(5, 5, 5)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(nameCheck))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(fullNameRadioButton)
@@ -480,46 +780,123 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel3))
.addComponent(pathCheck))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(pathSeparatorInfoLabel)
.addComponent(pathRegexCheckBox))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(pathRegexCheckBox)
.addComponent(pathSeparatorInfoLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(mimeCheck))
.addGap(11, 11, 11)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(equalitySymbolComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeCheck))
.addGap(15, 15, 15)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel4))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void filesAndDirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesAndDirsRadioButtonActionPerformed
setComponentsForSearchType();
}//GEN-LAST:event_filesAndDirsRadioButtonActionPerformed
private void ruleNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ruleNameTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_ruleNameTextFieldActionPerformed
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed
setComponentsForSearchType();
}//GEN-LAST:event_dirsRadioButtonActionPerformed
private void nameCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameCheckActionPerformed
if (!this.nameCheck.isSelected()) {
this.nameTextField.setEnabled(false);
this.nameTextField.setText("");
this.fullNameRadioButton.setEnabled(false);
this.extensionRadioButton.setEnabled(false);
this.nameRegexCheckbox.setEnabled(false);
} else {
this.nameTextField.setEnabled(true);
this.fullNameRadioButton.setEnabled(true);
this.extensionRadioButton.setEnabled(true);
this.nameRegexCheckbox.setEnabled(true);
}
this.setOkButton();
}//GEN-LAST:event_nameCheckActionPerformed
private void pathCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pathCheckActionPerformed
if (!this.pathCheck.isSelected()) {
this.pathTextField.setEnabled(false);
this.pathTextField.setText("");
this.pathRegexCheckBox.setEnabled(false);
this.pathSeparatorInfoLabel.setEnabled(false);
} else {
this.pathTextField.setEnabled(true);
this.pathRegexCheckBox.setEnabled(true);
this.pathSeparatorInfoLabel.setEnabled(true);
}
this.setOkButton();
}//GEN-LAST:event_pathCheckActionPerformed
private void mimeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeCheckActionPerformed
if (!this.mimeCheck.isSelected()) {
this.mimeTypeComboBox.setEnabled(false);
this.mimeTypeComboBox.setSelectedIndex(0);
} else {
this.mimeTypeComboBox.setEnabled(true);
}
this.setOkButton();
}//GEN-LAST:event_mimeCheckActionPerformed
private void fileSizeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileSizeCheckActionPerformed
if (!this.fileSizeCheck.isSelected()) {
this.fileSizeComboBox.setEnabled(false);
this.fileSizeSpinner.setEnabled(false);
this.fileSizeSpinner.setValue(0);
this.equalitySymbolComboBox.setEnabled(false);
} else {
this.fileSizeComboBox.setEnabled(true);
this.fileSizeSpinner.setEnabled(true);
this.equalitySymbolComboBox.setEnabled(true);
}
this.setOkButton();
}//GEN-LAST:event_fileSizeCheckActionPerformed
private void filesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioButtonActionPerformed
setComponentsForSearchType();
this.setComponentsForSearchType();
}//GEN-LAST:event_filesRadioButtonActionPerformed
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed
this.setComponentsForSearchType();
}//GEN-LAST:event_dirsRadioButtonActionPerformed
private void filesAndDirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesAndDirsRadioButtonActionPerformed
this.setComponentsForSearchType();
}//GEN-LAST:event_filesAndDirsRadioButtonActionPerformed
private void fullNameRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fullNameRadioButtonActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_fullNameRadioButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton dirsRadioButton;
private javax.swing.JComboBox<String> equalitySymbolComboBox;
private javax.swing.JRadioButton extensionRadioButton;
private javax.swing.JCheckBox fileSizeCheck;
private javax.swing.JComboBox<String> fileSizeComboBox;
private javax.swing.JSpinner fileSizeSpinner;
private javax.swing.JRadioButton filesAndDirsRadioButton;
private javax.swing.JRadioButton filesRadioButton;
private javax.swing.JRadioButton fullNameRadioButton;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JCheckBox mimeCheck;
private javax.swing.JComboBox<String> mimeTypeComboBox;
private javax.swing.ButtonGroup nameButtonGroup;
private javax.swing.JCheckBox nameCheck;
private javax.swing.JCheckBox nameRegexCheckbox;
private javax.swing.JTextField nameTextField;
private javax.swing.JCheckBox pathCheck;
private javax.swing.JCheckBox pathRegexCheckBox;
private javax.swing.JLabel pathSeparatorInfoLabel;
private javax.swing.JTextField pathTextField;
@@ -19,6 +19,9 @@
package org.sleuthkit.autopsy.modules.interestingitems;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -29,9 +32,8 @@ import java.util.Observable;
import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.openide.util.io.NbObjectInputStream;
import org.openide.util.io.NbObjectOutputStream;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
@@ -49,8 +51,10 @@ final class InterestingItemDefsManager extends Observable {
private static final List<String> ILLEGAL_FILE_NAME_CHARS = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("\\", "/", ":", "*", "?", "\"", "<", ">")));
private static final List<String> ILLEGAL_FILE_PATH_CHARS = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("\\", ":", "*", "?", "\"", "<", ">")));
private static final String INTERESTING_FILES_SET_DEFS_FILE_NAME = "InterestingFilesSetDefs.xml"; //NON-NLS
private static final String DEFAULT_FILE_SET_DEFS_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + INTERESTING_FILES_SET_DEFS_FILE_NAME;
private static final String LEGACY_FILES_SET_DEFS_FILE_NAME = "InterestingFilesSetDefs.xml"; //NON-NLS
private static final String INTERESTING_FILES_SET_DEFS_SERIALIZATION_NAME = "InterestingFileSets.settings";
private static final String INTERESTING_FILES_SET_DEFS_SERIALIZATION_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + INTERESTING_FILES_SET_DEFS_SERIALIZATION_NAME;
private static final String LEGACY_FILE_SET_DEFS_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + LEGACY_FILES_SET_DEFS_FILE_NAME;
private static InterestingItemDefsManager instance;
/**
@@ -88,8 +92,8 @@ final class InterestingItemDefsManager extends Observable {
* @return A map of interesting files set names to interesting file sets,
* possibly empty.
*/
synchronized Map<String, FilesSet> getInterestingFilesSets() {
return FilesSetXML.readDefinitionsFile(DEFAULT_FILE_SET_DEFS_PATH);
synchronized Map<String, FilesSet> getInterestingFilesSets() throws InterestingItemDefsManagerException {
return FilesSetXML.readDefinitionsFile(LEGACY_FILE_SET_DEFS_PATH);
}
/**
@@ -99,8 +103,8 @@ final class InterestingItemDefsManager extends Observable {
* @param filesSets A mapping of interesting files set names to files sets,
* used to enforce unique files set names.
*/
synchronized void setInterestingFilesSets(Map<String, FilesSet> filesSets) {
FilesSetXML.writeDefinitionsFile(DEFAULT_FILE_SET_DEFS_PATH, filesSets);
synchronized void setInterestingFilesSets(Map<String, FilesSet> filesSets) throws InterestingItemDefsManagerException {
FilesSetXML.writeDefinitionsFile(INTERESTING_FILES_SET_DEFS_SERIALIZATION_PATH, filesSets);
this.setChanged();
this.notifyObservers();
}
@@ -130,21 +134,6 @@ final class InterestingItemDefsManager extends Observable {
private static final String TYPE_FILTER_VALUE_FILES = "file"; //NON-NLS
private static final String TYPE_FILTER_VALUE_DIRS = "dir"; //NON-NLS
// The following tags and attributes are currently specific to the
// Autopsy implementation of interesting files set definitions. Autopsy
// definitions that use these will not be able to be used by TSK
// Framework. However, Autopsy can accept TSK Framework definitions:
//
// 1. Rules do not have names in the TSK Framework schema, but rules do
// have names in the Autopsy schema. Names will be synthesized as needed
// to allow Autopsy to use TSK Framework interesting files set
// definitions.
// 2. The TSK Framework has an interesting files module that supports
// simple globbing with "*" characters. Name rules and path filters with
// "*" characters will be converted to regexes to allow Autopsy to use
// TSK Framework interesting files set definitions.
// 3. Type filters are required by Autopsy, but not by TSK Frmaework.
// Missing type filters will defualt to "files" filters.
private static final String REGEX_ATTR = "regex"; //NON-NLS
private static final String PATH_REGEX_ATTR = "pathRegex"; //NON-NLS
private static final String TYPE_FILTER_VALUE_FILES_AND_DIRS = "files_and_dirs"; //NON-NLS
@@ -161,10 +150,13 @@ final class InterestingItemDefsManager extends Observable {
// Note: This method takes a file path to support the possibility of
// multiple intersting files set definition files, e.g., one for
// definitions that ship with Autopsy and one for user definitions.
static Map<String, FilesSet> readDefinitionsFile(String filePath) {
Map<String, FilesSet> filesSets = new HashMap<>();
static Map<String, FilesSet> readDefinitionsFile(String filePath) throws InterestingItemDefsManagerException {
Map<String, FilesSet> filesSets = readSerializedDefinitions();
// Check if the file exists.
if (!filesSets.isEmpty()) {
return filesSets;
}
// Check if the legacy xml file exists.
File defsFile = new File(filePath);
if (!defsFile.exists()) {
return filesSets;
@@ -195,10 +187,34 @@ final class InterestingItemDefsManager extends Observable {
for (int i = 0; i < setElems.getLength(); ++i) {
readFilesSet((Element) setElems.item(i), filesSets, filePath);
}
return filesSets;
}
/**
* Reads the definitions from the serialization file
*
* @return the map representing settings saved to serialization file,
* empty set if the file does not exist.
*
* @throws InterestingItemDefsManagerException if file could not be read
*/
private static Map<String, FilesSet> readSerializedDefinitions() throws InterestingItemDefsManagerException {
String filePath = INTERESTING_FILES_SET_DEFS_SERIALIZATION_PATH;
File fileSetFile = new File(filePath);
if (fileSetFile.exists()) {
try {
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath))) {
InterestingItemsFilesSetSettings filesSetsSettings = (InterestingItemsFilesSetSettings) in.readObject();
return filesSetsSettings.getFilesSets();
}
} catch (IOException | ClassNotFoundException ex) {
throw new InterestingItemDefsManagerException(String.format("Failed to read settings from %s", filePath), ex);
}
} else {
return new HashMap<String, FilesSet>();
}
}
/**
* Reads in an interesting files set.
*
@@ -288,16 +304,16 @@ final class InterestingItemDefsManager extends Observable {
private static FilesSet.Rule readFileNameRule(Element elem) {
String ruleName = FilesSetXML.readRuleName(elem);
// The content of the rule tag is a file name filter. It may be a
// The content of the rule tag is a file name condition. It may be a
// regex, or it may be from a TSK Framework rule definition with a
// "*" globbing char, or it may be simple text.
String content = elem.getTextContent();
FilesSet.Rule.FullNameFilter nameFilter;
FilesSet.Rule.FullNameCondition nameCondition;
String regex = elem.getAttribute(FilesSetXML.REGEX_ATTR);
if ((!regex.isEmpty() && regex.equalsIgnoreCase("true")) || content.contains("*")) { // NON-NLS
Pattern pattern = compileRegex(content);
if (pattern != null) {
nameFilter = new FilesSet.Rule.FullNameFilter(pattern);
nameCondition = new FilesSet.Rule.FullNameCondition(pattern);
} else {
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.NAME_RULE_TAG + " regex, ignoring malformed '{0}' rule definition", ruleName); // NON-NLS
return null;
@@ -309,29 +325,29 @@ final class InterestingItemDefsManager extends Observable {
return null;
}
}
nameFilter = new FilesSet.Rule.FullNameFilter(content);
nameCondition = new FilesSet.Rule.FullNameCondition(content);
}
// Read in the type filter.
FilesSet.Rule.MetaTypeFilter metaTypeFilter = FilesSetXML.readMetaTypeFilter(elem);
if (metaTypeFilter == null) {
// Read in the type condition.
FilesSet.Rule.MetaTypeCondition metaTypeCondition = FilesSetXML.readMetaTypeCondition(elem);
if (metaTypeCondition == null) {
// Malformed attribute.
return null;
}
// Read in the optional path filter. Null is o.k., but if the attribute
// Read in the optional path condition. Null is o.k., but if the attribute
// is there, be sure it is not malformed.
FilesSet.Rule.ParentPathFilter pathFilter = null;
FilesSet.Rule.ParentPathCondition pathCondition = null;
if (!elem.getAttribute(FilesSetXML.PATH_FILTER_ATTR).isEmpty()
|| !elem.getAttribute(FilesSetXML.PATH_REGEX_ATTR).isEmpty()) {
pathFilter = FilesSetXML.readPathFilter(elem);
if (pathFilter == null) {
pathCondition = FilesSetXML.readPathCondition(elem);
if (pathCondition == null) {
// Malformed attribute.
return null;
}
}
return new FilesSet.Rule(ruleName, nameFilter, metaTypeFilter, pathFilter);
return new FilesSet.Rule(ruleName, nameCondition, metaTypeCondition, pathCondition, null, null);
}
/**
@@ -346,16 +362,16 @@ final class InterestingItemDefsManager extends Observable {
private static FilesSet.Rule readFileExtensionRule(Element elem) {
String ruleName = FilesSetXML.readRuleName(elem);
// The content of the rule tag is a file name extension filter. It may
// The content of the rule tag is a file name extension condition. It may
// be a regex, or it may be from a TSK Framework rule definition
// with a "*" globbing char.
String content = elem.getTextContent();
FilesSet.Rule.ExtensionFilter extFilter;
FilesSet.Rule.ExtensionCondition extCondition;
String regex = elem.getAttribute(FilesSetXML.REGEX_ATTR);
if ((!regex.isEmpty() && regex.equalsIgnoreCase("true")) || content.contains("*")) { // NON-NLS
Pattern pattern = compileRegex(content);
if (pattern != null) {
extFilter = new FilesSet.Rule.ExtensionFilter(pattern);
extCondition = new FilesSet.Rule.ExtensionCondition(pattern);
} else {
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.EXTENSION_RULE_TAG + " regex, ignoring malformed {0} rule definition", ruleName); // NON-NLS
return null;
@@ -367,35 +383,35 @@ final class InterestingItemDefsManager extends Observable {
return null;
}
}
extFilter = new FilesSet.Rule.ExtensionFilter(content);
extCondition = new FilesSet.Rule.ExtensionCondition(content);
}
// The rule must have a meta-type filter, unless a TSK Framework
// The rule must have a meta-type condition, unless a TSK Framework
// definitions file is being read.
FilesSet.Rule.MetaTypeFilter metaTypeFilter = null;
FilesSet.Rule.MetaTypeCondition metaTypeCondition = null;
if (!elem.getAttribute(FilesSetXML.TYPE_FILTER_ATTR).isEmpty()) {
metaTypeFilter = FilesSetXML.readMetaTypeFilter(elem);
if (metaTypeFilter == null) {
metaTypeCondition = FilesSetXML.readMetaTypeCondition(elem);
if (metaTypeCondition == null) {
// Malformed attribute.
return null;
}
} else {
metaTypeFilter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
metaTypeCondition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES);
}
// The rule may have a path filter. Null is o.k., but if the attribute
// The rule may have a path condition. Null is o.k., but if the attribute
// is there, it must not be malformed.
FilesSet.Rule.ParentPathFilter pathFilter = null;
FilesSet.Rule.ParentPathCondition pathCondition = null;
if (!elem.getAttribute(FilesSetXML.PATH_FILTER_ATTR).isEmpty()
|| !elem.getAttribute(FilesSetXML.PATH_REGEX_ATTR).isEmpty()) {
pathFilter = FilesSetXML.readPathFilter(elem);
if (pathFilter == null) {
pathCondition = FilesSetXML.readPathCondition(elem);
if (pathCondition == null) {
// Malformed attribute.
return null;
}
}
return new FilesSet.Rule(ruleName, extFilter, metaTypeFilter, pathFilter);
return new FilesSet.Rule(ruleName, extCondition, metaTypeCondition, pathCondition, null, null);
}
/**
@@ -428,62 +444,63 @@ final class InterestingItemDefsManager extends Observable {
}
/**
* Construct a meta-type filter for an interesting files set membership
* rule from data in an XML element.
* Construct a meta-type condition for an interesting files set
* membership rule from data in an XML element.
*
* @param ruleElement The XML element.
*
* @return The meta-type filter, or null if there is an error (logged).
* @return The meta-type condition, or null if there is an error
* (logged).
*/
private static FilesSet.Rule.MetaTypeFilter readMetaTypeFilter(Element ruleElement) {
FilesSet.Rule.MetaTypeFilter filter = null;
String filterAttribute = ruleElement.getAttribute(FilesSetXML.TYPE_FILTER_ATTR);
if (!filterAttribute.isEmpty()) {
switch (filterAttribute) {
private static FilesSet.Rule.MetaTypeCondition readMetaTypeCondition(Element ruleElement) {
FilesSet.Rule.MetaTypeCondition condition = null;
String conditionAttribute = ruleElement.getAttribute(FilesSetXML.TYPE_FILTER_ATTR);
if (!conditionAttribute.isEmpty()) {
switch (conditionAttribute) {
case FilesSetXML.TYPE_FILTER_VALUE_FILES:
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
condition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES);
break;
case FilesSetXML.TYPE_FILTER_VALUE_DIRS:
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.DIRECTORIES);
condition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.DIRECTORIES);
break;
case FilesSetXML.TYPE_FILTER_VALUE_FILES_AND_DIRS:
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES_AND_DIRECTORIES);
condition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES_AND_DIRECTORIES);
break;
default:
logger.log(Level.SEVERE, "Found {0} " + FilesSetXML.TYPE_FILTER_ATTR + " attribute with unrecognized value ''{0}'', ignoring malformed rule definition", filterAttribute); // NON-NLS
logger.log(Level.SEVERE, "Found {0} " + FilesSetXML.TYPE_FILTER_ATTR + " attribute with unrecognized value ''{0}'', ignoring malformed rule definition", conditionAttribute); // NON-NLS
break;
}
} else {
// Accept TSK Framework interesting files set definitions,
// default to files.
filter = new FilesSet.Rule.MetaTypeFilter(FilesSet.Rule.MetaTypeFilter.Type.FILES);
condition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES);
}
return filter;
return condition;
}
/**
* Construct a path filter for an interesting files set membership rule
* from data in an XML element.
* Construct a path condition for an interesting files set membership
* rule from data in an XML element.
*
* @param ruleElement The XML element.
*
* @return The path filter, or null if there is an error (logged).
* @return The path condition, or null if there is an error (logged).
*/
private static FilesSet.Rule.ParentPathFilter readPathFilter(Element ruleElement) {
FilesSet.Rule.ParentPathFilter filter = null;
private static FilesSet.Rule.ParentPathCondition readPathCondition(Element ruleElement) {
FilesSet.Rule.ParentPathCondition condition = null;
String path = ruleElement.getAttribute(FilesSetXML.PATH_FILTER_ATTR);
String pathRegex = ruleElement.getAttribute(FilesSetXML.PATH_REGEX_ATTR);
if (!pathRegex.isEmpty() && path.isEmpty()) {
try {
Pattern pattern = Pattern.compile(pathRegex);
filter = new FilesSet.Rule.ParentPathFilter(pattern);
condition = new FilesSet.Rule.ParentPathCondition(pattern);
} catch (PatternSyntaxException ex) {
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.PATH_REGEX_ATTR + " regex, ignoring malformed path filter definition", ex); // NON-NLS
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.PATH_REGEX_ATTR + " regex, ignoring malformed path condition definition", ex); // NON-NLS
}
} else if (!path.isEmpty() && pathRegex.isEmpty()) {
filter = new FilesSet.Rule.ParentPathFilter(path);
condition = new FilesSet.Rule.ParentPathCondition(path);
}
return filter;
return condition;
}
/**
@@ -498,85 +515,33 @@ final class InterestingItemDefsManager extends Observable {
// Note: This method takes a file path to support the possibility of
// multiple intersting files set definition files, e.g., one for
// definitions that ship with Autopsy and one for user definitions.
static boolean writeDefinitionsFile(String filePath, Map<String, FilesSet> interestingFilesSets) {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
try {
// Create the new XML document.
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement(FilesSetXML.FILE_SETS_ROOT_TAG);
doc.appendChild(rootElement);
// Add the interesting files sets to the document.
for (FilesSet set : interestingFilesSets.values()) {
// Add the files set element and its attributes.
Element setElement = doc.createElement(FilesSetXML.FILE_SET_TAG);
setElement.setAttribute(FilesSetXML.NAME_ATTR, set.getName());
setElement.setAttribute(FilesSetXML.DESC_ATTR, set.getDescription());
setElement.setAttribute(FilesSetXML.IGNORE_KNOWN_FILES_ATTR, Boolean.toString(set.ignoresKnownFiles()));
// Add the child elements for the set membership rules.
for (FilesSet.Rule rule : set.getRules().values()) {
// Add a rule element with the appropriate name filter
// type tag.
FilesSet.Rule.FileNameFilter nameFilter = rule.getFileNameFilter();
Element ruleElement;
if (nameFilter instanceof FilesSet.Rule.FullNameFilter) {
ruleElement = doc.createElement(FilesSetXML.NAME_RULE_TAG);
} else {
ruleElement = doc.createElement(FilesSetXML.EXTENSION_RULE_TAG);
}
// Add the rule name attribute.
ruleElement.setAttribute(FilesSetXML.NAME_ATTR, rule.getName());
// Add the name filter regex attribute
ruleElement.setAttribute(FilesSetXML.REGEX_ATTR, Boolean.toString(nameFilter.isRegex()));
// Add the type filter attribute.
FilesSet.Rule.MetaTypeFilter typeFilter = rule.getMetaTypeFilter();
switch (typeFilter.getMetaType()) {
case FILES:
ruleElement.setAttribute(FilesSetXML.TYPE_FILTER_ATTR, FilesSetXML.TYPE_FILTER_VALUE_FILES);
break;
case DIRECTORIES:
ruleElement.setAttribute(FilesSetXML.TYPE_FILTER_ATTR, FilesSetXML.TYPE_FILTER_VALUE_DIRS);
break;
default:
ruleElement.setAttribute(FilesSetXML.TYPE_FILTER_ATTR, FilesSetXML.TYPE_FILTER_VALUE_FILES_AND_DIRS);
break;
}
// Add the optional path filter.
FilesSet.Rule.ParentPathFilter pathFilter = rule.getPathFilter();
if (pathFilter != null) {
if (pathFilter.isRegex()) {
ruleElement.setAttribute(FilesSetXML.PATH_REGEX_ATTR, pathFilter.getTextToMatch());
} else {
ruleElement.setAttribute(FilesSetXML.PATH_FILTER_ATTR, pathFilter.getTextToMatch());
}
}
// Add the name filter text as the rule element content.
ruleElement.setTextContent(nameFilter.getTextToMatch());
setElement.appendChild(ruleElement);
}
rootElement.appendChild(setElement);
}
// Overwrite the previous definitions file. Note that the utility
// method logs an error on failure.
return XMLUtil.saveDoc(FilesSetXML.class, filePath, XML_ENCODING, doc);
} catch (ParserConfigurationException ex) {
logger.log(Level.SEVERE, "Error writing interesting files definition file to " + filePath, ex); // NON-NLS
return false;
static boolean writeDefinitionsFile(String filePath, Map<String, FilesSet> interestingFilesSets) throws InterestingItemDefsManagerException {
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
out.writeObject(new InterestingItemsFilesSetSettings(interestingFilesSets));
} catch (IOException ex) {
throw new InterestingItemDefsManagerException(String.format("Failed to write settings to %s", filePath), ex);
}
return true;
}
}
static class InterestingItemDefsManagerException extends Exception {
InterestingItemDefsManagerException() {
}
InterestingItemDefsManagerException(String message) {
super(message);
}
InterestingItemDefsManagerException(String message, Throwable cause) {
super(message, cause);
}
InterestingItemDefsManagerException(Throwable cause) {
super(cause);
}
}
}
@@ -4,6 +4,8 @@
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="fileNameButtonGroup">
</Component>
<Component class="javax.swing.ButtonGroup" name="typeButtonGroup">
</Component>
</NonVisualComponents>
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
@@ -28,18 +30,14 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="710" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="728" max="-2" attributes="0"/>
<EmptySpace min="0" pref="34" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="468" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="0" pref="503" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
@@ -67,7 +65,7 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="setsListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
@@ -83,65 +81,104 @@
<Component id="deleteSetButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="separator" min="-2" pref="6" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<Component id="ignoreKnownFilesCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="filesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bothRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="9" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
<Component id="filesRadioButton" min="-2" pref="47" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="dirsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bothRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="380" pref="380" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="fileNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="fileNameExtensionRadioButton" min="-2" pref="114" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="fileNameTextField" min="-2" pref="250" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="rulePathFilterRegexCheckBox" min="-2" max="-2" attributes="0"/>
<Component id="rulePathFilterTextField" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="rulePathConditionTextField" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="equalitySignComboBox" min="-2" pref="38" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSpinner1" min="-2" pref="104" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="fileSizeUnitComboBox" min="-2" pref="83" max="-2" attributes="0"/>
</Group>
<Component id="mimeTypeComboBox" alignment="0" pref="245" max="32767" attributes="0"/>
<Component id="fileNameTextField" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="setDescScrollPanel" min="-2" pref="336" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="jLabel6" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="rulesListScrollPane" min="-2" pref="336" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="360" pref="360" max="-2" attributes="0"/>
<Component id="newRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="editRuleButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="deleteRuleButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="setDescScrollPanel" min="-2" pref="336" max="-2" attributes="0"/>
<Component id="jLabel6" min="-2" max="-2" attributes="0"/>
<Component id="rulesListScrollPane" min="-2" pref="336" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="456" pref="456" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="fileNameRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
<Component id="fileNameExtensionRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="rulePathConditionRegexCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -149,65 +186,81 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="separator" alignment="1" min="-2" pref="444" max="-2" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="jLabel6" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="setDescScrollPanel" min="-2" pref="53" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rulesListScrollPane" min="-2" pref="110" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="separator" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="jScrollPane2" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="setsListLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="setsListScrollPane" min="-2" pref="199" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newSetButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editSetButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteSetButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel6" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel5" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="setDescScrollPanel" min="-2" pref="42" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="ignoreKnownFilesCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="rulesListLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rulesListScrollPane" min="-2" pref="64" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteRuleButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bothRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="fileNameRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameExtensionRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="filesRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="dirsRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bothRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="fileNameRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameExtensionRadioButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileNameRegexCheckbox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="rulePathFilterTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="rulePathConditionTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="rulePathFilterRegexCheckBox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane2" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="setsListLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="setsListScrollPane" min="-2" pref="199" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="rulePathConditionRegexCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newSetButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editSetButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteSetButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="mimeTypeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="equalitySignComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jSpinner1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="fileSizeUnitComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
@@ -242,7 +295,6 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.newRuleButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newRuleButtonActionPerformed"/>
@@ -250,6 +302,9 @@
</Component>
<Component class="javax.swing.JRadioButton" name="filesRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="typeButtonGroup"/>
</Property>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="filesRadioButton" property="font" relativeSize="false" size="11"/>
@@ -442,6 +497,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.fileNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileNameTextFieldActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="jLabel5">
<Properties>
@@ -471,16 +529,16 @@
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="rulePathFilterTextField">
<Component class="javax.swing.JTextField" name="rulePathConditionTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="rulePathFilterTextField" property="font" relativeSize="false" size="11"/>
<Font bold="false" component="rulePathConditionTextField" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathFilterTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathConditionTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@@ -532,6 +590,9 @@
</Component>
<Component class="javax.swing.JRadioButton" name="bothRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="typeButtonGroup"/>
</Property>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="bothRadioButton" property="font" relativeSize="false" size="11"/>
@@ -613,6 +674,9 @@
</Component>
<Component class="javax.swing.JRadioButton" name="dirsRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="typeButtonGroup"/>
</Property>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="dirsRadioButton" property="font" relativeSize="false" size="11"/>
@@ -651,15 +715,15 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="rulePathFilterRegexCheckBox">
<Component class="javax.swing.JCheckBox" name="rulePathConditionRegexCheckBox">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="rulePathFilterRegexCheckBox" property="font" relativeSize="false" size="11"/>
<Font bold="false" component="rulePathConditionRegexCheckBox" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.rulePathConditionRegexCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
@@ -700,6 +764,61 @@
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="jLabel7">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.jLabel7.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="mimeTypeComboBox">
<Properties>
<Property name="editable" type="boolean" value="true"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] {&quot;&quot;})" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="jLabel8">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="InterestingItemDefsPanel.jLabel8.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="equalitySignComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] { &quot;=&quot;, &quot;&gt;&quot;, &quot;&#x2265;&quot;, &quot;&lt;&quot;, &quot;&#x2264;&quot; })" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox&lt;String&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JSpinner" name="jSpinner1">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="fileSizeUnitComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;String&gt;(new String[] { Bundle.InterestingItemDefsPanel_bytes(), Bundle.InterestingItemDefsPanel_kiloBytes(), Bundle.InterestingItemDefsPanel_megaBytes(), Bundle.InterestingItemDefsPanel_gigaBytes() })" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox&lt;String&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,25 +20,51 @@ package org.sleuthkit.autopsy.modules.interestingitems;
import java.awt.EventQueue;
import java.awt.Font;
import java.util.ArrayList;
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;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.apache.tika.mime.MediaType;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypes;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* A panel that allows a user to make interesting item definitions.
*/
final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
@NbBundle.Messages({
"InterestingItemDefsPanel.bytes=Bytes",
"InterestingItemDefsPanel.kiloBytes=Kilobytes",
"InterestingItemDefsPanel.megaBytes=Megabytes",
"InterestingItemDefsPanel.gigaBytes=Gigabytes",
"InterestingItemsDefsPanel.loadError=Error loading interesting files sets from file.",
"InterestingItemsDefsPanel.saveError=Error saving interesting files sets to file."
})
private static final SortedSet<MediaType> mediaTypes = MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry().getTypes();
private final DefaultListModel<FilesSet> setsListModel = new DefaultListModel<>();
private final DefaultListModel<FilesSet.Rule> rulesListModel = new DefaultListModel<>();
private final Logger logger = Logger.getLogger(InterestingItemDefsPanel.class.getName());
private JButton okButton = new JButton("OK");
private JButton cancelButton = new JButton("Cancel");
// The following is a map of interesting files set names to interesting
// files set definitions. It is a snapshot of the files set definitions
@@ -54,18 +80,58 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
*/
InterestingItemDefsPanel() {
this.initComponents();
this.customInit();
this.setsList.setModel(setsListModel);
this.setsList.addListSelectionListener(new InterestingItemDefsPanel.SetsListSelectionListener());
this.rulesList.setModel(rulesListModel);
this.rulesList.addListSelectionListener(new InterestingItemDefsPanel.RulesListSelectionListener());
}
@NbBundle.Messages({"InterestingItemDefsPanel.Title=Global Interesting Items Settings"})
private void customInit() {
setName(Bundle.InterestingItemDefsPanel_Title());
Set<String> fileTypesCollated = new HashSet<>();
for (MediaType mediaType : mediaTypes) {
fileTypesCollated.add(mediaType.toString());
}
FileTypeDetector fileTypeDetector;
try {
fileTypeDetector = new FileTypeDetector();
List<String> userDefinedFileTypes = fileTypeDetector.getUserDefinedTypes();
fileTypesCollated.addAll(userDefinedFileTypes);
} 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);
}
this.fileSizeUnitComboBox.setSelectedIndex(1);
this.equalitySignComboBox.setSelectedIndex(2);
}
/**
* @inheritDoc
*/
@Override
public void saveSettings() {
InterestingItemDefsManager.getInstance().setInterestingFilesSets(this.filesSets);
try {
InterestingItemDefsManager.getInstance().setInterestingFilesSets(this.filesSets);
} catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
MessageNotifyUtil.Message.error(Bundle.InterestingItemsDefsPanel_saveError());
}
}
/**
@@ -83,9 +149,14 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
public void load() {
this.resetComponents();
// Get a working copy of the interesting files set definitions and sort
// by set name.
this.filesSets = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
try {
// Get a working copy of the interesting files set definitions and sort
// by set name.
this.filesSets = new TreeMap<>(InterestingItemDefsManager.getInstance().getInterestingFilesSets());
} catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
MessageNotifyUtil.Message.error(Bundle.InterestingItemsDefsPanel_loadError());
this.filesSets = new TreeMap<>();
}
// Populate the list model for the interesting files sets list
// component.
@@ -124,8 +195,8 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
this.fileNameRadioButton.setSelected(true);
this.fileNameRegexCheckbox.setSelected(false);
this.filesRadioButton.setSelected(true);
this.rulePathFilterTextField.setText("");
this.rulePathFilterRegexCheckBox.setSelected(false);
this.rulePathConditionTextField.setText("");
this.rulePathConditionRegexCheckBox.setSelected(false);
this.newRuleButton.setEnabled(!this.setsListModel.isEmpty());
this.editRuleButton.setEnabled(false);
this.deleteRuleButton.setEnabled(false);
@@ -189,18 +260,27 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
// Get the selected rule and populate the rule components.
FilesSet.Rule rule = InterestingItemDefsPanel.this.rulesList.getSelectedValue();
if (rule != null) {
// Get the filters that make up the rule.
FilesSet.Rule.FileNameFilter nameFilter = rule.getFileNameFilter();
FilesSet.Rule.MetaTypeFilter typeFilter = rule.getMetaTypeFilter();
FilesSet.Rule.ParentPathFilter pathFilter = rule.getPathFilter();
// Get the conditions that make up the rule.
FilesSet.Rule.FileNameCondition nameCondition = rule.getFileNameCondition();
FilesSet.Rule.MetaTypeCondition typeCondition = rule.getMetaTypeCondition();
FilesSet.Rule.ParentPathCondition pathCondition = rule.getPathCondition();
FilesSet.Rule.MimeTypeCondition mimeTypeCondition = rule.getMimeTypeCondition();
FilesSet.Rule.FileSizeCondition fileSizeCondition = rule.getFileSizeCondition();
// Populate the components that display the properties of the
// selected rule.
InterestingItemDefsPanel.this.fileNameTextField.setText(nameFilter.getTextToMatch());
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(nameFilter instanceof FilesSet.Rule.FullNameFilter);
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(nameFilter instanceof FilesSet.Rule.ExtensionFilter);
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(nameFilter.isRegex());
switch (typeFilter.getMetaType()) {
if (nameCondition != null) {
InterestingItemDefsPanel.this.fileNameTextField.setText(nameCondition.getTextToMatch());
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(nameCondition instanceof FilesSet.Rule.FullNameCondition);
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(nameCondition instanceof FilesSet.Rule.ExtensionCondition);
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(nameCondition.isRegex());
} else {
InterestingItemDefsPanel.this.fileNameTextField.setText("");
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(true);
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(false);
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(false);
}
switch (typeCondition.getMetaType()) {
case FILES:
InterestingItemDefsPanel.this.filesRadioButton.setSelected(true);
break;
@@ -211,12 +291,26 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
InterestingItemDefsPanel.this.bothRadioButton.setSelected(true);
break;
}
if (pathFilter != null) {
InterestingItemDefsPanel.this.rulePathFilterTextField.setText(pathFilter.getTextToMatch());
InterestingItemDefsPanel.this.rulePathFilterRegexCheckBox.setSelected(pathFilter.isRegex());
if (pathCondition != null) {
InterestingItemDefsPanel.this.rulePathConditionTextField.setText(pathCondition.getTextToMatch());
InterestingItemDefsPanel.this.rulePathConditionRegexCheckBox.setSelected(pathCondition.isRegex());
} else {
InterestingItemDefsPanel.this.rulePathFilterTextField.setText("");
InterestingItemDefsPanel.this.rulePathFilterRegexCheckBox.setSelected(false);
InterestingItemDefsPanel.this.rulePathConditionTextField.setText("");
InterestingItemDefsPanel.this.rulePathConditionRegexCheckBox.setSelected(false);
}
if (mimeTypeCondition != null) {
InterestingItemDefsPanel.this.mimeTypeComboBox.setSelectedItem(mimeTypeCondition.getMimeType());
} else {
InterestingItemDefsPanel.this.mimeTypeComboBox.setSelectedIndex(0);
}
if (fileSizeCondition != null) {
InterestingItemDefsPanel.this.fileSizeUnitComboBox.setSelectedItem(fileSizeCondition.getUnit().getName());
InterestingItemDefsPanel.this.equalitySignComboBox.setSelectedItem(fileSizeCondition.getComparator().getSymbol());
InterestingItemDefsPanel.this.jSpinner1.setValue(fileSizeCondition.getSizeValue());
} else {
InterestingItemDefsPanel.this.fileSizeUnitComboBox.setSelectedIndex(1);
InterestingItemDefsPanel.this.equalitySignComboBox.setSelectedIndex(2);
InterestingItemDefsPanel.this.jSpinner1.setValue(0);
}
// Enable the new, edit and delete rule buttons.
@@ -290,18 +384,17 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
FilesSetRulePanel panel;
if (selectedRule != null) {
// Editing an existing rule definition.
panel = new FilesSetRulePanel(selectedRule);
panel = new FilesSetRulePanel(selectedRule, okButton, cancelButton);
} else {
// Creating a new rule definition.
panel = new FilesSetRulePanel();
panel = new FilesSetRulePanel(okButton, cancelButton);
}
// Do a dialog box with the files set panel until the user either enters
// a valid definition or cancels. Note that the panel gives the user
// feedback when isValidDefinition() is called.
int option = JOptionPane.OK_OPTION;
do {
option = JOptionPane.showConfirmDialog(null, panel, NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
option = JOptionPane.showOptionDialog(null, panel, NbBundle.getMessage(FilesSetPanel.class, "FilesSetPanel.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{okButton, cancelButton}, okButton);
} while (option == JOptionPane.OK_OPTION && !panel.isValidRuleDefinition());
if (option == JOptionPane.OK_OPTION) {
@@ -316,7 +409,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
if (selectedRule != null) {
rules.remove(selectedRule.getUuid());
}
FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameFilter(), panel.getMetaTypeFilter(), panel.getPathFilter());
FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameCondition(), panel.getMetaTypeCondition(), panel.getPathCondition(), panel.getMimeTypeCondition(), panel.getFileSizeCondition());
rules.put(newRule.getUuid(), newRule);
// Add the new/edited files set definition, replacing any previous
@@ -380,6 +473,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
private void initComponents() {
fileNameButtonGroup = new javax.swing.ButtonGroup();
typeButtonGroup = new javax.swing.ButtonGroup();
jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel();
jLabel6 = new javax.swing.JLabel();
@@ -388,18 +482,18 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
editRuleButton = new javax.swing.JButton();
rulesListLabel = new javax.swing.JLabel();
rulesListScrollPane = new javax.swing.JScrollPane();
rulesList = new javax.swing.JList<>();
rulesList = new javax.swing.JList<FilesSet.Rule>();
setDescScrollPanel = new javax.swing.JScrollPane();
setDescriptionTextArea = new javax.swing.JTextArea();
editSetButton = new javax.swing.JButton();
setsListScrollPane = new javax.swing.JScrollPane();
setsList = new javax.swing.JList<>();
setsList = new javax.swing.JList<FilesSet>();
fileNameExtensionRadioButton = new javax.swing.JRadioButton();
jLabel3 = new javax.swing.JLabel();
fileNameTextField = new javax.swing.JTextField();
jLabel5 = new javax.swing.JLabel();
fileNameRadioButton = new javax.swing.JRadioButton();
rulePathFilterTextField = new javax.swing.JTextField();
rulePathConditionTextField = new javax.swing.JTextField();
ignoreKnownFilesCheckbox = new javax.swing.JCheckBox();
fileNameRegexCheckbox = new javax.swing.JCheckBox();
separator = new javax.swing.JSeparator();
@@ -412,9 +506,15 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
dirsRadioButton = new javax.swing.JRadioButton();
jLabel1 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
rulePathFilterRegexCheckBox = new javax.swing.JCheckBox();
rulePathConditionRegexCheckBox = new javax.swing.JCheckBox();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jLabel7 = new javax.swing.JLabel();
mimeTypeComboBox = new javax.swing.JComboBox<String>();
jLabel8 = new javax.swing.JLabel();
equalitySignComboBox = new javax.swing.JComboBox<String>();
jSpinner1 = new javax.swing.JSpinner();
fileSizeUnitComboBox = new javax.swing.JComboBox<String>();
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
@@ -428,13 +528,13 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
newRuleButton.setFont(newRuleButton.getFont().deriveFont(newRuleButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
newRuleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(newRuleButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.newRuleButton.text")); // NOI18N
newRuleButton.setEnabled(false);
newRuleButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
newRuleButtonActionPerformed(evt);
}
});
typeButtonGroup.add(filesRadioButton);
filesRadioButton.setFont(filesRadioButton.getFont().deriveFont(filesRadioButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
filesRadioButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(filesRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.filesRadioButton.text")); // NOI18N
@@ -496,6 +596,11 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
fileNameTextField.setEditable(false);
fileNameTextField.setFont(fileNameTextField.getFont().deriveFont(fileNameTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
fileNameTextField.setText(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNameTextField.text")); // NOI18N
fileNameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
fileNameTextFieldActionPerformed(evt);
}
});
jLabel5.setFont(jLabel5.getFont().deriveFont(jLabel5.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.jLabel5.text")); // NOI18N
@@ -505,9 +610,9 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
org.openide.awt.Mnemonics.setLocalizedText(fileNameRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.fileNameRadioButton.text")); // NOI18N
fileNameRadioButton.setEnabled(false);
rulePathFilterTextField.setEditable(false);
rulePathFilterTextField.setFont(rulePathFilterTextField.getFont().deriveFont(rulePathFilterTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
rulePathFilterTextField.setText(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathFilterTextField.text")); // NOI18N
rulePathConditionTextField.setEditable(false);
rulePathConditionTextField.setFont(rulePathConditionTextField.getFont().deriveFont(rulePathConditionTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
rulePathConditionTextField.setText(org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathConditionTextField.text")); // NOI18N
ignoreKnownFilesCheckbox.setFont(ignoreKnownFilesCheckbox.getFont().deriveFont(ignoreKnownFilesCheckbox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(ignoreKnownFilesCheckbox, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.ignoreKnownFilesCheckbox.text")); // NOI18N
@@ -527,6 +632,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
setsListLabel.setFont(setsListLabel.getFont().deriveFont(setsListLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(setsListLabel, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.setsListLabel.text")); // NOI18N
typeButtonGroup.add(bothRadioButton);
bothRadioButton.setFont(bothRadioButton.getFont().deriveFont(bothRadioButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(bothRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.bothRadioButton.text")); // NOI18N
bothRadioButton.setEnabled(false);
@@ -563,6 +669,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.jLabel2.text")); // NOI18N
typeButtonGroup.add(dirsRadioButton);
dirsRadioButton.setFont(dirsRadioButton.getFont().deriveFont(dirsRadioButton.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(dirsRadioButton, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.dirsRadioButton.text")); // NOI18N
dirsRadioButton.setEnabled(false);
@@ -578,9 +685,9 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
jLabel4.setFont(jLabel4.getFont().deriveFont(jLabel4.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.jLabel4.text")); // NOI18N
rulePathFilterRegexCheckBox.setFont(rulePathFilterRegexCheckBox.getFont().deriveFont(rulePathFilterRegexCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(rulePathFilterRegexCheckBox, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathFilterRegexCheckBox.text")); // NOI18N
rulePathFilterRegexCheckBox.setEnabled(false);
rulePathConditionRegexCheckBox.setFont(rulePathConditionRegexCheckBox.getFont().deriveFont(rulePathConditionRegexCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(rulePathConditionRegexCheckBox, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.rulePathConditionRegexCheckBox.text")); // NOI18N
rulePathConditionRegexCheckBox.setEnabled(false);
jScrollPane2.setFont(jScrollPane2.getFont().deriveFont(jScrollPane2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
@@ -594,6 +701,22 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
jTextArea1.setWrapStyleWord(true);
jScrollPane2.setViewportView(jTextArea1);
org.openide.awt.Mnemonics.setLocalizedText(jLabel7, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.jLabel7.text")); // NOI18N
mimeTypeComboBox.setEditable(true);
mimeTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] {""}));
mimeTypeComboBox.setEnabled(false);
org.openide.awt.Mnemonics.setLocalizedText(jLabel8, org.openide.util.NbBundle.getMessage(InterestingItemDefsPanel.class, "InterestingItemDefsPanel.jLabel8.text")); // NOI18N
equalitySignComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { "=", ">", "≥", "<", "≤" }));
equalitySignComboBox.setEnabled(false);
jSpinner1.setEnabled(false);
fileSizeUnitComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { Bundle.InterestingItemDefsPanel_bytes(), Bundle.InterestingItemDefsPanel_kiloBytes(), Bundle.InterestingItemDefsPanel_megaBytes(), Bundle.InterestingItemDefsPanel_gigaBytes() }));
fileSizeUnitComboBox.setEnabled(false);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
@@ -611,112 +734,152 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
.addComponent(editSetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(deleteSetButton)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGap(18, 18, 18)
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 6, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(10, 10, 10)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulesListLabel)
.addComponent(jLabel5)
.addComponent(ignoreKnownFilesCheckbox)
.addGap(12, 12, 12)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel2)
.addComponent(jLabel1))
.addGap(18, 18, 18)
.addComponent(filesRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel1)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel2)
.addGap(27, 27, 27)
.addComponent(filesRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dirsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bothRadioButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bothRadioButton)
.addGap(27, 27, 27))))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(9, 9, 9)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGap(380, 380, 380)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(2, 2, 2)
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(fileNameRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileNameExtensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileNameRegexCheckbox))
.addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel3)
.addComponent(jLabel7)
.addComponent(jLabel8))
.addGap(6, 6, 6))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(jLabel4)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(rulePathFilterRegexCheckBox)
.addComponent(rulePathFilterTextField)))))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)))
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(rulePathConditionTextField, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
.addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.Alignment.LEADING, 0, 245, Short.MAX_VALUE)
.addComponent(fileNameTextField)))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(rulesListLabel))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(jLabel5))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(ignoreKnownFilesCheckbox))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(jLabel6))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(360, 360, 360)
.addComponent(newRuleButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGap(18, 18, 18)
.addComponent(editRuleButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGap(18, 18, 18)
.addComponent(deleteRuleButton))
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel6)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(456, 456, 456)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(fileNameRadioButton)
.addGap(4, 4, 4)
.addComponent(fileNameExtensionRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(fileNameRegexCheckbox))
.addComponent(rulePathConditionRegexCheckBox))))
.addGap(20, 20, 20))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, 444, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(separator)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel6)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ignoreKnownFilesCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(rulesListLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newRuleButton)
.addComponent(editRuleButton)
.addComponent(deleteRuleButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel1)
.addGap(2, 2, 2)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(filesRadioButton)
.addComponent(dirsRadioButton)
.addComponent(bothRadioButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(fileNameRadioButton)
.addComponent(fileNameExtensionRadioButton)
.addComponent(fileNameRegexCheckbox))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(setsListLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(setsListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newSetButton)
.addComponent(editSetButton)
.addComponent(deleteSetButton)))
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel6)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ignoreKnownFilesCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(rulesListLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newRuleButton)
.addComponent(editRuleButton)
.addComponent(deleteRuleButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1)
.addGap(2, 2, 2)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(filesRadioButton)
.addComponent(dirsRadioButton)
.addComponent(bothRadioButton))
.addGap(16, 16, 16)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(fileNameRadioButton)
.addComponent(fileNameExtensionRadioButton)
.addComponent(fileNameRegexCheckbox))))
.addGap(14, 14, 14)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel4)
.addComponent(rulePathFilterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rulePathFilterRegexCheckBox))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(setsListLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(setsListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(rulePathConditionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(rulePathConditionRegexCheckBox)
.addGap(10, 10, 10)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(newSetButton)
.addComponent(editSetButton)
.addComponent(deleteSetButton))))
.addComponent(jLabel7)
.addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(16, 16, 16)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel8)
.addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap())
);
@@ -729,33 +892,34 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 710, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 728, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 34, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 11, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 468, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 503, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_dirsRadioButtonActionPerformed
private void newSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newSetButtonActionPerformed
this.doFileSetsDialog(null);
}//GEN-LAST:event_newSetButtonActionPerformed
private void editSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSetButtonActionPerformed
this.doFileSetsDialog(this.setsList.getSelectedValue());
}//GEN-LAST:event_editSetButtonActionPerformed
private void newRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRuleButtonActionPerformed
this.doFilesSetRuleDialog(null);
}//GEN-LAST:event_newRuleButtonActionPerformed
private void editRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editRuleButtonActionPerformed
this.doFilesSetRuleDialog(this.rulesList.getSelectedValue());
}//GEN-LAST:event_editRuleButtonActionPerformed
private void deleteRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteRuleButtonActionPerformed
// Interesting file sets are immutable for thread safety,
// so editing a files set rule definition is a replacement
// operation. Preserve the existing rules from the set being
// edited, except for the deleted rule.
FilesSet oldSet = this.setsList.getSelectedValue();
Map<String, FilesSet.Rule> rules = new HashMap<>(oldSet.getRules());
FilesSet.Rule selectedRule = this.rulesList.getSelectedValue();
rules.remove(selectedRule.getUuid());
this.replaceFilesSet(oldSet, oldSet.getName(), oldSet.getDescription(), oldSet.ignoresKnownFiles(), rules);
}//GEN-LAST:event_deleteRuleButtonActionPerformed
private void deleteSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteSetButtonActionPerformed
FilesSet selectedSet = this.setsList.getSelectedValue();
@@ -771,25 +935,25 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
}
}//GEN-LAST:event_deleteSetButtonActionPerformed
private void deleteRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteRuleButtonActionPerformed
// Interesting file sets are immutable for thread safety,
// so editing a files set rule definition is a replacement
// operation. Preserve the existing rules from the set being
// edited, except for the deleted rule.
FilesSet oldSet = this.setsList.getSelectedValue();
Map<String, FilesSet.Rule> rules = new HashMap<>(oldSet.getRules());
FilesSet.Rule selectedRule = this.rulesList.getSelectedValue();
rules.remove(selectedRule.getUuid());
this.replaceFilesSet(oldSet, oldSet.getName(), oldSet.getDescription(), oldSet.ignoresKnownFiles(), rules);
}//GEN-LAST:event_deleteRuleButtonActionPerformed
private void ignoreKnownFilesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ignoreKnownFilesCheckboxActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_ignoreKnownFilesCheckboxActionPerformed
private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed
private void editSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editSetButtonActionPerformed
this.doFileSetsDialog(this.setsList.getSelectedValue());
}//GEN-LAST:event_editSetButtonActionPerformed
private void editRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editRuleButtonActionPerformed
this.doFilesSetRuleDialog(this.rulesList.getSelectedValue());
}//GEN-LAST:event_editRuleButtonActionPerformed
private void newRuleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newRuleButtonActionPerformed
this.doFilesSetRuleDialog(null);
}//GEN-LAST:event_newRuleButtonActionPerformed
private void fileNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileNameTextFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_dirsRadioButtonActionPerformed
}//GEN-LAST:event_fileNameTextFieldActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton bothRadioButton;
@@ -798,11 +962,13 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
private javax.swing.JRadioButton dirsRadioButton;
private javax.swing.JButton editRuleButton;
private javax.swing.JButton editSetButton;
private javax.swing.JComboBox<String> equalitySignComboBox;
private javax.swing.ButtonGroup fileNameButtonGroup;
private javax.swing.JRadioButton fileNameExtensionRadioButton;
private javax.swing.JRadioButton fileNameRadioButton;
private javax.swing.JCheckBox fileNameRegexCheckbox;
private javax.swing.JTextField fileNameTextField;
private javax.swing.JComboBox<String> fileSizeUnitComboBox;
private javax.swing.JRadioButton filesRadioButton;
private javax.swing.JCheckBox ignoreKnownFilesCheckbox;
private javax.swing.JLabel jLabel1;
@@ -811,14 +977,18 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JSpinner jSpinner1;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JComboBox<String> mimeTypeComboBox;
private javax.swing.JButton newRuleButton;
private javax.swing.JButton newSetButton;
private javax.swing.JCheckBox rulePathFilterRegexCheckBox;
private javax.swing.JTextField rulePathFilterTextField;
private javax.swing.JCheckBox rulePathConditionRegexCheckBox;
private javax.swing.JTextField rulePathConditionTextField;
private javax.swing.JList<FilesSet.Rule> rulesList;
private javax.swing.JLabel rulesListLabel;
private javax.swing.JScrollPane rulesListScrollPane;
@@ -828,6 +998,7 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
private javax.swing.JList<FilesSet> setsList;
private javax.swing.JLabel setsListLabel;
private javax.swing.JScrollPane setsListScrollPane;
private javax.swing.ButtonGroup typeButtonGroup;
// End of variables declaration//GEN-END:variables
}
@@ -0,0 +1,44 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.modules.interestingitems;
import java.io.Serializable;
import java.util.Map;
/**
*
* @author oliver
*/
class InterestingItemsFilesSetSettings implements Serializable {
private static final long serialVersionUID = 1L;
private Map<String, FilesSet> filesSets;
InterestingItemsFilesSetSettings(Map<String, FilesSet> filesSets) {
this.filesSets = filesSets;
}
/**
* @return the filesSets
*/
Map<String, FilesSet> getFilesSets() {
return filesSets;
}
}
@@ -20,8 +20,11 @@ package org.sleuthkit.autopsy.modules.interestingitems;
import java.util.ArrayList;
import java.util.List;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
@@ -37,6 +40,10 @@ import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
@ServiceProvider(service = IngestModuleFactory.class)
final public class InterestingItemsIngestModuleFactory extends IngestModuleFactoryAdapter {
@Messages({
"InterestingItemsIngestModuleFactory.defaultSettingsError=Error getting default interesting files settings from file."
})
@Override
public String getModuleDisplayName() {
return getModuleName();
@@ -76,8 +83,12 @@ final public class InterestingItemsIngestModuleFactory extends IngestModuleFacto
// definitions independent of the rules that make up the defintions.
// Doing so also keeps the serialization simple.
List<String> enabledFilesSetNames = new ArrayList<>();
for (String name : InterestingItemDefsManager.getInstance().getInterestingFilesSets().keySet()) {
enabledFilesSetNames.add(name);
try {
for (String name : InterestingItemDefsManager.getInstance().getInterestingFilesSets().keySet()) {
enabledFilesSetNames.add(name);
}
} catch (InterestingItemDefsManager.InterestingItemDefsManagerException ex) {
MessageNotifyUtil.Message.error(Bundle.InterestingItemsIngestModuleFactory_defaultSettingsError());
}
return new FilesIdentifierIngestJobSettings(enabledFilesSetNames);
}
@@ -152,7 +152,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
// Initialize job totals
initTotalsForIngestJob(jobId);
} catch (SecurityException | IOException | UnsupportedOperationException ex) {
throw new IngestModule.IngestModuleException(NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "cannotCreateOutputDir.message", ex.getLocalizedMessage()));
throw new IngestModule.IngestModuleException(NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "cannotCreateOutputDir.message", ex.getLocalizedMessage()), ex);
}
}
}
@@ -396,7 +396,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
} catch (FileAlreadyExistsException ex) {
// No worries.
} catch (IOException | SecurityException | UnsupportedOperationException ex) {
throw new IngestModule.IngestModuleException(NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "cannotCreateOutputDir.message", ex.getLocalizedMessage()));
throw new IngestModule.IngestModuleException(NbBundle.getMessage(PhotoRecCarverFileIngestModule.class, "cannotCreateOutputDir.message", ex.getLocalizedMessage()), ex);
}
return path;
}
@@ -115,15 +115,15 @@ class EvalAccountObj extends EvaluatableObject {
boolean foundSIDMatch = false;
for (BlackboardAttribute attr : art.getAttributes()) {
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID())
&& (haveHomeDir)) {
foundHomeDirMatch = compareStringObject(userAccountObj.getHomeDirectory(), attr.getValueString());
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
&& (haveUsername)) {
foundUsernameMatch = compareStringObject(userAccountObj.getUsername(), attr.getValueString());
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID.getTypeID())
&& (haveSID) && (winUserObj != null)) {
foundSIDMatch = compareStringObject(winUserObj.getSecurityID(), attr.getValueString());
}
@@ -117,7 +117,7 @@ class EvalAddressObj extends EvaluatableObject {
for (BlackboardArtifact art : artList) {
for (BlackboardAttribute attr : art.getAttributes()) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
if (compareStringObject(addressStr, obj.getAddressValue().getCondition(),
obj.getAddressValue().getApplyCondition(), attr.getValueString())) {
finalHits.add(art);
@@ -80,7 +80,7 @@ class EvalDomainObj extends EvaluatableObject {
for (BlackboardArtifact art : artList) {
for (BlackboardAttribute attr : art.getAttributes()) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
String url = attr.getValueString();
// Check whether the domain name is a substring of the URL (regardless
@@ -98,11 +98,11 @@ class EvalNetworkShareObj extends EvaluatableObject {
boolean foundLocalPathMatch = false;
for (BlackboardAttribute attr : art.getAttributes()) {
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REMOTE_PATH.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REMOTE_PATH.getTypeID())
&& (obj.getNetname() != null)) {
foundRemotePathMatch = compareStringObject(obj.getNetname(), attr.getValueString());
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCAL_PATH.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCAL_PATH.getTypeID())
&& (obj.getLocalPath() != null)) {
foundLocalPathMatch = compareStringObject(obj.getLocalPath(), attr.getValueString());
}
@@ -108,7 +108,7 @@ class EvalURIObj extends EvaluatableObject {
for (BlackboardArtifact art : artList) {
for (BlackboardAttribute attr : art.getAttributes()) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
String modifiedAttrString = attr.getValueString();
if (modifiedAttrString != null) {
@@ -152,7 +152,7 @@ class EvalURLHistoryObj extends EvaluatableObject {
boolean foundBrowserNameMatch = false;
for (BlackboardAttribute attr : art.getAttributes()) {
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID())
&& (haveURL)) {
if (entry.getURL().getValue() instanceof AnyURIObjectPropertyType) {
foundURLMatch = compareStringObject(entry.getURL().getValue().getValue().toString(),
@@ -163,12 +163,12 @@ class EvalURLHistoryObj extends EvaluatableObject {
addWarning("Non-AnyURIObjectPropertyType found in URL value field"); //NON-NLS
}
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID())
&& (haveHostname)) {
foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
attr.getValueString());
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
&& (haveReferrer)) {
if (entry.getReferrerURL().getValue() instanceof AnyURIObjectPropertyType) {
foundReferrerMatch = compareStringObject(entry.getReferrerURL().getValue().getValue().toString(),
@@ -179,17 +179,17 @@ class EvalURLHistoryObj extends EvaluatableObject {
addWarning("Non-AnyURIObjectPropertyType found in URL value field"); //NON-NLS
}
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE.getTypeID())
&& (havePageTitle)) {
foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
attr.getValueString());
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
&& (haveUserProfile)) {
foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
attr.getValueString());
}
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
&& (haveBrowserName)) {
foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
null, null, attr.getValueString());
@@ -240,7 +240,7 @@ class EvalURLHistoryObj extends EvaluatableObject {
boolean foundBrowserNameMatch = false;
for (BlackboardAttribute attr : art.getAttributes()) {
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
&& (haveBrowserName)) {
foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
null, null, attr.getValueString());
@@ -87,7 +87,7 @@
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JList&lt;&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;ARTIFACT_TYPE&gt;"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;BlackboardArtifact.Type&gt;"/>
</AuxValues>
</Component>
</SubComponents>
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
@@ -40,15 +41,14 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.TskCoreException;
public class ArtifactSelectionDialog extends javax.swing.JDialog {
private ArtifactModel model;
private ArtifactRenderer renderer;
private Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> artifactStates;
private List<BlackboardArtifact.ARTIFACT_TYPE> artifacts;
private Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections;
private List<BlackboardArtifact.Type> artifactTypes;
/**
* Creates new form ArtifactSelectionDialog
@@ -61,27 +61,31 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
}
/**
* Populate the list of artifacts with all important artifacts.
* Populate the list of artifact types with all important artifact types.
*/
@SuppressWarnings("deprecation")
private void populateList() {
try {
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> doNotReport = new ArrayList<>();
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO);
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT); // output is too unstructured for table review.
ArrayList<BlackboardArtifact.Type> doNotReport = new ArrayList<>();
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getLabel(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName()));
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getLabel(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getDisplayName())); // output is too unstructured for table review
artifacts = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTypesInUse();
artifacts.removeAll(doNotReport);
Collections.sort(artifacts, new Comparator<BlackboardArtifact.ARTIFACT_TYPE>() {
artifactTypes = Case.getCurrentCase().getSleuthkitCase().getArtifactTypesInUse();
artifactTypes.removeAll(doNotReport);
Collections.sort(artifactTypes, new Comparator<BlackboardArtifact.Type>() {
@Override
public int compare(ARTIFACT_TYPE o1, ARTIFACT_TYPE o2) {
public int compare(BlackboardArtifact.Type o1, BlackboardArtifact.Type o2) {
return o1.getDisplayName().compareTo(o2.getDisplayName());
}
});
artifactStates = new EnumMap<>(BlackboardArtifact.ARTIFACT_TYPE.class);
for (BlackboardArtifact.ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
artifactTypeSelections = new HashMap<>();
for (BlackboardArtifact.Type type : artifactTypes) {
artifactTypeSelections.put(type, Boolean.TRUE);
}
} catch (TskCoreException ex) {
Logger.getLogger(ArtifactSelectionDialog.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS
@@ -99,17 +103,19 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
@Override
public void mousePressed(MouseEvent evt) {
int index = artifactList.locationToIndex(evt.getPoint());
BlackboardArtifact.ARTIFACT_TYPE type = model.getElementAt(index);
artifactStates.put(type, !artifactStates.get(type));
BlackboardArtifact.Type type = model.getElementAt(index);
artifactTypeSelections.put(type, !artifactTypeSelections.get(type));
artifactList.repaint();
}
});
}
/**
* Display this dialog, and return the selected artifacts.
* Display this dialog, and return the selected artifactTypes.
*
* @return The state of artifact types displayed
*/
Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> display() {
Map<BlackboardArtifact.Type, Boolean> display() {
this.setTitle(NbBundle.getMessage(this.getClass(), "ArtifactSelectionDialog.dlgTitle.text"));
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
@@ -120,7 +126,7 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
this.setVisible(true);
return artifactStates;
return artifactTypeSelections;
}
/**
@@ -215,20 +221,20 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
}//GEN-LAST:event_okButtonActionPerformed
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
for (ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
for (BlackboardArtifact.Type type : artifactTypes) {
artifactTypeSelections.put(type, Boolean.TRUE);
}
artifactList.repaint();
}//GEN-LAST:event_selectAllButtonActionPerformed
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
for (ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.FALSE);
for (BlackboardArtifact.Type type : artifactTypes) {
artifactTypeSelections.put(type, Boolean.FALSE);
}
artifactList.repaint();
}//GEN-LAST:event_deselectAllButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JList<ARTIFACT_TYPE> artifactList;
private javax.swing.JList<BlackboardArtifact.Type> artifactList;
private javax.swing.JScrollPane artifactScrollPane;
private javax.swing.JButton deselectAllButton;
private javax.swing.JButton okButton;
@@ -236,16 +242,16 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
private javax.swing.JLabel titleLabel;
// End of variables declaration//GEN-END:variables
private class ArtifactModel implements ListModel<ARTIFACT_TYPE> {
private class ArtifactModel implements ListModel<BlackboardArtifact.Type> {
@Override
public int getSize() {
return artifacts.size();
return artifactTypes.size();
}
@Override
public ARTIFACT_TYPE getElementAt(int index) {
return artifacts.get(index);
public BlackboardArtifact.Type getElementAt(int index) {
return artifactTypes.get(index);
}
@Override
@@ -257,13 +263,13 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
}
}
private class ArtifactRenderer extends JCheckBox implements ListCellRenderer<BlackboardArtifact.ARTIFACT_TYPE> {
private class ArtifactRenderer extends JCheckBox implements ListCellRenderer<BlackboardArtifact.Type> {
@Override
public Component getListCellRendererComponent(JList<? extends ARTIFACT_TYPE> list, ARTIFACT_TYPE value, int index, boolean isSelected, boolean cellHasFocus) {
public Component getListCellRendererComponent(JList<? extends BlackboardArtifact.Type> list, BlackboardArtifact.Type value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
setEnabled(list.isEnabled());
setSelected(artifactStates.get(value));
setSelected(artifactTypeSelections.get(value));
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
@@ -71,8 +71,6 @@ ReportGenerator.artifactTable.taggedResults.text=Contains results that were tagg
ReportGenerator.progress.processing=Now processing {0}...
ReportGenerator.msgShow.skippingArtType.title=Skipping artifact type {0} in reports
ReportGenerator.msgShow.skippingArtType.msg=Unknown columns to report on
ReportGenerator.msgShow.skippingArtRow.title=Skipping artifact rows for type {0} in reports
ReportGenerator.msgShow.skippingArtRow.msg=Unknown columns to report on
ReportGenerator.makeContTagTab.taggedFiles.msg=Contains files that were tagged with one of the following\:
ReportGenerator.makeBbArtTagTab.taggedRes.msg=This report only includes results tagged with\:
ReportGenerator.tagTable.header.resultType=Result Type
File diff suppressed because it is too large Load Diff
@@ -262,7 +262,6 @@ class ReportHTML implements TableReportModule {
break;
}
} else { // no defined artifact found for this dataType
logger.log(Level.WARNING, "useDataTypeIcon: no artifact found for data type = " + dataType); //NON-NLS
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/star.png"); //NON-NLS
iconFileName = "star.png"; //NON-NLS
iconFilePath = path + File.separator + iconFileName;
@@ -984,8 +983,8 @@ class ReportHTML implements TableReportModule {
StringBuilder head = new StringBuilder();
head.append("<html>\n<head>\n<title>").append( //NON-NLS
NbBundle.getMessage(this.getClass(), "ReportHTML.writeSum.title")).append("</title>\n"); //NON-NLS
head.append("<style type=\"text/css\">\n"); //NON-NLS
head.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"); //NON-NLS
head.append("<style type=\"text/css\">\n"); //NON-NLS
head.append("body { padding: 0px; margin: 0px; font: 13px/20px Arial, Helvetica, sans-serif; color: #535353; }\n"); //NON-NLS
head.append("#wrapper { width: 90%; margin: 0px auto; margin-top: 35px; }\n"); //NON-NLS
head.append("h1 { color: #07A; font-size: 36px; line-height: 42px; font-weight: normal; margin: 0px; border-bottom: 1px solid #81B9DB; }\n"); //NON-NLS
@@ -113,12 +113,12 @@ class ReportKML implements GeneralReportModule {
geoPath = "";
String extractedToPath;
for (BlackboardAttribute attribute : artifact.getAttributes()) {
if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) //latitude
if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) //latitude
{
lat = attribute.getValueDouble();
}
if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) //longitude
if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) //longitude
{
lon = attribute.getValueDouble();
}
@@ -150,11 +150,11 @@ class ReportKML implements GeneralReportModule {
lat = 0;
lon = 0;
for (BlackboardAttribute attribute : artifact.getAttributes()) {
if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) //latitude
if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) //latitude
{
lat = attribute.getValueDouble();
}
if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) //longitude
if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) //longitude
{
lon = attribute.getValueDouble();
}
@@ -172,22 +172,22 @@ class ReportKML implements GeneralReportModule {
String name = "";
String location = "";
for (BlackboardAttribute attribute : artifact.getAttributes()) {
if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID()) //latitude
if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID()) //latitude
{
lat = attribute.getValueDouble();
} else if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END.getTypeID()) //longitude
} else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END.getTypeID()) //longitude
{
destlat = attribute.getValueDouble();
} else if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START.getTypeID()) //longitude
} else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START.getTypeID()) //longitude
{
lon = attribute.getValueDouble();
} else if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END.getTypeID()) //longitude
} else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END.getTypeID()) //longitude
{
destlon = attribute.getValueDouble();
} else if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()) //longitude
} else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()) //longitude
{
name = attribute.getValueString();
} else if (attribute.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()) //longitude
} else if (attribute.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION.getTypeID()) //longitude
{
location = attribute.getValueString();
}
@@ -23,6 +23,7 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -50,8 +51,8 @@ final class ReportVisualPanel2 extends JPanel {
private Map<String, Boolean> tagStates = new LinkedHashMap<>();
private List<String> tags = new ArrayList<>();
ArtifactSelectionDialog dialog = new ArtifactSelectionDialog(new JFrame(), true);
private Map<ARTIFACT_TYPE, Boolean> artifactStates = new EnumMap<>(ARTIFACT_TYPE.class);
private List<ARTIFACT_TYPE> artifacts = new ArrayList<>();
private Map<BlackboardArtifact.Type, Boolean> artifactStates = new HashMap<>();
private List<BlackboardArtifact.Type> artifacts = new ArrayList<>();
private TagsListModel tagsModel;
private TagsListRenderer tagsRenderer;
@@ -111,16 +112,20 @@ final class ReportVisualPanel2 extends JPanel {
private void initArtifactTypes() {
try {
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> doNotReport = new ArrayList<>();
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO);
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT); // output is too unstructured for table review
ArrayList<BlackboardArtifact.Type> doNotReport = new ArrayList<>();
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getLabel(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName()));
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getLabel(),
BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getDisplayName())); // output is too unstructured for table review
artifacts = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTypesInUse();
artifacts = Case.getCurrentCase().getSleuthkitCase().getArtifactTypesInUse();
artifacts.removeAll(doNotReport);
artifactStates = new EnumMap<>(ARTIFACT_TYPE.class);
for (ARTIFACT_TYPE type : artifacts) {
artifactStates = new HashMap<>();
for (BlackboardArtifact.Type type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
}
} catch (TskCoreException ex) {
@@ -134,9 +139,11 @@ final class ReportVisualPanel2 extends JPanel {
}
/**
* Gets the enabled/disabled state of all artifacts
*
* @return the enabled/disabled state of all Artifacts
*/
Map<ARTIFACT_TYPE, Boolean> getArtifactStates() {
Map<BlackboardArtifact.Type, Boolean> getArtifactStates() {
return artifactStates;
}
@@ -159,7 +166,7 @@ final class ReportVisualPanel2 extends JPanel {
private boolean areArtifactsSelected() {
boolean result = false;
for (Entry<ARTIFACT_TYPE, Boolean> entry : artifactStates.entrySet()) {
for (Entry<BlackboardArtifact.Type, Boolean> entry : artifactStates.entrySet()) {
if (entry.getValue()) {
result = true;
}
@@ -42,7 +42,7 @@ import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.core.RuntimeProperties;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportWizardAction")
@ActionRegistration(displayName = "#CTL_ReportWizardAction", lazy = false)
@@ -68,7 +68,7 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
ReportGenerator generator = new ReportGenerator((Map<TableReportModule, Boolean>) wiz.getProperty("tableModuleStates"), //NON-NLS
(Map<GeneralReportModule, Boolean>) wiz.getProperty("generalModuleStates"), //NON-NLS
(Map<FileReportModule, Boolean>) wiz.getProperty("fileModuleStates")); //NON-NLS
generator.generateTableReports((Map<ARTIFACT_TYPE, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
generator.generateTableReports((Map<BlackboardArtifact.Type, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
generator.generateFileListReports((Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
generator.generateGeneralReports();
generator.displayProgressPanels();
@@ -440,6 +440,7 @@ public class TimeLineController {
return false;
}
@SuppressWarnings("deprecation") // TODO (EUR-733): Do not use SleuthkitCase.getLastObjectId
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
@NbBundle.Messages({"TimeLineController.errorTitle=Timeline error.",
"TimeLineController.outOfDate.errorMessage=Error determing if the timeline is out of date. We will assume it should be updated. See the logs for more details.",
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2014-16 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,10 +18,9 @@
*/
package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.text.MessageFormat;
import java.util.Optional;
import java.util.function.Function;
import java.util.logging.Level;
import org.apache.commons.lang3.StringUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
@@ -34,56 +33,56 @@ import org.sleuthkit.datamodel.TskCoreException;
*/
public interface ArtifactEventType extends EventType {
public static final Logger LOGGER = Logger.getLogger(ArtifactEventType.class.getName());
static final EmptyExtractor EMPTY_EXTRACTOR = new EmptyExtractor();
/**
* @return the Artifact type this event type is derived form, or null if
* there is no artifact type (eg file system events)
* @return the Artifact type this event type is derived from
*/
public BlackboardArtifact.ARTIFACT_TYPE getArtifactType();
public BlackboardArtifact.Type getArtifactType();
public BlackboardAttribute.ATTRIBUTE_TYPE getDateTimeAttrubuteType();
public BlackboardAttribute.Type getDateTimeAttrubuteType();
/**
* given an artifact, and a map from attribute types to attributes, pull out
* the time stamp, and compose the descriptions. Each implementation of
* {@link ArtifactEventType} needs to implement parseAttributesHelper() as
* hook for {@link buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact)
* given an artifact, pull out the time stamp, and compose the descriptions.
* Each implementation of {@link ArtifactEventType} needs to implement
* parseAttributesHelper() as hook for {@link buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact)
* to invoke. Most subtypes can use this default implementation.
*
* @param artf
* @param attrMap
*
* @return an {@link AttributeEventDescription} containing the timestamp
* and description information
*
* @throws TskCoreException
*/
default AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) throws TskCoreException {
final BlackboardAttribute dateTimeAttr = attrMap.get(getDateTimeAttrubuteType());
default AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf) throws TskCoreException {
final BlackboardAttribute dateTimeAttr = artf.getAttribute(getDateTimeAttrubuteType());
long time = dateTimeAttr.getValueLong();
String shortDescription = getShortExtractor().apply(artf, attrMap);
String medDescription = shortDescription + " : " + getMedExtractor().apply(artf, attrMap);
String fullDescription = medDescription + " : " + getFullExtractor().apply(artf, attrMap);
String shortDescription = getShortExtractor().apply(artf);
String medDescription = shortDescription + " : " + getMedExtractor().apply(artf);
String fullDescription = medDescription + " : " + getFullExtractor().apply(artf);
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
}
/**
* @return a function from an artifact and a map of its attributes, to a
* String to use as part of the full event description
* @return a function from an artifact to a String to use as part of the
* full event description
*/
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getFullExtractor();
Function<BlackboardArtifact, String> getFullExtractor();
/**
* @return a function from an artifact and a map of its attributes, to a
* String to use as part of the medium event description
* @return a function from an artifact to a String to use as part of the
* medium event description
*/
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getMedExtractor();
Function<BlackboardArtifact, String> getMedExtractor();
/**
* @return a function from an artifact and a map of its attributes, to a
* String to use as part of the short event description
* @return a function from an artifact to a String to use as part of the
* short event description
*/
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getShortExtractor();
Function<BlackboardArtifact, String> getShortExtractor();
/**
* bundles the per event information derived from a BlackBoard Artifact into
@@ -124,14 +123,13 @@ public interface ArtifactEventType extends EventType {
this.medDescription = medDescription;
this.fullDescription = fullDescription;
}
}
/**
* Build a {@link AttributeEventDescription} derived from a
* {@link BlackboardArtifact}. This is a template method that relies on each
* {@link SubType}'s implementation of
* {@link SubType#parseAttributesHelper()} to know how to go from
* {@link ArtifactEventType}'s implementation of
* {@link ArtifactEventType#parseAttributesHelper()} to know how to go from
* {@link BlackboardAttribute}s to the event description.
*
* @param artf the {@link BlackboardArtifact} to derive the event
@@ -149,48 +147,45 @@ public interface ArtifactEventType extends EventType {
if (type.getArtifactType().getTypeID() != artf.getArtifactTypeID()) {
throw new IllegalArgumentException();
}
/*
* build a map from attribute type to attribute, this makes implementing
* the parseAttributeHelper easier but could be ineffecient if we don't
* need most of the attributes. This would be unnessecary if there was
* an api on Blackboard artifacts to get specific attributes by type
*/
List<BlackboardAttribute> attributes = artf.getAttributes();
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap = new HashMap<>();
for (BlackboardAttribute attr : attributes) {
attrMap.put(BlackboardAttribute.ATTRIBUTE_TYPE.fromLabel(attr.
getAttributeTypeName()), attr);
}
if (attrMap.get(type.getDateTimeAttrubuteType()) == null) {
Logger.getLogger(AttributeEventDescription.class.getName()).log(Level.WARNING, "Artifact {0} has no date/time attribute, skipping it.", artf.getArtifactID()); // NON-NLS
if (artf.getAttribute(type.getDateTimeAttrubuteType()) == null) {
LOGGER.log(Level.WARNING, "Artifact {0} has no date/time attribute, skipping it.", artf.getArtifactID()); // NON-NLS
return null;
}
//use the hook provided by this subtype implementation
return type.parseAttributesHelper(artf, attrMap);
return type.parseAttributesHelper(artf);
}
public static class AttributeExtractor implements BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> {
static class AttributeExtractor implements Function<BlackboardArtifact, String> {
@Override
public String apply(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
final BlackboardAttribute attr = attrMap.get(attribute);
return (attr != null) ? StringUtils.defaultString(attr.getDisplayString()) : " ";
public String apply(BlackboardArtifact artf) {
return Optional.ofNullable(getAttributeSafe(artf, attributeType))
.map(BlackboardAttribute::getDisplayString)
.map(StringUtils::defaultString)
.orElse("");
}
private final BlackboardAttribute.ATTRIBUTE_TYPE attribute;
private final BlackboardAttribute.Type attributeType;
public AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE attribute) {
this.attribute = attribute;
public AttributeExtractor(BlackboardAttribute.Type attribute) {
this.attributeType = attribute;
}
}
public static class EmptyExtractor implements BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> {
static class EmptyExtractor implements Function<BlackboardArtifact, String> {
@Override
public String apply(BlackboardArtifact t, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> u) {
public String apply(BlackboardArtifact t) {
return "";
}
}
static BlackboardAttribute getAttributeSafe(BlackboardArtifact artf, BlackboardAttribute.Type attrType) {
try {
return artf.getAttribute(attrType);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting extracting attribute from artifact {0}.", artf.getArtifactID()), ex); // NON-NLS
return null;
}
}
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2014-16 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,17 +21,19 @@ package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.Optional;
import java.util.function.Function;
import java.util.logging.Level;
import javafx.scene.image.Image;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.getAttributeSafe;
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.TskCoreException;
/**
@@ -40,116 +42,113 @@ import org.sleuthkit.datamodel.TskCoreException;
public enum MiscTypes implements EventType, ArtifactEventType {
MESSAGE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.message.name"), "message.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE),
(artf, attrMap) -> {
final BlackboardAttribute dir = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION);
final BlackboardAttribute readStatus = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_READ_STATUS);
final BlackboardAttribute name = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME);
final BlackboardAttribute phoneNumber = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER);
final BlackboardAttribute subject = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT);
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_MESSAGE),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)),
artf -> {
final BlackboardAttribute dir = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DIRECTION));
final BlackboardAttribute readStatus = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_READ_STATUS));
final BlackboardAttribute name = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_NAME));
final BlackboardAttribute phoneNumber = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
final BlackboardAttribute subject = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SUBJECT));
List<String> asList = Arrays.asList(stringValueOf(dir), stringValueOf(readStatus), name != null || phoneNumber != null ? toFrom(dir) : "", stringValueOf(name != null ? name : phoneNumber), (subject == null ? "" : stringValueOf(subject)));
return StringUtils.join(asList, " ");
},
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_TEXT))),
GPS_ROUTE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSRoutes.name"), "gps-search.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION),
(artf, attrMap) -> {
final BlackboardAttribute latStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START);
final BlackboardAttribute longStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START);
final BlackboardAttribute latEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END);
final BlackboardAttribute longEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END);
return String.format("from %1$g %2$g to %3$g %4$g", latStart.getValueDouble(), longStart.getValueDouble(), latEnd.getValueDouble(), longEnd.getValueDouble()); // NON-NLS
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_GPS_ROUTE),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_LOCATION)),
artf -> {
final BlackboardAttribute latStart = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START));
final BlackboardAttribute longStart = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START));
final BlackboardAttribute latEnd = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END));
final BlackboardAttribute longEnd = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END));
return String.format("from %1$s %2$s to %3$s %4$s", stringValueOf(latStart), stringValueOf(longStart), stringValueOf(latEnd), stringValueOf(longEnd)); // NON-NLS
}),
GPS_TRACKPOINT(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSTrackpoint.name"), "gps-trackpoint.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
(artf, attrMap) -> {
final BlackboardAttribute longitude = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE);
final BlackboardAttribute latitude = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
return (latitude != null ? latitude.getValueDouble() : "") + " " + (longitude != null ? longitude.getValueDouble() : ""); // NON-NLS
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_GPS_TRACKPOINT),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
artf -> {
final BlackboardAttribute longitude = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE));
final BlackboardAttribute latitude = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE));
return stringValueOf(latitude) + " " + stringValueOf(longitude); // NON-NLS
},
(artf, attrMap) -> ""),
EMPTY_EXTRACTOR),
CALL_LOG(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Calls.name"), "calllog.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)),
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_CALLLOG),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_START),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_NAME)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DIRECTION))),
EMAIL(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Email.name"), "mail-icon-16.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT,
(artifact, attrMap) -> {
final BlackboardAttribute emailFrom = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM);
final BlackboardAttribute emailTo = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO);
return (emailFrom != null ? emailFrom.getValueString() : "") + " to " + (emailTo != null ? emailTo.getValueString() : ""); // NON-NLS
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_EMAIL_MSG),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_SENT),
artf -> {
final BlackboardAttribute emailFrom = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_FROM));
final BlackboardAttribute emailTo = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_TO));
return stringValueOf(emailFrom) + " to " + stringValueOf(emailTo); // NON-NLS
},
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SUBJECT)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN))),
RECENT_DOCUMENTS(NbBundle.getMessage(MiscTypes.class, "MiscTypes.recentDocuments.name"), "recent_docs.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH).andThen(
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_RECENT_OBJECT),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH)).andThen(
(String t) -> (StringUtils.substringBeforeLast(StringUtils.substringBeforeLast(t, "\\"), "\\"))),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH).andThen(
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH)).andThen(
(String t) -> StringUtils.substringBeforeLast(t, "\\")),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)) {
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH))) {
/**
* Override
* {@link ArtifactEventType#parseAttributesHelper(org.sleuthkit.datamodel.BlackboardArtifact, java.util.Map)}
* with non-default description construction
*/
@Override
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) throws TskCoreException {
final BlackboardAttribute dateTimeAttr = attrMap.get(getDateTimeAttrubuteType());
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf) throws TskCoreException {
final BlackboardAttribute dateTimeAttr = artf.getAttribute(getDateTimeAttrubuteType());
long time = dateTimeAttr.getValueLong();
//Non-default description construction
String shortDescription = getShortExtractor().apply(artf, attrMap);
String medDescription = getMedExtractor().apply(artf, attrMap);
String fullDescription = getFullExtractor().apply(artf, attrMap);
String shortDescription = getShortExtractor().apply(artf);
String medDescription = getMedExtractor().apply(artf);
String fullDescription = getFullExtractor().apply(artf);
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
}
},
INSTALLED_PROGRAM(NbBundle.getMessage(MiscTypes.class, "MiscTypes.installedPrograms.name"), "programs.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
new EmptyExtractor(),
new EmptyExtractor()),
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_INSTALLED_PROG),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
EMPTY_EXTRACTOR,
EMPTY_EXTRACTOR),
EXIF(NbBundle.getMessage(MiscTypes.class, "MiscTypes.exif.name"), "camera-icon-16.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL),
(artifact, attributeMap) -> {
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_METADATA_EXIF),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
artf -> {
try {
AbstractFile file = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
AbstractFile file = artf.getSleuthkitCase().getAbstractFileById(artf.getObjectID());
if (file != null) {
return file.getName();
}
} catch (TskCoreException ex) {
Logger.getLogger(MiscTypes.class.getName()).log(Level.SEVERE, "Exif event type failed to look up backing file name", ex); //NON-NLS
LOGGER.log(Level.SEVERE, "Exif event type failed to look up backing file name", ex); //NON-NLS
}
return " error loading file name"; // NON-NLS
return "error loading file name";
}),
DEVICES_ATTACHED(NbBundle.getMessage(MiscTypes.class, "MiscTypes.devicesAttached.name"), "usb_devices.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID));
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED),
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_ID)));
static public String stringValueOf(BlackboardAttribute attr) {
return attr != null ? attr.getDisplayString() : "";
return Optional.ofNullable(attr)
.map(BlackboardAttribute::getDisplayString)
.orElse("");
}
public static String toFrom(BlackboardAttribute dir) {
@@ -167,7 +166,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
}
}
private final BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType;
private final BlackboardAttribute.Type dateTimeAttributeType;
private final String iconBase;
@@ -178,47 +177,32 @@ public enum MiscTypes implements EventType, ArtifactEventType {
return image;
}
private final BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> longExtractor;
private final Function<BlackboardArtifact, String> longExtractor;
private final BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> medExtractor;
private final Function<BlackboardArtifact, String> medExtractor;
private final BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> shortExtractor;
private final Function<BlackboardArtifact, String> shortExtractor;
/**
* {@inheritDoc }
*/
@Override
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getFullExtractor() {
public Function<BlackboardArtifact, String> getFullExtractor() {
return longExtractor;
}
/**
* {@inheritDoc }
*/
@Override
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getMedExtractor() {
public Function<BlackboardArtifact, String> getMedExtractor() {
return medExtractor;
}
/**
* {@inheritDoc }
*/
@Override
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getShortExtractor() {
public Function<BlackboardArtifact, String> getShortExtractor() {
return shortExtractor;
}
/**
* {@inheritDoc }
*/
@Override
public BlackboardAttribute.ATTRIBUTE_TYPE getDateTimeAttrubuteType() {
public BlackboardAttribute.Type getDateTimeAttrubuteType() {
return dateTimeAttributeType;
}
/**
* {@inheritDoc }
*/
@Override
public EventTypeZoomLevel getZoomLevel() {
return EventTypeZoomLevel.SUB_TYPE;
@@ -226,7 +210,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
private final String displayName;
private final BlackboardArtifact.ARTIFACT_TYPE artifactType;
private final BlackboardArtifact.Type artifactType;
@Override
public String getDisplayName() {
@@ -243,11 +227,11 @@ public enum MiscTypes implements EventType, ArtifactEventType {
return MiscTypes.valueOf(string);
}
private MiscTypes(String displayName, String iconBase, BlackboardArtifact.ARTIFACT_TYPE artifactType,
BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType,
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> shortExtractor,
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> medExtractor,
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> longExtractor) {
private MiscTypes(String displayName, String iconBase, BlackboardArtifact.Type artifactType,
BlackboardAttribute.Type dateTimeAttributeType,
Function<BlackboardArtifact, String> shortExtractor,
Function<BlackboardArtifact, String> medExtractor,
Function<BlackboardArtifact, String> longExtractor) {
this.displayName = displayName;
this.iconBase = iconBase;
this.artifactType = artifactType;
@@ -269,7 +253,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
}
@Override
public BlackboardArtifact.ARTIFACT_TYPE getArtifactType() {
public BlackboardArtifact.Type getArtifactType() {
return artifactType;
}
@@ -0,0 +1,35 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2016 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
*
*/
class TypeUtils {
//TODO: this will be unncessary once their is BlackboardArtifact.Type constructr that takes a BlackboardArtifact.ARTIFACT_TYPE
static BlackboardArtifact.Type fromEnum(BlackboardArtifact.ARTIFACT_TYPE type) {
return new BlackboardArtifact.Type(type.getTypeID(), type.getLabel(), type.getDisplayName());
}
private TypeUtils() {
}
}
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2014-16 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,14 +21,14 @@ package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
import com.google.common.net.InternetDomainName;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import javafx.scene.image.Image;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
@@ -37,24 +37,19 @@ public enum WebTypes implements EventType, ArtifactEventType {
WEB_DOWNLOADS(NbBundle.getMessage(WebTypes.class, "WebTypes.webDownloads.name"),
"downloads.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD),
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
TopPrivateDomainExtractor.getInstance(),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)) {
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL))) {
/**
* Override
* {@link ArtifactEventType#parseAttributesHelper(org.sleuthkit.datamodel.BlackboardArtifact, java.util.Map)}
* with non default description construction
*/
@Override
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
long time = attrMap.get(getDateTimeAttrubuteType()).getValueLong();
String domain = getShortExtractor().apply(artf, attrMap);
String path = getMedExtractor().apply(artf, attrMap);
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf) throws TskCoreException {
long time = artf.getAttribute(getDateTimeAttrubuteType()).getValueLong();
String domain = getShortExtractor().apply(artf);
String path = getMedExtractor().apply(artf);
String fileName = StringUtils.substringAfterLast(path, "/");
String url = getFullExtractor().apply(artf, attrMap);
String url = getFullExtractor().apply(artf);
//TODO: review non default description construction
String shortDescription = fileName + " from " + domain; // NON-NLS
@@ -66,37 +61,37 @@ public enum WebTypes implements EventType, ArtifactEventType {
//TODO: review description separators
WEB_COOKIE(NbBundle.getMessage(WebTypes.class, "WebTypes.webCookies.name"),
"cookies.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE),
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME),
TopPrivateDomainExtractor.getInstance(),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE))),
//TODO: review description separators
WEB_BOOKMARK(NbBundle.getMessage(WebTypes.class, "WebTypes.webBookmarks.name"),
"bookmarks.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK),
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
TopPrivateDomainExtractor.getInstance(),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE))),
//TODO: review description separators
WEB_HISTORY(NbBundle.getMessage(WebTypes.class, "WebTypes.webHistory.name"),
"history.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY),
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
TopPrivateDomainExtractor.getInstance(),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE))),
//TODO: review description separators
WEB_SEARCH(NbBundle.getMessage(WebTypes.class, "WebTypes.webSearch.name"),
"searchquery.png", // NON-NLS
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT),
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY),
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)),
TopPrivateDomainExtractor.getInstance(),
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME)));
private final BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType;
private final BlackboardAttribute.Type dateTimeAttributeType;
private final String iconBase;
@@ -108,7 +103,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
}
@Override
public BlackboardAttribute.ATTRIBUTE_TYPE getDateTimeAttrubuteType() {
public BlackboardAttribute.Type getDateTimeAttrubuteType() {
return dateTimeAttributeType;
}
@@ -117,30 +112,30 @@ public enum WebTypes implements EventType, ArtifactEventType {
return EventTypeZoomLevel.SUB_TYPE;
}
private final BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> longExtractor;
private final Function<BlackboardArtifact, String> longExtractor;
private final BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> medExtractor;
private final Function<BlackboardArtifact, String> medExtractor;
private final BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> shortExtractor;
private final Function<BlackboardArtifact, String> shortExtractor;
@Override
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getFullExtractor() {
public Function<BlackboardArtifact, String> getFullExtractor() {
return longExtractor;
}
@Override
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getMedExtractor() {
public Function<BlackboardArtifact, String> getMedExtractor() {
return medExtractor;
}
@Override
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getShortExtractor() {
public Function<BlackboardArtifact, String> getShortExtractor() {
return shortExtractor;
}
private final String displayName;
BlackboardArtifact.ARTIFACT_TYPE artifactType;
private final BlackboardArtifact.Type artifactType;
@Override
public String getIconBase() {
@@ -148,15 +143,15 @@ public enum WebTypes implements EventType, ArtifactEventType {
}
@Override
public BlackboardArtifact.ARTIFACT_TYPE getArtifactType() {
public BlackboardArtifact.Type getArtifactType() {
return artifactType;
}
private WebTypes(String displayName, String iconBase, BlackboardArtifact.ARTIFACT_TYPE artifactType,
BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType,
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> shortExtractor,
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> medExtractor,
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> longExtractor) {
private WebTypes(String displayName, String iconBase, BlackboardArtifact.Type artifactType,
BlackboardAttribute.Type dateTimeAttributeType,
Function<BlackboardArtifact, String> shortExtractor,
Function<BlackboardArtifact, String> medExtractor,
Function<BlackboardArtifact, String> longExtractor) {
this.displayName = displayName;
this.iconBase = iconBase;
this.artifactType = artifactType;
@@ -196,8 +191,8 @@ public enum WebTypes implements EventType, ArtifactEventType {
}
@Override
public String apply(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
String domainString = StringUtils.substringBefore(super.apply(artf, attrMap), "/");
public String apply(BlackboardArtifact artf) {
String domainString = StringUtils.substringBefore(super.apply(artf), "/");
if (InternetDomainName.isValid(domainString)) {
InternetDomainName domain = InternetDomainName.from(domainString);
return (domain.isUnderPublicSuffix())
@@ -209,8 +204,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
}
TopPrivateDomainExtractor() {
super(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN);
super(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN));
}
}
}
@@ -461,6 +461,7 @@ public class EventsRepository {
updateProgress(workDone, total);
}
@SuppressWarnings("deprecation") // TODO (EUR-733): Do not use SleuthkitCase.getLastObjectId
@Override
@NbBundle.Messages({"progressWindow.msg.refreshingFileTags=Refreshing file tags",
"progressWindow.msg.refreshingResultTags=Refreshing result tags",
@@ -654,7 +655,7 @@ public class EventsRepository {
private void populateEventType(final ArtifactEventType type, EventDB.EventTransaction trans) {
try {
//get all the blackboard artifacts corresponding to the given event sub_type
final ArrayList<BlackboardArtifact> blackboardArtifacts = skCase.getBlackboardArtifacts(type.getArtifactType());
final ArrayList<BlackboardArtifact> blackboardArtifacts = skCase.getBlackboardArtifacts(type.getArtifactType().getTypeID());
final int numArtifacts = blackboardArtifacts.size();
restartProgressHandle(Bundle.progressWindow_populatingXevents(type.getDisplayName()), "", 0D, numArtifacts, true);
for (int i = 0; i < numArtifacts; i++) {