mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 01:37:43 +00:00
Merge branch 'develop' into aut-1900
This commit is contained in:
commit
38cb717bd9
@ -6,10 +6,6 @@
|
|||||||
<description>Builds, tests, and runs the project org.sleuthkit.autopsy.core</description>
|
<description>Builds, tests, and runs the project org.sleuthkit.autopsy.core</description>
|
||||||
<import file="nbproject/build-impl.xml"/>
|
<import file="nbproject/build-impl.xml"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Verify that the TSK_HOME env variable is set -->
|
<!-- Verify that the TSK_HOME env variable is set -->
|
||||||
<target name="findTSK">
|
<target name="findTSK">
|
||||||
<property environment="env"/>
|
<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"/>
|
<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>
|
||||||
|
|
||||||
|
|
||||||
<target name="init" depends="basic-init,files-init,build-init,-javac-init">
|
<target name="init" depends="basic-init,files-init,build-init,-javac-init">
|
||||||
<!-- get additional deps -->
|
<!-- get additional deps -->
|
||||||
<antcall target="getTSKJars" />
|
<antcall target="getTSKJars" />
|
||||||
|
@ -19,15 +19,13 @@
|
|||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.SleuthkitJNI;
|
import org.sleuthkit.datamodel.SleuthkitJNI;
|
||||||
@ -35,66 +33,220 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
import org.sleuthkit.datamodel.TskDataException;
|
import org.sleuthkit.datamodel.TskDataException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A background task that adds the given image to database using the Sleuthkit
|
* A runnable that adds an image data source to the case database.
|
||||||
* JNI interface.
|
|
||||||
*
|
|
||||||
* It updates the given ProgressMonitor as it works through adding the image,
|
|
||||||
* and et the end, calls the specified Callback.
|
|
||||||
*/
|
*/
|
||||||
class AddImageTask implements Runnable {
|
class AddImageTask implements Runnable {
|
||||||
|
|
||||||
private final Logger logger = Logger.getLogger(AddImageTask.class.getName());
|
private final Logger logger = Logger.getLogger(AddImageTask.class.getName());
|
||||||
|
private final String deviceId;
|
||||||
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 imagePath;
|
private final String imagePath;
|
||||||
String timeZone;
|
private final String timeZone;
|
||||||
boolean noFatOrphans;
|
private final boolean ignoreFatOrphanFiles;
|
||||||
|
private final DataSourceProcessorProgressMonitor progressMonitor;
|
||||||
private final String dataSourceId;
|
private final DataSourceProcessorCallback callback;
|
||||||
|
private boolean criticalErrorOccurred;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A thread that updates the progressMonitor with the name of the directory
|
* The cancellation requested flag and SleuthKit add image process are
|
||||||
* currently being processed by the AddImageTask
|
* 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;
|
* Adds the image to the case database.
|
||||||
this.process = proc;
|
*/
|
||||||
|
@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
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
String currDir = process.currentDirectory();
|
String currDir = tskAddImageProcess.currentDirectory();
|
||||||
if (currDir != null) {
|
if (currDir != null) {
|
||||||
if (!currDir.isEmpty()) {
|
if (!currDir.isEmpty()) {
|
||||||
progressMonitor.setProgressText(
|
progressMonitor.setProgressText(
|
||||||
@ -102,227 +254,20 @@ class AddImageTask implements Runnable {
|
|||||||
currDir));
|
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);
|
Thread.sleep(500);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException expected) {
|
||||||
// nothing to do, thread was interrupted externally
|
|
||||||
// signaling the end of AddImageProcess
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* @param panel instance of ImageTypePanel to change to
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private void updateCurrentPanel(JPanel panel) {
|
private void updateCurrentPanel(JPanel panel) {
|
||||||
currentPanel = panel;
|
currentPanel = panel;
|
||||||
typePanel.removeAll();
|
typePanel.removeAll();
|
||||||
|
@ -68,6 +68,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
|
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
|
||||||
|
|
||||||
private DataSourceProcessor dsProcessor;
|
private DataSourceProcessor dsProcessor;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
|
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
|
||||||
this.addImageAction = action;
|
this.addImageAction = action;
|
||||||
@ -228,6 +229,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
@Override
|
@Override
|
||||||
void cleanup() throws Exception {
|
void cleanup() throws Exception {
|
||||||
cancelDataSourceProcessing(dataSourceId);
|
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) {
|
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||||
dataSourceProcessorDone(dataSourceId, result, errList, contents);
|
dataSourceProcessorDone(dataSourceId, result, errList, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
progressPanel.setStateStarted();
|
progressPanel.setStateStarted();
|
||||||
@ -258,9 +259,6 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
* Cancels the data source processing - in case the users presses 'Cancel'
|
* Cancels the data source processing - in case the users presses 'Cancel'
|
||||||
*/
|
*/
|
||||||
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
||||||
new Thread(() -> {
|
|
||||||
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
|
||||||
}).start();
|
|
||||||
dsProcessor.cancel();
|
dsProcessor.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,21 +301,23 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
progressPanel.addErrors(err, critErr);
|
progressPanel.addErrors(err, critErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
newContents.clear();
|
|
||||||
newContents.addAll(contents);
|
|
||||||
|
|
||||||
//notify the UI of the new content added to the case
|
//notify the UI of the new content added to the case
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
if (!newContents.isEmpty()) {
|
if (!contents.isEmpty()) {
|
||||||
Case.getCurrentCase().notifyDataSourceAdded(newContents.get(0), dataSourceId);
|
Case.getCurrentCase().notifyDataSourceAdded(contents.get(0), dataSourceId);
|
||||||
} else {
|
} else {
|
||||||
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
// Start ingest if we can
|
if (!cancelled) {
|
||||||
progressPanel.setStateStarted();
|
newContents.clear();
|
||||||
startIngest();
|
newContents.addAll(contents);
|
||||||
|
progressPanel.setStateStarted();
|
||||||
|
startIngest();
|
||||||
|
} else {
|
||||||
|
cancelled = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,11 +219,11 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
|||||||
* multi-user (using PostgreSql)
|
* multi-user (using PostgreSql)
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({"Case_caseType_singleUser=Single-user case",
|
@NbBundle.Messages({"Case_caseType_singleUser=Single-user case",
|
||||||
"Case_caseType_multiUser=Multi-user case"})
|
"Case_caseType_multiUser=Multi-user case"})
|
||||||
public enum CaseType {
|
public enum CaseType {
|
||||||
|
|
||||||
SINGLE_USER_CASE(Bundle.Case_caseType_singleUser()),
|
SINGLE_USER_CASE("Single-user case"), //NON-NLS
|
||||||
MULTI_USER_CASE(Bundle.Case_caseType_multiUser());
|
MULTI_USER_CASE("Multi-user case"); //NON-NLS
|
||||||
|
|
||||||
private final String caseType;
|
private final String caseType;
|
||||||
|
|
||||||
@ -250,6 +250,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return caseType;
|
return caseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getLocalizedDisplayName() {
|
||||||
|
if (fromString(caseType) == SINGLE_USER_CASE) {
|
||||||
|
return Bundle.Case_caseType_singleUser();
|
||||||
|
} else {
|
||||||
|
return Bundle.Case_caseType_multiUser();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -92,7 +92,7 @@ class CasePropertiesForm extends javax.swing.JPanel {
|
|||||||
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(currentCase.getConfigFilePath()));
|
CaseMetadata caseMetadata = new CaseMetadata(Paths.get(currentCase.getConfigFilePath()));
|
||||||
tbDbName.setText(caseMetadata.getCaseDatabaseName());
|
tbDbName.setText(caseMetadata.getCaseDatabaseName());
|
||||||
Case.CaseType caseType = caseMetadata.getCaseType();
|
Case.CaseType caseType = caseMetadata.getCaseType();
|
||||||
tbDbType.setText(caseType.toString());
|
tbDbType.setText(caseType.getLocalizedDisplayName());
|
||||||
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
|
if (caseType == Case.CaseType.SINGLE_USER_CASE) {
|
||||||
deleteCaseButton.setEnabled(true);
|
deleteCaseButton.setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -466,7 +466,11 @@ final class CollaborationMonitor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
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
|
@Override
|
||||||
public void run() {
|
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;
|
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
|
* 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
|
* wizard. It also provides a run method overload to allow it to be used
|
||||||
* independently of the wizard.
|
* 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
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
public static String getType() {
|
public static String getType() {
|
||||||
return DATA_SOURCE_TYPE;
|
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
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getDataSourceType() {
|
public String getDataSourceType() {
|
||||||
return DATA_SOURCE_TYPE;
|
return getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the panel that allows a user to select a data source and do any
|
* 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
|
@Override
|
||||||
public JPanel getPanel() {
|
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
|
* @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
|
@Override
|
||||||
public boolean isPanelValid() {
|
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
|
* Adds a data source to the case database using a background task in a
|
||||||
* settings provided by the panel. Returns as soon as the background task is
|
* separate thread and the settings provided by the selection and
|
||||||
* started and uses the callback object to signal task completion and return
|
* configuration panel. Returns as soon as the background task is started.
|
||||||
* results.
|
* 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
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
* processing.
|
* background task to report progress.
|
||||||
* @param callback Callback to call when processing is done.
|
* @param callback Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
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
|
* Adds a data source to the case database using a background task in a
|
||||||
* given settings instead of those provided by the panel. Returns as soon as
|
* separate thread and the given settings instead of those provided by the
|
||||||
* the background task is started and uses the callback object to signal
|
* selection and configuration panel. Returns as soon as the background task
|
||||||
* task completion and return results.
|
* is started and uses the callback object to signal task completion and
|
||||||
|
* return results.
|
||||||
*
|
*
|
||||||
* @param deviceId An ASCII-printable identifier for the device
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
* associated with the data source that is
|
* 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
|
* Requests cancellation of the background task that adds a data source to
|
||||||
* started using the run method. Cancellation is not guaranteed.
|
* 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
|
@Override
|
||||||
public void cancel() {
|
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
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@ -199,7 +209,7 @@ public class ImageDSProcessor implements DataSourceProcessor {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the configuration of the data source processor without using the
|
* 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 imagePath Path to the image file.
|
||||||
* @param timeZone The time zone to use when processing dates
|
* @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))
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||||
String oldText = pathTextField.getText();
|
String oldText = pathTextField.getText();
|
||||||
// set the current directory of the FileChooser if the ImagePath Field is valid
|
// 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
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
public static String getType() {
|
public static String getType() {
|
||||||
return DATA_SOURCE_TYPE;
|
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
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getDataSourceType() {
|
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
|
* 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
|
@Override
|
||||||
public JPanel getPanel() {
|
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
|
* @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
|
@Override
|
||||||
public boolean isPanelValid() {
|
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
|
* Adds a data source to the case database using a background task in a
|
||||||
* settings provided by the panel. Returns as soon as the background task is
|
* separate thread and the settings provided by the selection and
|
||||||
* started and uses the callback object to signal task completion and return
|
* configuration panel. Returns as soon as the background task is started.
|
||||||
* results.
|
* 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
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
* processing.
|
* background task to report progress.
|
||||||
* @param callback Callback to call when processing is done.
|
* @param callback Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
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
|
* Adds a data source to the case database using a background task in a
|
||||||
* given settings instead of those provided by the panel. Returns as soon as
|
* separate thread and the given settings instead of those provided by the
|
||||||
* the background task is started and uses the callback object to signal
|
* selection and configuration panel. Returns as soon as the background task
|
||||||
* task completion and return results.
|
* is started and uses the callback object to signal task completion and
|
||||||
|
* return results.
|
||||||
*
|
*
|
||||||
* @param deviceId An ASCII-printable identifier for the device
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
* associated with the data source that is
|
* 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
|
* Requests cancellation of the background task that adds a data source to
|
||||||
* started using the run method. Cancellation is not guaranteed.
|
* 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
|
@Override
|
||||||
public void cancel() {
|
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
|
@Override
|
||||||
public void reset() {
|
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
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
public static String getType() {
|
public static String getType() {
|
||||||
return DATA_SOURCE_TYPE;
|
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
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getDataSourceType() {
|
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
|
* 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
|
@Override
|
||||||
public JPanel getPanel() {
|
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
|
* @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
|
@Override
|
||||||
public boolean isPanelValid() {
|
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
|
* Adds a data source to the case database using a background task in a
|
||||||
* settings provided by the panel. Returns as soon as the background task is
|
* separate thread and the settings provided by the selection and
|
||||||
* started and uses the callback object to signal task completion and return
|
* configuration panel. Returns as soon as the background task is started.
|
||||||
* results.
|
* 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
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
* processing.
|
* background task to report progress.
|
||||||
* @param callback Callback to call when processing is done.
|
* @param callback Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
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
|
* Adds a data source to the case database using a background task in a
|
||||||
* given settings instead of those provided by the panel. Returns as soon as
|
* separate thread and the given settings instead of those provided by the
|
||||||
* the background task is started and uses the callback object to signal
|
* selection and configuration panel. Returns as soon as the background task
|
||||||
* task completion and return results.
|
* is started and uses the callback object to signal task completion and
|
||||||
|
* return results.
|
||||||
*
|
*
|
||||||
* @param deviceId An ASCII-printable identifier for the
|
* @param deviceId An ASCII-printable identifier for the
|
||||||
* device associated with the data source
|
* 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
|
* Requests cancellation of the background task that adds a data source to
|
||||||
* started using the run method. Cancellation is not guaranteed.
|
* 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
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
/*
|
|
||||||
* Cancellation is not currently supported.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the panel.
|
* Resets the selection and configuration panel for this data source
|
||||||
|
* processor.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
@ -239,7 +239,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
|
|
||||||
Object res2 = DialogDisplayer.getDefault().notify(d2);
|
Object res2 = DialogDisplayer.getDefault().notify(d2);
|
||||||
if (res2 != null && res2 == DialogDescriptor.YES_OPTION) {
|
if (res2 != null && res2 == DialogDescriptor.YES_OPTION) {
|
||||||
// if user say yes
|
// if user says yes
|
||||||
try {
|
try {
|
||||||
createDirectory(caseDirPath, getComponent().getCaseType());
|
createDirectory(caseDirPath, getComponent().getCaseType());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@ -251,7 +251,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res2 != null && res2 == DialogDescriptor.NO_OPTION) {
|
if (res2 != null && res2 == DialogDescriptor.NO_OPTION) {
|
||||||
// if user say no
|
// if user says no
|
||||||
validationError(NbBundle.getMessage(this.getClass(),
|
validationError(NbBundle.getMessage(this.getClass(),
|
||||||
"NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg",
|
"NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg",
|
||||||
caseDirPath));
|
caseDirPath));
|
||||||
|
@ -389,7 +389,11 @@ public class ServicesMonitor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
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
|
* Interface implemented by classes that add data sources of a particular type
|
||||||
* (e.g., images, local disks, virtual directories of local/logical files, etc.)
|
* (e.g., images, local disks, virtual directories of local/logical files) to a
|
||||||
* to a case database. A data source processor is NOT responsible for analyzing
|
* case database. A data source processor is NOT responsible for analyzing the
|
||||||
* the data source (running ingest modules on the data source and its contents).
|
* 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
|
* 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
|
* provide a UI panel to allow a user to select a data source and do any
|
||||||
* configuration the data source processor may require. The panel should support
|
* configuration required by the data source processor. The selection and
|
||||||
* addition of the add data source wizard as a property change listener and
|
* configuration panel should support addition of the add data source wizard as
|
||||||
* should fire DSP_PANEL_EVENT property changes to communicate with the wizard.
|
* 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,
|
* Data source processors should perform all processing in a background task in
|
||||||
* reporting results using a callback object.
|
* 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 {
|
public interface DataSourceProcessor {
|
||||||
|
|
||||||
@ -48,64 +54,76 @@ public interface DataSourceProcessor {
|
|||||||
enum DSP_PANEL_EVENT {
|
enum DSP_PANEL_EVENT {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire this event when the user changes something in the panel to
|
* This event is fired when the user changes something in the selection
|
||||||
* notify the add data source wizard that it should call isPanelValid.
|
* and configuration panel. It notifies the add data source wizard that
|
||||||
|
* it should call isPanelValid.
|
||||||
*/
|
*/
|
||||||
UPDATE_UI,
|
UPDATE_UI,
|
||||||
/**
|
/**
|
||||||
* Fire this event to make the add data source wizard move focus to the
|
* This event is fired to make the add data source wizard move focus to
|
||||||
* next button.
|
* the wizard's next button.
|
||||||
|
* @deprecated Use UPDATE_UI.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
FOCUS_NEXT
|
FOCUS_NEXT
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a string that describes the type of data sources this processor is
|
* 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
|
* @return A data source type display string for this data source processor.
|
||||||
* selection UI component (e.g., a combo box).
|
|
||||||
*/
|
*/
|
||||||
String getDataSourceType();
|
String getDataSourceType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the panel that allows a user to select a data source and do any
|
* 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();
|
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
|
* @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();
|
boolean isPanelValid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a data source to the case database using a separate thread and the
|
* Adds a data source to the case database using a background task in a
|
||||||
* settings provided by the panel. Returns as soon as the background task is
|
* separate thread and the settings provided by the selection and
|
||||||
* started and uses the callback object to signal task completion and return
|
* configuration panel. Returns as soon as the background task is started.
|
||||||
* results.
|
* 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
|
* @param progressMonitor Progress monitor that will be used by the
|
||||||
* processing.
|
* background task to report progress.
|
||||||
* @param callback Callback to call when processing is done.
|
* @param callback Callback that will be used by the background task
|
||||||
|
* to return results.
|
||||||
*/
|
*/
|
||||||
void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback);
|
void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests cancellation of the data source processing task after it is
|
* Requests cancellation of the background task that adds a data source to
|
||||||
* started using the run method. Cancellation is not guaranteed.
|
* 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();
|
void cancel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the panel.
|
* Resets the selection and configuration panel for this data source
|
||||||
|
* processor.
|
||||||
*/
|
*/
|
||||||
void reset();
|
void reset();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-2014 Basis Technology Corp.
|
* Copyright 2013-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -23,56 +23,72 @@ import java.util.List;
|
|||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for a callback for a DataSourceProcessor.
|
* 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
|
||||||
* Ensures that DSP invokes the caller overridden method, doneEDT(), in the EDT
|
* database. The callback objects are used to signal task completion and return
|
||||||
* thread.
|
* results.
|
||||||
*
|
*
|
||||||
|
* Concrete implementations of DataSourceProcessorCallback should override
|
||||||
|
* either the done method or the doneEDT method, but not both.
|
||||||
*/
|
*/
|
||||||
public abstract class DataSourceProcessorCallback {
|
public abstract class DataSourceProcessorCallback {
|
||||||
|
|
||||||
public enum DataSourceProcessorResult {
|
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).
|
* No errors occurred while ading the data source to the case database.
|
||||||
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,
|
||||||
|
/**
|
||||||
|
* 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
|
* Called by a data source processor when it is done adding a data source to
|
||||||
* the database. Users of the DSP can override this method if they do not
|
* the case database, this method adds a task to call the doneEDT method to
|
||||||
* want to be notified on the EDT. Otherwise, this method will call
|
* the EDT task queue.
|
||||||
* doneEDT() with the same arguments.
|
|
||||||
*
|
*
|
||||||
* @param result Code for status
|
* IMPORTANT: Concrete implementations of DataSourceProcessorCallback should
|
||||||
* @param errList List of error strings
|
* override this method if the callback SHOULD NOT be done in the EDT.
|
||||||
* @param newContents List of root Content objects that were added to
|
*
|
||||||
* database. Typically only one is given.
|
* @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 DataSourceProcessorResult resultf = result;
|
||||||
final List<String> errListf = errList;
|
final List<String> errListf = errList;
|
||||||
final List<Content> newContentsf = newContents;
|
final List<Content> newContentsf = newDataSources;
|
||||||
|
EventQueue.invokeLater(() -> {
|
||||||
// Invoke doneEDT() that runs on the EDT .
|
doneEDT(resultf, errListf, newContentsf);
|
||||||
EventQueue.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
doneEDT(resultf, errListf, newContentsf);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by done() if the default implementation is used. Users of DSPs
|
* Called by a data source processor when it is done adding a data source to
|
||||||
* that have UI updates to do after the DSP is finished adding the DS can
|
* the case database, if the default done method has not been overridden.
|
||||||
* implement this method to receive the updates on the EDT.
|
|
||||||
*
|
*
|
||||||
* @param result Code for status
|
* IMPORTANT: Concrete implementations of DataSourceProcessorCallback should
|
||||||
* @param errList List of error strings
|
* override the done method and provide an implementation of this method
|
||||||
* @param newContents List of root Content objects that were added to
|
* that throws an UnsupportedOperationException if the callback SHOULD NOT
|
||||||
* database. Typically only one is given.
|
* 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
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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 {
|
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 URL url = null;
|
||||||
|
private final Icon about;
|
||||||
private Icon about;
|
|
||||||
|
|
||||||
private boolean verboseLogging;
|
private boolean verboseLogging;
|
||||||
|
|
||||||
|
public AboutWindowPanel() {
|
||||||
|
about = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/splash.png"));
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
public AboutWindowPanel(String pathToBrandingImage) {
|
public AboutWindowPanel(String pathToBrandingImage) {
|
||||||
about = new ImageIcon(ImageUtilities.loadImage(pathToBrandingImage));
|
about = new ImageIcon(ImageUtilities.loadImage(pathToBrandingImage));
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
initComponents();
|
initComponents();
|
||||||
logoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
logoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||||
description.setText(org.openide.util.NbBundle.getMessage(AboutWindowPanel.class,
|
description.setText(org.openide.util.NbBundle.getMessage(AboutWindowPanel.class,
|
||||||
@ -68,7 +74,6 @@ public final class AboutWindowPanel extends JPanel implements HyperlinkListener
|
|||||||
if (verboseLoggingIsSet()) {
|
if (verboseLoggingIsSet()) {
|
||||||
disableVerboseLoggingButton();
|
disableVerboseLoggingButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <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.bufferingInterrupted=media buffering was interrupted
|
||||||
FXVideoPanel.progress.errorWritingVideoToDisk=Error writing video to disk
|
FXVideoPanel.progress.errorWritingVideoToDisk=Error writing video to disk
|
||||||
OptionsCategory_Name_Multi_User_Settings=Multi-user
|
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.lbSolrSettings.text=Solr Settings
|
||||||
MultiUserSettingsPanel.cbEnableMultiUser.text=Enable Multi-user cases
|
MultiUserSettingsPanel.cbEnableMultiUser.text=Enable Multi-user cases
|
||||||
MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings
|
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
|
// if the artifact has an ASSOCIATED ARTIFACT, then we display the associated artifact instead
|
||||||
try {
|
try {
|
||||||
for (BlackboardAttribute attr : artifact.getAttributes()) {
|
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();
|
long assocArtifactId = attr.getValueLong();
|
||||||
int assocArtifactIndex = -1;
|
int assocArtifactIndex = -1;
|
||||||
for (BlackboardArtifact art : artifacts) {
|
for (BlackboardArtifact art : artifacts) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -23,38 +23,67 @@ import org.openide.nodes.FilterNode;
|
|||||||
import org.openide.nodes.Node;
|
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 {
|
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) {
|
TableFilterChildren(Node wrappedNode) {
|
||||||
super(arg);
|
super(wrappedNode);
|
||||||
}
|
|
||||||
|
|
||||||
@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)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
@Override
|
||||||
if (createChild) {
|
protected Node copyNode(Node nodeToCopy) {
|
||||||
return new TableFilterChildren(arg);
|
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 {
|
} else {
|
||||||
return Children.LEAF;
|
return Children.LEAF;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -23,48 +23,40 @@ import org.openide.nodes.Node;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to filter the nodes that we want to show on the
|
* A filter node that creates at most one layer of child nodes for the node it
|
||||||
* "TreeTableView". So basically we just want to show one layer of nodes from
|
* wraps. It is designed to be used for nodes displayed in Autopsy table views.
|
||||||
* it's parent.
|
|
||||||
*
|
|
||||||
* @author jantonius
|
|
||||||
*/
|
*/
|
||||||
public class TableFilterNode extends FilterNode {
|
public class TableFilterNode extends FilterNode {
|
||||||
|
|
||||||
private boolean createChild;
|
private final boolean createChildren;
|
||||||
private String itemType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the constructor
|
* 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
|
||||||
public TableFilterNode(Node arg, boolean crChild) {
|
* Autopsy table views.
|
||||||
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".
|
|
||||||
*
|
*
|
||||||
* @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
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
if (createChild) {
|
if (createChildren) {
|
||||||
return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text");
|
return NbBundle.getMessage(this.getClass(), "TableFilterNode.displayName.text");
|
||||||
} else {
|
} else {
|
||||||
return super.getDisplayName();
|
return super.getDisplayName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getItemType() {
|
|
||||||
return itemType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -72,19 +72,19 @@ public class ArtifactStringContent implements StringContent {
|
|||||||
|
|
||||||
// name column
|
// name column
|
||||||
buffer.append("<tr><td>"); //NON-NLS
|
buffer.append("<tr><td>"); //NON-NLS
|
||||||
buffer.append(attr.getAttributeTypeDisplayName());
|
buffer.append(attr.getAttributeType().getDisplayName());
|
||||||
buffer.append("</td>"); //NON-NLS
|
buffer.append("</td>"); //NON-NLS
|
||||||
|
|
||||||
// value column
|
// value column
|
||||||
buffer.append("<td>"); //NON-NLS
|
buffer.append("<td>"); //NON-NLS
|
||||||
if (attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()
|
if (attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID()
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID()
|
||||||
|| attr.getAttributeTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()) {
|
|| attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()) {
|
||||||
long epoch = attr.getValueLong();
|
long epoch = attr.getValueLong();
|
||||||
String time = "0000-00-00 00:00:00";
|
String time = "0000-00-00 00:00:00";
|
||||||
if (epoch != 0) {
|
if (epoch != 0) {
|
||||||
@ -93,7 +93,7 @@ public class ArtifactStringContent implements StringContent {
|
|||||||
}
|
}
|
||||||
buffer.append(time);
|
buffer.append(time);
|
||||||
} else {
|
} else {
|
||||||
switch (attr.getValueType()) {
|
switch (attr.getAttributeType().getValueType()) {
|
||||||
case STRING:
|
case STRING:
|
||||||
String str = attr.getValueString();
|
String str = attr.getValueString();
|
||||||
str = str.replaceAll(" ", " "); //NON-NLS
|
str = str.replaceAll(" ", " "); //NON-NLS
|
||||||
|
@ -117,7 +117,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
|||||||
if (artifact != null && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
|
if (artifact != null && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
|
||||||
try {
|
try {
|
||||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
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());
|
BlackboardArtifact associatedArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(attribute.getValueLong());
|
||||||
if (associatedArtifact != null) {
|
if (associatedArtifact != null) {
|
||||||
displayName = associatedArtifact.getDisplayName() + " Artifact"; // NON-NLS
|
displayName = associatedArtifact.getDisplayName() + " Artifact"; // NON-NLS
|
||||||
@ -171,7 +171,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
|||||||
AbstractFile af = (AbstractFile) associated;
|
AbstractFile af = (AbstractFile) associated;
|
||||||
ext = af.getNameExtension();
|
ext = af.getNameExtension();
|
||||||
actualMimeType = af.getMIMEType();
|
actualMimeType = af.getMIMEType();
|
||||||
if(actualMimeType == null) {
|
if (actualMimeType == null) {
|
||||||
actualMimeType = "";
|
actualMimeType = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,11 +179,11 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
|||||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.displayName"),
|
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.ext.displayName"),
|
||||||
NO_DESCR,
|
NO_DESCR,
|
||||||
ext));
|
ext));
|
||||||
ss.put(new NodeProperty<>(
|
ss.put(new NodeProperty<>(
|
||||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.name"),
|
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.name"),
|
||||||
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.displayName"),
|
NbBundle.getMessage(this.getClass(), "BlackboardArtifactNode.createSheet.mimeType.displayName"),
|
||||||
NO_DESCR,
|
NO_DESCR,
|
||||||
actualMimeType));
|
actualMimeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Arrays.asList(SHOW_UNIQUE_PATH).contains(artifactTypeId)) {
|
if (Arrays.asList(SHOW_UNIQUE_PATH).contains(artifactTypeId)) {
|
||||||
@ -282,8 +282,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode {
|
|||||||
/**
|
/**
|
||||||
* Fill map with Artifact properties
|
* Fill map with Artifact properties
|
||||||
*
|
*
|
||||||
* @param map map with preserved ordering, where property names/values are
|
* @param map map with preserved ordering, where property names/values
|
||||||
* put
|
* are put
|
||||||
* @param artifact to extract properties from
|
* @param artifact to extract properties from
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation") // TODO: Remove this when TSK_TAGGED_ARTIFACT rows are removed in a database upgrade.
|
@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 keyword = null;
|
||||||
String regexp = null;
|
String regexp = null;
|
||||||
for (BlackboardAttribute att : attributes) {
|
for (BlackboardAttribute att : attributes) {
|
||||||
final int attributeTypeID = att.getAttributeTypeID();
|
final int attributeTypeID = att.getAttributeType().getTypeID();
|
||||||
if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
|
if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
|
||||||
keyword = att.getValueString();
|
keyword = att.getValueString();
|
||||||
} else if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()) {
|
} else if (attributeTypeID == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()) {
|
||||||
|
@ -271,8 +271,8 @@ public class DataResultFilterNode extends FilterNode {
|
|||||||
Content c = null;
|
Content c = null;
|
||||||
try {
|
try {
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
for (BlackboardAttribute attr : art.getAttributes()) {
|
||||||
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
|
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()) {
|
||||||
switch (attr.getValueType()) {
|
switch (attr.getAttributeType().getValueType()) {
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
int i = attr.getValueInt();
|
int i = attr.getValueInt();
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
|
@ -865,7 +865,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
String setName = null;
|
String setName = null;
|
||||||
List<BlackboardAttribute> attributes = art.getAttributes();
|
List<BlackboardAttribute> attributes = art.getAttributes();
|
||||||
for (BlackboardAttribute att : attributes) {
|
for (BlackboardAttribute att : attributes) {
|
||||||
int typeId = att.getAttributeTypeID();
|
int typeId = att.getAttributeType().getTypeID();
|
||||||
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
||||||
setName = att.getValueString();
|
setName = att.getValueString();
|
||||||
}
|
}
|
||||||
@ -882,7 +882,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
String keywordName = null;
|
String keywordName = null;
|
||||||
List<BlackboardAttribute> attributes = art.getAttributes();
|
List<BlackboardAttribute> attributes = art.getAttributes();
|
||||||
for (BlackboardAttribute att : attributes) {
|
for (BlackboardAttribute att : attributes) {
|
||||||
int typeId = att.getAttributeTypeID();
|
int typeId = att.getAttributeType().getTypeID();
|
||||||
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
||||||
listName = att.getValueString();
|
listName = att.getValueString();
|
||||||
} else if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
|
} else if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()) {
|
||||||
@ -909,7 +909,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
String setName = null;
|
String setName = null;
|
||||||
List<BlackboardAttribute> attributes = art.getAttributes();
|
List<BlackboardAttribute> attributes = art.getAttributes();
|
||||||
for (BlackboardAttribute att : attributes) {
|
for (BlackboardAttribute att : attributes) {
|
||||||
int typeId = att.getAttributeTypeID();
|
int typeId = att.getAttributeType().getTypeID();
|
||||||
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
if (typeId == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()) {
|
||||||
setName = att.getValueString();
|
setName = att.getValueString();
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public final class AutopsyEventPublisher {
|
|||||||
* Composed of thread-safe objects.
|
* Composed of thread-safe objects.
|
||||||
*/
|
*/
|
||||||
private static final Logger logger = Logger.getLogger(AutopsyEventPublisher.class.getName());
|
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 final LocalEventPublisher localPublisher;
|
||||||
private RemoteEventPublisher remotePublisher;
|
private RemoteEventPublisher remotePublisher;
|
||||||
private String currentChannelName;
|
private String currentChannelName;
|
||||||
@ -86,15 +86,8 @@ public final class AutopsyEventPublisher {
|
|||||||
* events from other Autopsy nodes.
|
* events from other Autopsy nodes.
|
||||||
*/
|
*/
|
||||||
public void closeRemoteEventChannel() {
|
public void closeRemoteEventChannel() {
|
||||||
|
stopRemotePublisher();
|
||||||
currentChannelName = null;
|
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.
|
* @param event The event to publish.
|
||||||
*/
|
*/
|
||||||
public void publishRemotely(AutopsyEvent event) {
|
public void publishRemotely(AutopsyEvent event) {
|
||||||
/*
|
|
||||||
* This is a no-op if a remote channel has not been opened.
|
|
||||||
*/
|
|
||||||
if (null != currentChannelName) {
|
if (null != currentChannelName) {
|
||||||
boolean published = false;
|
boolean published = false;
|
||||||
int tryCount = 1;
|
int tryCount = 1;
|
||||||
|
|
||||||
while (false == published && tryCount <= MAX_REMOTE_EVENT_PUBLISH_TRIES) {
|
while (false == published && tryCount <= MAX_REMOTE_EVENT_PUBLISH_TRIES) {
|
||||||
try {
|
try {
|
||||||
if (null == remotePublisher) {
|
if (null == remotePublisher) {
|
||||||
@ -175,16 +166,28 @@ public final class AutopsyEventPublisher {
|
|||||||
}
|
}
|
||||||
remotePublisher.publish(event);
|
remotePublisher.publish(event);
|
||||||
published = true;
|
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
|
logger.log(Level.SEVERE, String.format("Failed to publish %s using channel %s (tryCount = %s)", event.getPropertyName(), currentChannelName, tryCount), ex); //NON-NLS
|
||||||
closeRemoteEventChannel();
|
stopRemotePublisher();
|
||||||
++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
|
|
||||||
++tryCount;
|
++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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -115,5 +115,5 @@ IngestJob.cancelReason.notCancelled.text=Not cancelled
|
|||||||
IngestJob.cancelReason.cancelledByUser.text=Cancelled by user
|
IngestJob.cancelReason.cancelledByUser.text=Cancelled by user
|
||||||
IngestJob.cancelReason.ingestModStartFail.text=Ingest modules startup failed
|
IngestJob.cancelReason.ingestModStartFail.text=Ingest modules startup failed
|
||||||
IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space
|
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
|
IngestJob.cancelReason.caseClosed.text=Case closed
|
||||||
|
@ -1,116 +1,115 @@
|
|||||||
CTL_IngestMessageTopComponent=\u30E1\u30C3\u30BB\u30FC\u30B8
|
CTL_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8
|
||||||
HINT_IngestMessageTopComponent=\u30E1\u30C3\u30BB\u30FC\u30B8\u30A6\u30A3\u30F3\u30C9\u30A6
|
HINT_IngestMessageTopComponent=\u30e1\u30c3\u30bb\u30fc\u30b8\u30a6\u30a3\u30f3\u30c9\u30a6
|
||||||
IngestDialog.closeButton.title=\u9589\u3058\u308B
|
IngestDialog.closeButton.title=\u9589\u3058\u308b
|
||||||
IngestDialog.startButton.title=\u958B\u59CB
|
IngestDialog.startButton.title=\u958b\u59cb
|
||||||
IngestDialog.title.text=\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
|
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.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
|
||||||
IngestJob.progress.dataSourceIngest.displayName={1}\u306E{0}
|
IngestJob.progress.dataSourceIngest.displayName={1}\u306e{0}
|
||||||
IngestJob.progress.fileIngest.displayName={0}\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u89E3\u6790\u4E2D
|
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=\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.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.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
|
||||||
IngestManager.StartIngestJobsTask.run.displayName=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u958B\u59CB\u4E2D
|
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.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.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.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.data.text=\ \u30c7\u30fc\u30bf\uff1a{0}
|
||||||
IngestMessage.toString.date.text=\ \u65E5\u4ED8\uFF1A{0}
|
IngestMessage.toString.date.text=\ \u65e5\u4ed8\uff1a{0}
|
||||||
IngestMessage.toString.details.text=\ \u8A73\u7D30\uFF1A{0}
|
IngestMessage.toString.details.text=\ \u8a73\u7d30\uff1a{0}
|
||||||
IngestMessage.toString.subject.text=\ \u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\uFF1A{0}
|
IngestMessage.toString.subject.text=\ \u30b5\u30d6\u30b8\u30a7\u30af\u30c8\uff1a{0}
|
||||||
IngestMessage.toString.type.text=\u30BF\u30A4\u30D7\uFF1A{0}
|
IngestMessage.toString.type.text=\u30bf\u30a4\u30d7\uff1a{0}
|
||||||
IngestMessageDetailsPanel.copyMenuItem.text=\u30B3\u30D4\u30FC
|
IngestMessageDetailsPanel.copyMenuItem.text=\u30b3\u30d4\u30fc
|
||||||
IngestMessageDetailsPanel.messageDetailsPane.contentType=\u30C6\u30AD\u30B9\u30C8\uFF0Fhtml
|
IngestMessageDetailsPanel.messageDetailsPane.contentType=\u30c6\u30ad\u30b9\u30c8\uff0fhtml
|
||||||
IngestMessageDetailsPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E
|
IngestMessageDetailsPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e
|
||||||
IngestMessageDetailsPanel.viewArtifactButton.text=\u7D50\u679C\u3078\u79FB\u52D5
|
IngestMessageDetailsPanel.viewArtifactButton.text=\u7d50\u679c\u3078\u79fb\u52d5
|
||||||
IngestMessageDetailsPanel.viewContentButton.text=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\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.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.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=\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.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.module=\u30e2\u30b8\u30e5\u30fc\u30eb
|
||||||
IngestMessagePanel.MsgTableMod.colNames.new=\u65B0\u898F\uFF1F
|
IngestMessagePanel.MsgTableMod.colNames.new=\u65b0\u898f\uff1f
|
||||||
IngestMessagePanel.MsgTableMod.colNames.num=\u756A\u53F7
|
IngestMessagePanel.MsgTableMod.colNames.num=\u756a\u53f7
|
||||||
IngestMessagePanel.MsgTableMod.colNames.subject=\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8
|
IngestMessagePanel.MsgTableMod.colNames.subject=\u30b5\u30d6\u30b8\u30a7\u30af\u30c8
|
||||||
IngestMessagePanel.MsgTableMod.colNames.timestamp=\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7
|
IngestMessagePanel.MsgTableMod.colNames.timestamp=\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7
|
||||||
IngestMessagePanel.sortByComboBox.model.priority=\u512A\u5148\u5EA6
|
IngestMessagePanel.sortByComboBox.model.priority=\u512a\u5148\u5ea6
|
||||||
IngestMessagePanel.sortByComboBox.model.time=\u6642\u9593
|
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.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.sortByLabel.text=\u6b21\u3067\u30bd\u30fc\u30c8\uff1a
|
||||||
IngestMessagePanel.totalMessagesNameLabel.text=\u5408\u8A08\uFF1A
|
IngestMessagePanel.totalMessagesNameLabel.text=\u5408\u8a08\uff1a
|
||||||
IngestMessagePanel.totalMessagesNameVal.text=-
|
IngestMessagePanel.totalMessagesNameVal.text=-
|
||||||
IngestMessagePanel.totalUniqueMessagesNameLabel.text=\u30E6\u30CB\u30FC\u30AF\uFF1A
|
IngestMessagePanel.totalUniqueMessagesNameLabel.text=\u30e6\u30cb\u30fc\u30af\uff1a
|
||||||
IngestMessagePanel.totalUniqueMessagesNameVal.text=-
|
IngestMessagePanel.totalUniqueMessagesNameVal.text=-
|
||||||
IngestMessagesToolbar.customizeButton.toolTipText=\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
|
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.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.GenRpt=\u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210
|
||||||
IngestMessageTopComponent.displayReport.option.OK=OK
|
IngestMessageTopComponent.displayReport.option.OK=OK
|
||||||
IngestMessageTopComponent.initComponents.name=\u30A4\u30F3\u30DC\u30C3\u30AF\u30B9\u3092\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8
|
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
|
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.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
|
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
|
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.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.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.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
|
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
|
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
|
IngestJob.progress.dataSourceIngest.initialDisplayName={0}\u3092\u89e3\u6790\u4e2d
|
||||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9
|
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.elapsedTime=\u7d4c\u904e\u6642\u9593\uff08\u6642\uff1a\u5206\uff1a\u79d2\uff09
|
||||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file=\u30D5\u30A1\u30A4\u30EB
|
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file=\u30d5\u30a1\u30a4\u30eb
|
||||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime=\u958B\u59CB\u6642\u9593
|
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime=\u958b\u59cb\u6642\u9593
|
||||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.threadID=\u30B9\u30EC\u30C3\u30C9ID
|
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.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.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.IngestMessage.ErrorMessageLimitReached.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30de\u30cd\u30b8\u30e3\u30fc
|
||||||
IngestManager.IngestThreadActivitySnapshot.idleThread=\u30A2\u30A4\u30C9\u30EB
|
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
|
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.closeButton.text=\u9589\u3058\u308b
|
||||||
IngestProgressSnapshotPanel.refreshButton.text=\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5
|
IngestProgressSnapshotPanel.refreshButton.text=\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5
|
||||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3
|
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
|
||||||
IngestJobSettingsPanel.advancedButton.actionCommand=\u30A2\u30C9\u30D0\u30F3\u30B9
|
IngestJobSettingsPanel.advancedButton.actionCommand=\u30a2\u30c9\u30d0\u30f3\u30b9
|
||||||
IngestJobSettingsPanel.advancedButton.text=\u30A2\u30C9\u30D0\u30F3\u30B9
|
IngestJobSettingsPanel.advancedButton.text=\u30a2\u30c9\u30d0\u30f3\u30b9
|
||||||
ModuleTableModel.colName.duration=\u6240\u8981\u6642\u9593
|
ModuleTableModel.colName.duration=\u6240\u8981\u6642\u9593
|
||||||
IngestJob.cancellationDialog.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u30AD\u30E3\u30F3\u30BB\u30EB
|
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
|
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.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
|
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.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
|
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.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
|
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.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
|
||||||
IngestJobTableModel.colName.dirQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
|
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.filesPerSec=\u30d5\u30a1\u30a4\u30eb\uff0f\u79d2
|
||||||
IngestJobTableModel.colName.filesQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
IngestJobTableModel.colName.filesQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb
|
||||||
IngestJobTableModel.colName.inProgress=\u51E6\u7406\u4E2D
|
IngestJobTableModel.colName.inProgress=\u51e6\u7406\u4e2d
|
||||||
IngestJobTableModel.colName.jobID=\u30B8\u30E7\u30D6ID
|
IngestJobTableModel.colName.jobID=\u30b8\u30e7\u30d6ID
|
||||||
IngestJobTableModel.colName.numProcessed=\u51E6\u7406\u3055\u308C\u305F\u6570
|
IngestJobTableModel.colName.numProcessed=\u51e6\u7406\u3055\u308c\u305f\u6570
|
||||||
IngestJobTableModel.colName.rootQueued=\u30AD\u30E5\u30FC\u3055\u308C\u305F\u30EB\u30FC\u30C8
|
IngestJobTableModel.colName.rootQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305f\u30eb\u30fc\u30c8
|
||||||
IngestJobTableModel.colName.start=\u30B9\u30BF\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
|
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
|
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.jobID=\u30b8\u30e7\u30d6ID
|
||||||
ModuleTableModel.colName.module=\u30E2\u30B8\u30E5\u30FC\u30EB
|
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.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
|
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
|
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
|
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.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
|
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
|
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
|
IngestJobTableModel.colName.dsQueued=\u30ad\u30e5\u30fc\u3055\u308c\u305fDS
|
||||||
IngestJobSettingsPanel.jButtonSelectAll.text=\u5168\u3066\u9078\u629E
|
IngestJobSettingsPanel.jButtonSelectAll.text=\u5168\u3066\u9078\u629e
|
||||||
IngestJobSettingsPanel.jButtonDeselectAll.text=\u5168\u3066\u9078\u629E\u89E3\u9664
|
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.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
|
IngestManager.serviceIsDown.msgDlg.text={0}\u304c\u30c0\u30a6\u30f3\u3057\u3066\u3044\u307e\u3059
|
||||||
RunIngestSubMenu.menuItem.empty=\u30FC\u7A7A\u767D\u30FC
|
RunIngestSubMenu.menuItem.empty=\u30fc\u7a7a\u767d\u30fc
|
||||||
RunIngestModulesMenu.getName.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u5B9F\u884C
|
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
|
DataSourceIngestPipeline.moduleError.title.text={0}\u30a8\u30e9\u30fc
|
||||||
FileIngestPipeline.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.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.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.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.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
|
||||||
IngestJob.cancelReason.caseClosed.text=\u30B1\u30FC\u30B9\u3092\u9589\u3058\u307E\u3057\u305F
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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;
|
import org.python.util.PythonObjectInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates the ingest job settings for a particular context such as the Add
|
* Encapsulates the ingest job settings for a particular execution context.
|
||||||
* Data Source wizard or the Run Ingest Modules dialog.
|
* 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 {
|
public class IngestJobSettings {
|
||||||
|
|
||||||
@ -60,19 +62,30 @@ public class IngestJobSettings {
|
|||||||
private boolean processUnallocatedSpace;
|
private boolean processUnallocatedSpace;
|
||||||
private final List<String> warnings;
|
private final List<String> warnings;
|
||||||
|
|
||||||
// Determines which modeules to run
|
/**
|
||||||
|
* The type of ingest modules to run.
|
||||||
|
*/
|
||||||
public enum IngestType {
|
public enum IngestType {
|
||||||
|
|
||||||
// Run all modules
|
/**
|
||||||
|
* Run both data source level and file-level ingest modules.
|
||||||
|
*/
|
||||||
ALL_MODULES,
|
ALL_MODULES,
|
||||||
// Run only data source modules
|
/**
|
||||||
|
* Run only data source level ingest modules.
|
||||||
|
*/
|
||||||
DATA_SOURCE_ONLY,
|
DATA_SOURCE_ONLY,
|
||||||
// Run only files modules
|
/**
|
||||||
|
* Run only file level ingest modules.
|
||||||
|
*/
|
||||||
FILES_ONLY
|
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.
|
* @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 context The context identifier string.
|
||||||
* @param ingestType The type of modules ingest is running.
|
* @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() {
|
String getExecutionContext() {
|
||||||
return this.executionContext;
|
return this.executionContext;
|
||||||
|
@ -71,28 +71,27 @@ public class IngestManager {
|
|||||||
private static IngestManager instance;
|
private static IngestManager instance;
|
||||||
private final Object ingestMessageBoxLock = new Object();
|
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.
|
* 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
|
* Each runnable/callable task the ingest manager submits to its thread
|
||||||
* pools is given a unique thread/task ID.
|
* pools is given a unique thread/task ID.
|
||||||
*/
|
*/
|
||||||
private final AtomicLong nextThreadId;
|
private final AtomicLong nextThreadId;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Ingest jobs may be queued to be started on a pool thread by ingest job
|
* Ingest jobs may be queued to be started on a pool thread by start ingest
|
||||||
* starters. A mapping of thread/task IDs to the result objects associated
|
* job tasks. A mapping of task ids to the Future objects for each task is
|
||||||
* with each ingest job starter is maintained to provide handles that can be
|
* maintained to allow for task cancellation.
|
||||||
* used to cancel the ingest job starter.
|
|
||||||
*/
|
*/
|
||||||
private final ConcurrentHashMap<Long, Future<Void>> ingestJobStarters;
|
private final Map<Long, Future<Void>> startIngestJobTasks;
|
||||||
private final ExecutorService startIngestJobsThreadPool;
|
private final ExecutorService startIngestJobsThreadPool;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Ingest jobs use an ingest task scheduler to break themselves down into
|
* Ingest jobs use an ingest task scheduler to break themselves down into
|
||||||
* data source level and file level tasks. The ingest scheduler puts these
|
* data source level and file level tasks. The ingest scheduler puts these
|
||||||
* ingest tasks into queues for execution on ingest manager pool threads by
|
* ingest tasks into queues for execution on ingest manager pool threads by
|
||||||
@ -118,14 +117,14 @@ public class IngestManager {
|
|||||||
private AutopsyEventPublisher moduleEventPublisher;
|
private AutopsyEventPublisher moduleEventPublisher;
|
||||||
private final ExecutorService eventPublishingExecutor;
|
private final ExecutorService eventPublishingExecutor;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The ingest manager uses an ingest monitor to determine when system
|
* The ingest manager uses an ingest monitor to determine when system
|
||||||
* resources are under pressure. If the monitor detects such a situation, it
|
* 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.
|
* calls back to the ingest manager to cancel all ingest jobs in progress.
|
||||||
*/
|
*/
|
||||||
private final IngestMonitor ingestMonitor;
|
private final IngestMonitor ingestMonitor;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The ingest manager provides access to a top component that is used by
|
* 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
|
* ingest module to post messages for the user. A count of the posts is used
|
||||||
* as a cap to avoid bogging down the application.
|
* as a cap to avoid bogging down the application.
|
||||||
@ -134,7 +133,7 @@ public class IngestManager {
|
|||||||
private volatile IngestMessageTopComponent ingestMessageBox;
|
private volatile IngestMessageTopComponent ingestMessageBox;
|
||||||
private final AtomicLong ingestErrorMessagePosts;
|
private final AtomicLong ingestErrorMessagePosts;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The ingest manager supports reporting of ingest processing progress by
|
* The ingest manager supports reporting of ingest processing progress by
|
||||||
* collecting snapshots of the activities of the ingest threads, ingest job
|
* collecting snapshots of the activities of the ingest threads, ingest job
|
||||||
* progress, and ingest module run times.
|
* progress, and ingest module run times.
|
||||||
@ -142,13 +141,13 @@ public class IngestManager {
|
|||||||
private final ConcurrentHashMap<Long, IngestThreadActivitySnapshot> ingestThreadActivitySnapshots;
|
private final ConcurrentHashMap<Long, IngestThreadActivitySnapshot> ingestThreadActivitySnapshots;
|
||||||
private final ConcurrentHashMap<String, Long> ingestModuleRunTimes;
|
private final ConcurrentHashMap<String, Long> ingestModuleRunTimes;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The ingest job creation capability of the ingest manager can be turned on
|
* The ingest job creation capability of the ingest manager can be turned on
|
||||||
* and off to support an orderly shut down of the application.
|
* and off to support an orderly shut down of the application.
|
||||||
*/
|
*/
|
||||||
private volatile boolean jobCreationIsEnabled;
|
private volatile boolean jobCreationIsEnabled;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Ingest manager subscribes to service outage notifications. If key
|
* Ingest manager subscribes to service outage notifications. If key
|
||||||
* services are down, ingest manager cancels all ingest jobs in progress.
|
* 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.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.startIngestJobsThreadPool = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("IM-start-ingest-jobs-%d").build()); //NON-NLS
|
||||||
this.nextThreadId = new AtomicLong(0L);
|
this.nextThreadId = new AtomicLong(0L);
|
||||||
this.jobsById = new ConcurrentHashMap<>();
|
this.jobsById = new HashMap<>();
|
||||||
this.ingestJobStarters = new ConcurrentHashMap<>();
|
this.startIngestJobTasks = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
this.servicesMonitor = ServicesMonitor.getInstance();
|
this.servicesMonitor = ServicesMonitor.getInstance();
|
||||||
subscribeToServiceMonitorEvents();
|
subscribeToServiceMonitorEvents();
|
||||||
@ -329,7 +328,7 @@ public class IngestManager {
|
|||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
if (evt.getNewValue().equals(ServicesMonitor.ServiceStatus.DOWN.toString())) {
|
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 {
|
try {
|
||||||
if (!Case.isCaseOpen() || Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
|
if (!Case.isCaseOpen() || Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
|
||||||
return;
|
return;
|
||||||
@ -474,13 +473,13 @@ public class IngestManager {
|
|||||||
* @param dataSources The data sources to process.
|
* @param dataSources The data sources to process.
|
||||||
* @param settings The settings for the ingest job.
|
* @param settings The settings for the ingest job.
|
||||||
*/
|
*/
|
||||||
public synchronized void queueIngestJob(Collection<Content> dataSources, IngestJobSettings settings) {
|
public void queueIngestJob(Collection<Content> dataSources, IngestJobSettings settings) {
|
||||||
if (this.jobCreationIsEnabled) {
|
if (jobCreationIsEnabled) {
|
||||||
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.coreComponentsAreActive());
|
IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.coreComponentsAreActive());
|
||||||
if (job.hasIngestPipeline()) {
|
if (job.hasIngestPipeline()) {
|
||||||
long taskId = nextThreadId.incrementAndGet();
|
long taskId = nextThreadId.incrementAndGet();
|
||||||
Future<Void> task = startIngestJobsThreadPool.submit(new StartIngestJobTask(taskId, job));
|
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();
|
ingestMonitor.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
synchronized (jobsById) {
|
||||||
* Add the job to the jobs map now so that isIngestRunning() will
|
jobsById.put(job.getId(), job);
|
||||||
* 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);
|
|
||||||
List<IngestModuleError> errors = job.start();
|
List<IngestModuleError> errors = job.start();
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
this.fireIngestJobStarted(job.getId());
|
this.fireIngestJobStarted(job.getId());
|
||||||
IngestManager.logger.log(Level.INFO, "Ingest job {0} started", job.getId()); //NON-NLS
|
IngestManager.logger.log(Level.INFO, "Ingest job {0} started", job.getId()); //NON-NLS
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
this.jobsById.remove(job.getId());
|
synchronized (jobsById) {
|
||||||
|
this.jobsById.remove(job.getId());
|
||||||
|
}
|
||||||
for (IngestModuleError error : errors) {
|
for (IngestModuleError error : errors) {
|
||||||
logger.log(Level.SEVERE, String.format("Error starting %s ingest module", error.getModuleDisplayName()), error.getModuleError()); //NON-NLS
|
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) {
|
synchronized void finishIngestJob(IngestJob job) {
|
||||||
long jobId = job.getId();
|
long jobId = job.getId();
|
||||||
this.jobsById.remove(jobId);
|
synchronized (jobsById) {
|
||||||
|
jobsById.remove(jobId);
|
||||||
|
}
|
||||||
if (!job.isCancelled()) {
|
if (!job.isCancelled()) {
|
||||||
IngestManager.logger.log(Level.INFO, "Ingest job {0} completed", jobId); //NON-NLS
|
IngestManager.logger.log(Level.INFO, "Ingest job {0} completed", jobId); //NON-NLS
|
||||||
this.fireIngestJobCompleted(jobId);
|
fireIngestJobCompleted(jobId);
|
||||||
} else {
|
} else {
|
||||||
IngestManager.logger.log(Level.INFO, "Ingest job {0} cancelled", jobId); //NON-NLS
|
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.
|
* @return True or false.
|
||||||
*/
|
*/
|
||||||
public boolean isIngestRunning() {
|
public boolean isIngestRunning() {
|
||||||
return !this.jobsById.isEmpty();
|
synchronized (jobsById) {
|
||||||
|
return !jobsById.isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -625,7 +626,7 @@ public class IngestManager {
|
|||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public synchronized void cancelAllIngestJobs() {
|
public void cancelAllIngestJobs() {
|
||||||
cancelAllIngestJobs(IngestJob.CancellationReason.USER_CANCELLED);
|
cancelAllIngestJobs(IngestJob.CancellationReason.USER_CANCELLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,15 +635,21 @@ public class IngestManager {
|
|||||||
*
|
*
|
||||||
* @param reason The cancellation reason.
|
* @param reason The cancellation reason.
|
||||||
*/
|
*/
|
||||||
public synchronized void cancelAllIngestJobs(IngestJob.CancellationReason reason) {
|
public void cancelAllIngestJobs(IngestJob.CancellationReason reason) {
|
||||||
// Stop creating new ingest jobs.
|
/*
|
||||||
for (Future<Void> handle : ingestJobStarters.values()) {
|
* Cancel the start job tasks.
|
||||||
|
*/
|
||||||
|
for (Future<Void> handle : startIngestJobTasks.values()) {
|
||||||
handle.cancel(true);
|
handle.cancel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel all the jobs already created.
|
/*
|
||||||
for (IngestJob job : this.jobsById.values()) {
|
* Cancel the jobs in progress.
|
||||||
job.cancel(reason);
|
*/
|
||||||
|
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> getIngestJobSnapshots() {
|
||||||
List<DataSourceIngestJob.Snapshot> snapShots = new ArrayList<>();
|
List<DataSourceIngestJob.Snapshot> snapShots = new ArrayList<>();
|
||||||
for (IngestJob job : this.jobsById.values()) {
|
synchronized (jobsById) {
|
||||||
snapShots.addAll(job.getDataSourceIngestJobSnapshots());
|
for (IngestJob job : jobsById.values()) {
|
||||||
|
snapShots.addAll(job.getDataSourceIngestJobSnapshots());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return snapShots;
|
return snapShots;
|
||||||
}
|
}
|
||||||
@ -941,7 +950,9 @@ public class IngestManager {
|
|||||||
public Void call() {
|
public Void call() {
|
||||||
try {
|
try {
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
jobsById.remove(job.getId());
|
synchronized (jobsById) {
|
||||||
|
jobsById.remove(job.getId());
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +964,7 @@ public class IngestManager {
|
|||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progress.setDisplayName(NbBundle.getMessage(this.getClass(), "IngestManager.StartIngestJobsTask.run.cancelling", displayName));
|
progress.setDisplayName(NbBundle.getMessage(this.getClass(), "IngestManager.StartIngestJobsTask.run.cancelling", displayName));
|
||||||
}
|
}
|
||||||
Future<?> handle = ingestJobStarters.remove(threadId);
|
Future<?> handle = startIngestJobTasks.remove(threadId);
|
||||||
handle.cancel(true);
|
handle.cancel(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -968,7 +979,7 @@ public class IngestManager {
|
|||||||
if (null != progress) {
|
if (null != progress) {
|
||||||
progress.finish();
|
progress.finish();
|
||||||
}
|
}
|
||||||
ingestJobStarters.remove(threadId);
|
startIngestJobTasks.remove(threadId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-2015 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -39,11 +39,14 @@ import org.sleuthkit.datamodel.Content;
|
|||||||
import org.sleuthkit.datamodel.Directory;
|
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 {
|
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 static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text");
|
||||||
private final IngestType ingestType;
|
private final IngestType ingestType;
|
||||||
private static Dimension DIMENSIONS = new Dimension(500, 300);
|
private static Dimension DIMENSIONS = new Dimension(500, 300);
|
||||||
@ -51,13 +54,13 @@ public final class RunIngestModulesDialog extends JDialog {
|
|||||||
private IngestJobSettingsPanel ingestJobSettingsPanel;
|
private IngestJobSettingsPanel ingestJobSettingsPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a dialog box that allows a user to configure and run an ingest
|
* Constructs a dialog box that allows a user to configure and execute
|
||||||
* job on one or more data sources.
|
* analysis of one or more data sources with ingest modules.
|
||||||
*
|
*
|
||||||
* @param frame The dialog parent window.
|
* @param frame The dialog parent window.
|
||||||
* @param title The title for the dialog.
|
* @param title The title for the dialog.
|
||||||
* @param modal True if the dialog should be modal, false otherwise.
|
* @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) {
|
public RunIngestModulesDialog(JFrame frame, String title, boolean modal, List<Content> dataSources) {
|
||||||
super(frame, title, modal);
|
super(frame, title, modal);
|
||||||
@ -66,8 +69,8 @@ public final class RunIngestModulesDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a dialog box that allows a user to configure and run an ingest
|
* Constructs a dialog box that allows a user to configure and execute
|
||||||
* job on one or more data sources.
|
* analysis of one or more data sources with ingest modules.
|
||||||
*
|
*
|
||||||
* @param dataSources The data sources to be processed.
|
* @param dataSources The data sources to be processed.
|
||||||
*/
|
*/
|
||||||
@ -75,51 +78,17 @@ public final class RunIngestModulesDialog extends JDialog {
|
|||||||
this(new JFrame(TITLE), TITLE, true, 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) {
|
public RunIngestModulesDialog(Directory dir) {
|
||||||
this.dataSources.add(dir);
|
this.dataSources.add(dir);
|
||||||
this.ingestType = IngestType.FILES_ONLY;
|
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.
|
* Displays this dialog.
|
||||||
*/
|
*/
|
||||||
@ -227,4 +196,45 @@ public final class RunIngestModulesDialog extends JDialog {
|
|||||||
JOptionPane.showMessageDialog(null, warningMessage.toString());
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,26 +49,77 @@ public class UserArtifactIngestModule implements DataSourceIngestModule {
|
|||||||
FileManager manager = Case.getCurrentCase().getServices().getFileManager();
|
FileManager manager = Case.getCurrentCase().getServices().getFileManager();
|
||||||
List<AbstractFile> file1 = manager.findFiles("Sunset.jpg"); //NON-NLS
|
List<AbstractFile> file1 = manager.findFiles("Sunset.jpg"); //NON-NLS
|
||||||
List<AbstractFile> file2 = manager.findFiles("Winter.jpg"); //NON-NLS
|
List<AbstractFile> file2 = manager.findFiles("Winter.jpg"); //NON-NLS
|
||||||
BlackboardArtifact art1;
|
List<BlackboardArtifact> currArtifacts = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF);
|
||||||
|
BlackboardArtifact art1 = currArtifacts.size() == 0 ? null : currArtifacts.get(0);
|
||||||
BlackboardArtifact art2;
|
BlackboardArtifact art2;
|
||||||
if (!file1.isEmpty()) {
|
if (art1 == null) {
|
||||||
art1 = file1.get(0).newArtifact(type1.getTypeID());
|
if (!file1.isEmpty()) {
|
||||||
} else {
|
art1 = file1.get(0).newArtifact(type1.getTypeID());
|
||||||
art1 = dataSource.newArtifact(type1.getTypeID());
|
} else {
|
||||||
|
art1 = dataSource.newArtifact(type1.getTypeID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!file2.isEmpty()) {
|
if (!file2.isEmpty()) {
|
||||||
art2 = file2.get(0).newArtifact(type2.getTypeID());
|
art2 = file2.get(0).newArtifact(type2.getTypeID());
|
||||||
} else {
|
} else {
|
||||||
art2 = dataSource.newArtifact(type2.getTypeID());
|
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 attributeType = Case.getCurrentCase().getSleuthkitCase().getAttributeType("Test8");
|
||||||
BlackboardAttribute.Type attributeType2 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("Test2", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE, "3"); //NON-NLS
|
if (attributeType == null) {
|
||||||
|
attributeType = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("Test8", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG, "Header6");
|
||||||
|
}
|
||||||
|
BlackboardAttribute.Type attributeType2 = Case.getCurrentCase().getSleuthkitCase().getAttributeType("Test9");
|
||||||
|
if (attributeType2 == null) {
|
||||||
|
attributeType2 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("Test9", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME, "Header7");
|
||||||
|
|
||||||
|
}
|
||||||
|
BlackboardAttribute.Type attributeType3 = Case.getCurrentCase().getSleuthkitCase().getAttributeType("Test0");
|
||||||
|
if (attributeType3 == null) {
|
||||||
|
attributeType3 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("Test0", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING, "Header8");
|
||||||
|
|
||||||
|
}
|
||||||
|
BlackboardAttribute.Type attributeType4 = Case.getCurrentCase().getSleuthkitCase().getAttributeType("TestA");
|
||||||
|
if (attributeType4 == null) {
|
||||||
|
attributeType4 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("TestA", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER, "Header9");
|
||||||
|
|
||||||
|
}
|
||||||
|
BlackboardAttribute.Type attributeType5 = Case.getCurrentCase().getSleuthkitCase().getAttributeType("TestB");
|
||||||
|
if (attributeType5 == null) {
|
||||||
|
attributeType5 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("TestB", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE, "Header0");
|
||||||
|
|
||||||
|
}
|
||||||
|
BlackboardAttribute.Type attributeType6 = Case.getCurrentCase().getSleuthkitCase().getAttributeType("TestC");
|
||||||
|
if (attributeType6 == null) {
|
||||||
|
attributeType6 = Case.getCurrentCase().getServices().getBlackboard().addAttributeType("TestC", TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE, "HeaderA");
|
||||||
|
|
||||||
|
}
|
||||||
art1.addAttribute(new BlackboardAttribute(attributeType,
|
art1.addAttribute(new BlackboardAttribute(attributeType,
|
||||||
UserArtifactIngestModuleFactory.getModuleName(), -1L));
|
UserArtifactIngestModuleFactory.getModuleName(), 12345678L));
|
||||||
progressBar.progress(1);
|
art1.addAttribute(new BlackboardAttribute(attributeType2,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), 1457105587962L));
|
||||||
|
art1.addAttribute(new BlackboardAttribute(attributeType3,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), "STRING VALUE TEST"));
|
||||||
|
art1.addAttribute(new BlackboardAttribute(attributeType4,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), 1234));
|
||||||
|
art1.addAttribute(new BlackboardAttribute(attributeType5,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), 1234.5678D));
|
||||||
|
byte[] bytes = new byte[2];
|
||||||
|
bytes[0] = 12;
|
||||||
|
bytes[1] = 100;
|
||||||
|
art1.addAttribute(new BlackboardAttribute(attributeType6,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), bytes));
|
||||||
art2.addAttribute(new BlackboardAttribute(attributeType2,
|
art2.addAttribute(new BlackboardAttribute(attributeType2,
|
||||||
UserArtifactIngestModuleFactory.getModuleName(), new byte[7]));
|
UserArtifactIngestModuleFactory.getModuleName(), 1457105587962L));
|
||||||
progressBar.progress(1);
|
art2.addAttribute(new BlackboardAttribute(attributeType,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), 12345678L));
|
||||||
|
art2.addAttribute(new BlackboardAttribute(attributeType3,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), "STRING VALUE TEST"));
|
||||||
|
art2.addAttribute(new BlackboardAttribute(attributeType4,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), 1234));
|
||||||
|
art2.addAttribute(new BlackboardAttribute(attributeType5,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), 1234.5678D));
|
||||||
|
art2.addAttribute(new BlackboardAttribute(attributeType6,
|
||||||
|
UserArtifactIngestModuleFactory.getModuleName(), bytes));
|
||||||
IngestServices.getInstance().postMessage(IngestMessage.createDataMessage(
|
IngestServices.getInstance().postMessage(IngestMessage.createDataMessage(
|
||||||
"name", // NON-NLS
|
"name", // NON-NLS
|
||||||
UserArtifactIngestModuleFactory.getModuleName(),
|
UserArtifactIngestModuleFactory.getModuleName(),
|
||||||
@ -84,9 +135,15 @@ public class UserArtifactIngestModule implements DataSourceIngestModule {
|
|||||||
@Override
|
@Override
|
||||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
try {
|
try {
|
||||||
type1 = Case.getCurrentCase().getServices().getBlackboard().addArtifactType("This is", "a test"); //NON-NLS
|
type1 = Case.getCurrentCase().getSleuthkitCase().getArtifactType("FINAL TEST a");
|
||||||
type2 = Case.getCurrentCase().getServices().getBlackboard().addArtifactType("Another", "kinda test"); //NON-NLS
|
type2 = Case.getCurrentCase().getSleuthkitCase().getArtifactType("FINAL TEST b");
|
||||||
} catch (BlackboardException ex) {
|
if (type1 == null) {
|
||||||
|
type1 = Case.getCurrentCase().getServices().getBlackboard().addArtifactType("FINAL TEST a", "FINAL TEST a"); //NON-NLS
|
||||||
|
}
|
||||||
|
if (type2 == null) {
|
||||||
|
type2 = Case.getCurrentCase().getServices().getBlackboard().addArtifactType("FINAL TEST b", "FINAL TEST b"); //NON-NLS
|
||||||
|
}
|
||||||
|
} catch (BlackboardException | TskCoreException ex) {
|
||||||
Logger.logMsg(Logger.ERROR, "Startup failed"); //NON-NLS
|
Logger.logMsg(Logger.ERROR, "Startup failed"); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,15 +19,17 @@
|
|||||||
package org.sleuthkit.autopsy.modules.UserArtifacts;
|
package org.sleuthkit.autopsy.modules.UserArtifacts;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.python.apache.xmlcommons.Version;
|
import org.python.apache.xmlcommons.Version;
|
||||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for test module that creates new artifact and attribute types.
|
* Factory for test module that creates new artifact and attribute types.
|
||||||
*/
|
*/
|
||||||
//@ServiceProvider(service = IngestModuleFactory.class)
|
@ServiceProvider(service = IngestModuleFactory.class)
|
||||||
public class UserArtifactIngestModuleFactory extends IngestModuleFactoryAdapter {
|
public class UserArtifactIngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||||
|
|
||||||
static String getModuleName() {
|
static String getModuleName() {
|
||||||
|
@ -79,7 +79,7 @@ public final class EmbeddedFileExtractorIngestModule implements FileIngestModule
|
|||||||
} catch (SecurityException ex) {
|
} catch (SecurityException ex) {
|
||||||
logger.log(Level.SEVERE, "Error initializing output dir: " + moduleDirAbsolute, ex); //NON-NLS
|
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
|
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 {
|
try {
|
||||||
fileTypeDetector = new FileTypeDetector();
|
fileTypeDetector = new FileTypeDetector();
|
||||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||||
throw new IngestModuleException(ex.getMessage());
|
throw new IngestModuleException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize the extraction modules.
|
// initialize the extraction modules.
|
||||||
|
@ -133,7 +133,7 @@ class SevenZipExtractor {
|
|||||||
String details = NbBundle.getMessage(SevenZipExtractor.class, "EmbeddedFileExtractorIngestModule.ArchiveExtractor.init.errCantInitLib",
|
String details = NbBundle.getMessage(SevenZipExtractor.class, "EmbeddedFileExtractorIngestModule.ArchiveExtractor.init.errCantInitLib",
|
||||||
e.getMessage());
|
e.getMessage());
|
||||||
services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
|
services.postMessage(IngestMessage.createErrorMessage(EmbeddedFileExtractorModuleFactory.getModuleName(), msg, details));
|
||||||
throw new IngestModuleException(e.getMessage());
|
throw new IngestModuleException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -91,7 +91,7 @@ public final class ExifParserFileIngestModule implements FileIngestModule {
|
|||||||
try {
|
try {
|
||||||
fileTypeDetector = new FileTypeDetector();
|
fileTypeDetector = new FileTypeDetector();
|
||||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,13 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.modules.fileextmismatch;
|
package org.sleuthkit.autopsy.modules.fileextmismatch;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.openide.util.Exceptions;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
|
||||||
@ -40,7 +38,6 @@ import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
|
|||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
@ -58,6 +55,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
|||||||
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
|
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
|
||||||
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
||||||
private static Blackboard blackboard;
|
private static Blackboard blackboard;
|
||||||
|
private FileTypeDetector detector;
|
||||||
|
|
||||||
private static class IngestJobTotals {
|
private static class IngestJobTotals {
|
||||||
|
|
||||||
@ -94,6 +92,11 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
|||||||
|
|
||||||
FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault();
|
FileExtMismatchXML xmlLoader = FileExtMismatchXML.getDefault();
|
||||||
SigTypeToExtMap = xmlLoader.load();
|
SigTypeToExtMap = xmlLoader.load();
|
||||||
|
try {
|
||||||
|
this.detector = new FileTypeDetector();
|
||||||
|
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
||||||
|
throw new IngestModuleException("Could not create file type detector.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +160,7 @@ public class FileExtMismatchIngestModule implements FileIngestModule {
|
|||||||
if (settings.skipFilesWithNoExtension() && currActualExt.isEmpty()) {
|
if (settings.skipFilesWithNoExtension() && currActualExt.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String currActualSigType = abstractFile.getMIMEType();
|
String currActualSigType = detector.getFileType(abstractFile);
|
||||||
if (currActualSigType == null) {
|
if (currActualSigType == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,10 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
|||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
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 {
|
public class FileTypeDetector {
|
||||||
|
|
||||||
@ -49,11 +49,14 @@ public class FileTypeDetector {
|
|||||||
private static final Logger logger = Logger.getLogger(FileTypeDetector.class.getName());
|
private static final Logger logger = Logger.getLogger(FileTypeDetector.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an object that detects the type of a file by an inspection of
|
* Constructs an object that detects the MIME type of a file by an
|
||||||
* its contents.
|
* inspection of its contents, using both user-defined type definitions and
|
||||||
|
* Tika.
|
||||||
*
|
*
|
||||||
* @throws FileTypeDetector.FileTypeDetectorInitException if an
|
* @throws FileTypeDetectorInitException if an initialization error occurs,
|
||||||
* initialization error occurs.
|
* e.g., user-defined file type
|
||||||
|
* definitions exist but cannot be
|
||||||
|
* loaded.
|
||||||
*/
|
*/
|
||||||
public FileTypeDetector() throws FileTypeDetectorInitException {
|
public FileTypeDetector() throws FileTypeDetectorInitException {
|
||||||
try {
|
try {
|
||||||
@ -64,12 +67,26 @@ public class FileTypeDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether or not a given MIME type is detectable by this
|
* Gets the names of the user-defined MIME types.
|
||||||
* detector.
|
|
||||||
*
|
*
|
||||||
* @param mimeType The MIME type name, e.g. "text/html", to look up.
|
* @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.
|
||||||
*
|
*
|
||||||
* @return True if MIME type is detectable.
|
* @param mimeType The MIME type name (e.g., "text/html").
|
||||||
|
*
|
||||||
|
* @return True if the given MIME type is detectable.
|
||||||
*/
|
*/
|
||||||
public boolean isDetectable(String mimeType) {
|
public boolean isDetectable(String mimeType) {
|
||||||
return isDetectableAsUserDefinedType(mimeType) || isDetectableByTika(mimeType);
|
return isDetectableAsUserDefinedType(mimeType) || isDetectableByTika(mimeType);
|
||||||
@ -77,11 +94,11 @@ public class FileTypeDetector {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether or not a given MIME type is detectable as a
|
* Determines whether or not a given MIME type is detectable as a
|
||||||
* user-defined file type.
|
* user-defined MIME type.
|
||||||
*
|
*
|
||||||
* @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 if the given MIME type is detectable.
|
||||||
*/
|
*/
|
||||||
private boolean isDetectableAsUserDefinedType(String mimeType) {
|
private boolean isDetectableAsUserDefinedType(String mimeType) {
|
||||||
for (FileType fileType : userDefinedFileTypes) {
|
for (FileType fileType : userDefinedFileTypes) {
|
||||||
@ -95,9 +112,9 @@ public class FileTypeDetector {
|
|||||||
/**
|
/**
|
||||||
* Determines whether or not a given MIME type is detectable by Tika.
|
* 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 if the given MIME type is detectable.
|
||||||
*/
|
*/
|
||||||
private boolean isDetectableByTika(String mimeType) {
|
private boolean isDetectableByTika(String mimeType) {
|
||||||
String[] split = mimeType.split("/");
|
String[] split = mimeType.split("/");
|
||||||
@ -112,59 +129,42 @@ public class FileTypeDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up the MIME type of a file using the blackboard. If it is not
|
* Gets the MIME type of a file, detecting it if it is not already known. If
|
||||||
* already posted, detect the type of the file, posting it to the blackboard
|
* detection is necessary, the result is added to the case database.
|
||||||
* if detection succeeds.
|
|
||||||
*
|
*
|
||||||
* @param file The file to test.
|
* @param file The file.
|
||||||
*
|
*
|
||||||
* @return The MIME type name if detection was successful, null otherwise.
|
* @return A MIME type name.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException if detection is required and there is a problem
|
||||||
*/
|
* writing the result to the case database.
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @param file The file to test.
|
|
||||||
*
|
|
||||||
* @return The MIME type name id detection was successful, null otherwise.
|
|
||||||
*
|
|
||||||
* @throws TskCoreException
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public String detectAndPostToBlackboard(AbstractFile file) throws TskCoreException {
|
public String getFileType(AbstractFile file) throws TskCoreException {
|
||||||
String mimeType = detect(file);
|
String mimeType = file.getMIMEType();
|
||||||
if (null != mimeType) {
|
if (null != mimeType) {
|
||||||
/**
|
return 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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
BlackboardArtifact getInfoArt = file.getGenInfoArtifact();
|
||||||
|
BlackboardAttribute batt = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG, FileTypeIdModuleFactory.getModuleName(), mimeType);
|
||||||
|
getInfoArt.addAttribute(batt);
|
||||||
|
|
||||||
return mimeType;
|
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.
|
* @param file The file to test.
|
||||||
*
|
*
|
||||||
@ -173,9 +173,12 @@ public class FileTypeDetector {
|
|||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
public String detect(AbstractFile file) 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)
|
* Consistently mark non-regular files (refer to
|
||||||
// as octet-stream.
|
* 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
|
if (!file.isFile() || file.getSize() <= 0
|
||||||
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|
||||||
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|
|| (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|
||||||
@ -183,8 +186,8 @@ public class FileTypeDetector {
|
|||||||
return MimeTypes.OCTET_STREAM;
|
return MimeTypes.OCTET_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileType = detectUserDefinedType(file);
|
String mimeType = detectUserDefinedType(file);
|
||||||
if (null == fileType) {
|
if (null == mimeType) {
|
||||||
try {
|
try {
|
||||||
byte buf[];
|
byte buf[];
|
||||||
int len = file.read(buffer, 0, BUFFER_SIZE);
|
int len = file.read(buffer, 0, BUFFER_SIZE);
|
||||||
@ -195,23 +198,25 @@ public class FileTypeDetector {
|
|||||||
buf = buffer;
|
buf = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
String mimetype = tika.detect(buf, file.getName());
|
String tikaType = tika.detect(buf, file.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip out any Tika enhancements to the MIME type name.
|
* Strip out any Tika enhancements to the MIME type name.
|
||||||
*/
|
*/
|
||||||
return mimetype.replace("tika-", ""); //NON-NLS
|
mimeType = tikaType.replace("tika-", ""); //NON-NLS
|
||||||
|
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
/**
|
/*
|
||||||
* This exception is swallowed rather than propagated because
|
* This exception is swallowed and not logged rather than
|
||||||
* files in images are not always consistent with their file
|
* propagated because files in data sources are not always
|
||||||
* system meta data making for read errors, and Tika can be a
|
* consistent with their file system metadata, making for read
|
||||||
* bit flaky at times, making this a best effort endeavor.
|
* errors, and 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,7 +240,7 @@ public class FileTypeDetector {
|
|||||||
BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, FileTypeIdModuleFactory.getModuleName(), fileType.getFilesSetName());
|
BlackboardAttribute setNameAttribute = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, FileTypeIdModuleFactory.getModuleName(), fileType.getFilesSetName());
|
||||||
artifact.addAttribute(setNameAttribute);
|
artifact.addAttribute(setNameAttribute);
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Use the MIME type as the category, i.e., the rule that
|
* Use the MIME type as the category, i.e., the rule that
|
||||||
* determined this file belongs to the interesting files
|
* determined this file belongs to the interesting files
|
||||||
* set.
|
* set.
|
||||||
@ -259,6 +264,7 @@ public class FileTypeDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class FileTypeDetectorInitException extends Exception {
|
public static class FileTypeDetectorInitException extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
FileTypeDetectorInitException(String message) {
|
FileTypeDetectorInitException(String message) {
|
||||||
@ -271,17 +277,22 @@ public class FileTypeDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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() {
|
@Deprecated
|
||||||
List<String> list = new ArrayList<>();
|
@SuppressWarnings("deprecation")
|
||||||
if (userDefinedFileTypes != null) {
|
public String detectAndPostToBlackboard(AbstractFile file) throws TskCoreException {
|
||||||
for (FileType fileType : userDefinedFileTypes) {
|
return getFileType(file);
|
||||||
list.add(fileType.getMimeType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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, "{key}")"/>
|
|
||||||
</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, "{key}")"/>
|
|
||||||
</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.IngestMessage;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.TskData.FileKnown;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
|
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||||
|
|
||||||
@ -38,7 +37,6 @@ import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
|||||||
public class FileTypeIdIngestModule implements FileIngestModule {
|
public class FileTypeIdIngestModule implements FileIngestModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(FileTypeIdIngestModule.class.getName());
|
private static final Logger logger = Logger.getLogger(FileTypeIdIngestModule.class.getName());
|
||||||
private final FileTypeIdModuleSettings settings;
|
|
||||||
private long jobId;
|
private long jobId;
|
||||||
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
|
private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
|
||||||
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
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
|
* Creates an ingest module that detects the type of a file based on
|
||||||
* signature (magic) values. Posts results to the blackboard.
|
* signature (magic) values. Posts results to the blackboard.
|
||||||
*
|
|
||||||
* @param settings The ingest module settings.
|
|
||||||
*/
|
*/
|
||||||
FileTypeIdIngestModule(FileTypeIdModuleSettings settings) {
|
FileTypeIdIngestModule() {
|
||||||
this.settings = settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,7 +78,7 @@ public class FileTypeIdIngestModule implements FileIngestModule {
|
|||||||
try {
|
try {
|
||||||
fileTypeDetector = new FileTypeDetector();
|
fileTypeDetector = new FileTypeDetector();
|
||||||
} catch (FileTypeDetector.FileTypeDetectorInitException ex) {
|
} 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
|
@Override
|
||||||
public ProcessResult process(AbstractFile file) {
|
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,
|
* Attempt to detect the file type. Do it within an exception firewall,
|
||||||
* so that any issues with reading file content or complaints from tika
|
* 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
|
* Update the match time total and increment number of files processed for
|
||||||
* this ingest job.
|
* this ingest job.
|
||||||
*
|
*
|
||||||
* @param jobId The ingest job identifier.
|
* @param jobId The ingest job identifier.
|
||||||
* @param matchTimeInc Amount of time to add.
|
* @param matchTimeInc Amount of time to add.
|
||||||
*/
|
*/
|
||||||
private static synchronized void addToTotals(long jobId, long matchTimeInc) {
|
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.IngestModuleFactoryAdapter;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
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.
|
* A factory that creates file ingest modules that determine the types of files.
|
||||||
@ -92,35 +91,6 @@ public class FileTypeIdModuleFactory extends IngestModuleFactoryAdapter {
|
|||||||
return globalSettingsPanel;
|
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
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@ -134,11 +104,6 @@ public class FileTypeIdModuleFactory extends IngestModuleFactoryAdapter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
assert settings instanceof FileTypeIdModuleSettings;
|
return new FileTypeIdIngestModule();
|
||||||
if (!(settings instanceof FileTypeIdModuleSettings)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
NbBundle.getMessage(this.getClass(), "FileTypeIdModuleFactory.createFileIngestModule.exception.msg"));
|
|
||||||
}
|
|
||||||
return new FileTypeIdIngestModule((FileTypeIdModuleSettings) settings);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -59,7 +59,6 @@ import org.xml.sax.SAXException;
|
|||||||
final class UserDefinedFileTypesManager {
|
final class UserDefinedFileTypesManager {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(UserDefinedFileTypesManager.class.getName());
|
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 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_TYPES_TAG_NAME = "FileTypes"; //NON-NLS
|
||||||
private static final String FILE_TYPE_TAG_NAME = "FileType"; //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 INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS
|
||||||
private static final String ALERT_ATTRIBUTE = "alert"; //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 ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS
|
||||||
private static final String ASCII_ENCODING = "US-ASCII"; //NON-NLS
|
|
||||||
private static UserDefinedFileTypesManager instance;
|
private static UserDefinedFileTypesManager instance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,8 +231,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS
|
byteArray = DatatypeConverter.parseHexBinary("54525545564953494F4E2D5846494C452E00"); //NON-NLS
|
||||||
fileType = new FileType("image/x-tga", new Signature(byteArray, 17, false), "", false); //NON-NLS
|
fileType = new FileType("image/x-tga", new Signature(byteArray, 17, false), "", false); //NON-NLS
|
||||||
fileTypes.add(fileType);
|
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) {
|
catch (IllegalArgumentException e) {
|
||||||
throw new UserDefinedFileTypesException("Error creating predefined file types", e); //
|
throw new UserDefinedFileTypesException("Error creating predefined file types", e); //
|
||||||
}
|
}
|
||||||
@ -282,7 +279,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
* Sets the user-defined file types.
|
* Sets the user-defined file types.
|
||||||
*
|
*
|
||||||
* @param newFileTypes A mapping of file type names to user-defined file
|
* @param newFileTypes A mapping of file type names to user-defined file
|
||||||
* types.
|
* types.
|
||||||
*/
|
*/
|
||||||
synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
|
synchronized void setUserDefinedFileTypes(List<FileType> newFileTypes) throws UserDefinedFileTypesException {
|
||||||
try {
|
try {
|
||||||
@ -317,7 +314,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
* Writes a set of file type definitions to an XML file.
|
* Writes a set of file type definitions to an XML file.
|
||||||
*
|
*
|
||||||
* @param fileTypes A collection of file types.
|
* @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 ParserConfigurationException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@ -340,7 +337,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
* Creates an XML representation of a file type.
|
* Creates an XML representation of a file type.
|
||||||
*
|
*
|
||||||
* @param fileType The file type object.
|
* @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.
|
* @return An XML element.
|
||||||
*/
|
*/
|
||||||
@ -356,9 +353,9 @@ final class UserDefinedFileTypesManager {
|
|||||||
/**
|
/**
|
||||||
* Add a MIME type child element to a file type XML element.
|
* 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 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) {
|
private static void addMimeTypeElement(FileType fileType, Element fileTypeElem, Document doc) {
|
||||||
Element typeNameElem = doc.createElement(MIME_TYPE_TAG_NAME);
|
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.
|
* 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 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) {
|
private static void addSignatureElement(FileType fileType, Element fileTypeElem, Document doc) {
|
||||||
Signature signature = fileType.getSignature();
|
Signature signature = fileType.getSignature();
|
||||||
@ -393,9 +390,9 @@ final class UserDefinedFileTypesManager {
|
|||||||
/**
|
/**
|
||||||
* Add an interesting files set element to a file type XML element.
|
* 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 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) {
|
private static void addInterestingFilesSetElement(FileType fileType, Element fileTypeElem, Document doc) {
|
||||||
if (!fileType.getFilesSetName().isEmpty()) {
|
if (!fileType.getFilesSetName().isEmpty()) {
|
||||||
@ -408,13 +405,20 @@ final class UserDefinedFileTypesManager {
|
|||||||
/**
|
/**
|
||||||
* Add an alert attribute to a file type XML element.
|
* 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.
|
* @param fileTypeElem The parent file type element.
|
||||||
*/
|
*/
|
||||||
private static void addAlertAttribute(FileType fileType, Element fileTypeElem) {
|
private static void addAlertAttribute(FileType fileType, Element fileTypeElem) {
|
||||||
fileTypeElem.setAttribute(ALERT_ATTRIBUTE, Boolean.toString(fileType.alertOnMatch()));
|
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 {
|
private static List<FileType> readFileTypes(String filePath) throws IOException, ParserConfigurationException, SAXException {
|
||||||
List<FileType> fileTypes = new ArrayList<>();
|
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) {
|
if (doc != null) {
|
||||||
Element fileTypesElem = doc.getDocumentElement();
|
Element fileTypesElem = doc.getDocumentElement();
|
||||||
if (fileTypesElem != null && fileTypesElem.getNodeName().equals(FILE_TYPES_TAG_NAME)) {
|
if (fileTypesElem != null && fileTypesElem.getNodeName().equals(FILE_TYPES_TAG_NAME)) {
|
||||||
@ -497,13 +511,15 @@ final class UserDefinedFileTypesManager {
|
|||||||
String offsetString = offsetElem.getTextContent();
|
String offsetString = offsetElem.getTextContent();
|
||||||
long offset = DatatypeConverter.parseLong(offsetString);
|
long offset = DatatypeConverter.parseLong(offsetString);
|
||||||
|
|
||||||
|
boolean isRelativeToStart;
|
||||||
String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
|
String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
|
||||||
if(relativeString == null || relativeString.equals(""))
|
if (null == relativeString || relativeString.equals("")) {
|
||||||
return new Signature(signatureBytes, offset, signatureType);
|
isRelativeToStart = true;
|
||||||
|
} else {
|
||||||
|
isRelativeToStart = DatatypeConverter.parseBoolean(relativeString);
|
||||||
|
}
|
||||||
|
|
||||||
boolean isRelative = DatatypeConverter.parseBoolean(relativeString);
|
return new Signature(signatureBytes, offset, signatureType, isRelativeToStart);
|
||||||
|
|
||||||
return new Signature(signatureBytes, offset, signatureType, isRelative);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -538,7 +554,7 @@ final class UserDefinedFileTypesManager {
|
|||||||
/**
|
/**
|
||||||
* Gets the text content of a single child element.
|
* 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.
|
* @param tagName The tag name of the child element.
|
||||||
*
|
*
|
||||||
* @return The text content or null if the tag doesn't exist.
|
* @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) {
|
private static String getChildElementTextContent(Element elem, String tagName) {
|
||||||
NodeList childElems = elem.getElementsByTagName(tagName);
|
NodeList childElems = elem.getElementsByTagName(tagName);
|
||||||
Node childNode = childElems.item(0);
|
Node childNode = childElems.item(0);
|
||||||
if(childNode == null)
|
if (childNode == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
Element childElem = (Element) childNode;
|
Element childElem = (Element) childNode;
|
||||||
return childElem.getTextContent();
|
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
|
* Logs an exception, bundles the exception with a simple message in a
|
||||||
* uniform exception type, and throws the wrapper exception.
|
* 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
|
* @param messageKey A key into the bundle file that maps to the desired
|
||||||
* message.
|
* message.
|
||||||
*
|
*
|
||||||
* @throws
|
* @throws
|
||||||
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
* org.sleuthkit.autopsy.modules.filetypeid.UserDefinedFileTypesManager.UserDefinedFileTypesException
|
||||||
@ -578,6 +602,8 @@ final class UserDefinedFileTypesManager {
|
|||||||
*/
|
*/
|
||||||
static class UserDefinedFileTypesException extends Exception {
|
static class UserDefinedFileTypesException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
UserDefinedFileTypesException(String message) {
|
UserDefinedFileTypesException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ final class PhotoRecCarverFileIngestModule implements FileIngestModule {
|
|||||||
// Initialize job totals
|
// Initialize job totals
|
||||||
initTotalsForIngestJob(jobId);
|
initTotalsForIngestJob(jobId);
|
||||||
} catch (SecurityException | IOException | UnsupportedOperationException ex) {
|
} 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) {
|
} catch (FileAlreadyExistsException ex) {
|
||||||
// No worries.
|
// No worries.
|
||||||
} catch (IOException | SecurityException | UnsupportedOperationException ex) {
|
} 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;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -115,15 +115,15 @@ class EvalAccountObj extends EvaluatableObject {
|
|||||||
boolean foundSIDMatch = false;
|
boolean foundSIDMatch = false;
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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)) {
|
&& (haveHomeDir)) {
|
||||||
foundHomeDirMatch = compareStringObject(userAccountObj.getHomeDirectory(), attr.getValueString());
|
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)) {
|
&& (haveUsername)) {
|
||||||
foundUsernameMatch = compareStringObject(userAccountObj.getUsername(), attr.getValueString());
|
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)) {
|
&& (haveSID) && (winUserObj != null)) {
|
||||||
foundSIDMatch = compareStringObject(winUserObj.getSecurityID(), attr.getValueString());
|
foundSIDMatch = compareStringObject(winUserObj.getSecurityID(), attr.getValueString());
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ class EvalAddressObj extends EvaluatableObject {
|
|||||||
for (BlackboardArtifact art : artList) {
|
for (BlackboardArtifact art : artList) {
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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(),
|
if (compareStringObject(addressStr, obj.getAddressValue().getCondition(),
|
||||||
obj.getAddressValue().getApplyCondition(), attr.getValueString())) {
|
obj.getAddressValue().getApplyCondition(), attr.getValueString())) {
|
||||||
finalHits.add(art);
|
finalHits.add(art);
|
||||||
|
@ -80,7 +80,7 @@ class EvalDomainObj extends EvaluatableObject {
|
|||||||
for (BlackboardArtifact art : artList) {
|
for (BlackboardArtifact art : artList) {
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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();
|
String url = attr.getValueString();
|
||||||
|
|
||||||
// Check whether the domain name is a substring of the URL (regardless
|
// Check whether the domain name is a substring of the URL (regardless
|
||||||
|
@ -98,11 +98,11 @@ class EvalNetworkShareObj extends EvaluatableObject {
|
|||||||
boolean foundLocalPathMatch = false;
|
boolean foundLocalPathMatch = false;
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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)) {
|
&& (obj.getNetname() != null)) {
|
||||||
foundRemotePathMatch = compareStringObject(obj.getNetname(), attr.getValueString());
|
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)) {
|
&& (obj.getLocalPath() != null)) {
|
||||||
foundLocalPathMatch = compareStringObject(obj.getLocalPath(), attr.getValueString());
|
foundLocalPathMatch = compareStringObject(obj.getLocalPath(), attr.getValueString());
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ class EvalURIObj extends EvaluatableObject {
|
|||||||
for (BlackboardArtifact art : artList) {
|
for (BlackboardArtifact art : artList) {
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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();
|
String modifiedAttrString = attr.getValueString();
|
||||||
if (modifiedAttrString != null) {
|
if (modifiedAttrString != null) {
|
||||||
|
@ -152,7 +152,7 @@ class EvalURLHistoryObj extends EvaluatableObject {
|
|||||||
boolean foundBrowserNameMatch = false;
|
boolean foundBrowserNameMatch = false;
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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)) {
|
&& (haveURL)) {
|
||||||
if (entry.getURL().getValue() instanceof AnyURIObjectPropertyType) {
|
if (entry.getURL().getValue() instanceof AnyURIObjectPropertyType) {
|
||||||
foundURLMatch = compareStringObject(entry.getURL().getValue().getValue().toString(),
|
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
|
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)) {
|
&& (haveHostname)) {
|
||||||
foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
|
foundHostnameMatch = compareStringObject(entry.getHostname().getHostnameValue(),
|
||||||
attr.getValueString());
|
attr.getValueString());
|
||||||
}
|
}
|
||||||
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
|
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID())
|
||||||
&& (haveReferrer)) {
|
&& (haveReferrer)) {
|
||||||
if (entry.getReferrerURL().getValue() instanceof AnyURIObjectPropertyType) {
|
if (entry.getReferrerURL().getValue() instanceof AnyURIObjectPropertyType) {
|
||||||
foundReferrerMatch = compareStringObject(entry.getReferrerURL().getValue().getValue().toString(),
|
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
|
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)) {
|
&& (havePageTitle)) {
|
||||||
foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
|
foundPageTitleMatch = compareStringObject(entry.getPageTitle(),
|
||||||
attr.getValueString());
|
attr.getValueString());
|
||||||
}
|
}
|
||||||
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
|
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME.getTypeID())
|
||||||
&& (haveUserProfile)) {
|
&& (haveUserProfile)) {
|
||||||
foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
|
foundUserProfileMatch = compareStringObject(entry.getUserProfileName(),
|
||||||
attr.getValueString());
|
attr.getValueString());
|
||||||
}
|
}
|
||||||
if ((attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
|
if ((attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID())
|
||||||
&& (haveBrowserName)) {
|
&& (haveBrowserName)) {
|
||||||
foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
|
foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
|
||||||
null, null, attr.getValueString());
|
null, null, attr.getValueString());
|
||||||
@ -240,7 +240,7 @@ class EvalURLHistoryObj extends EvaluatableObject {
|
|||||||
boolean foundBrowserNameMatch = false;
|
boolean foundBrowserNameMatch = false;
|
||||||
|
|
||||||
for (BlackboardAttribute attr : art.getAttributes()) {
|
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)) {
|
&& (haveBrowserName)) {
|
||||||
foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
|
foundBrowserNameMatch = compareStringObject(obj.getBrowserInformation().getName(),
|
||||||
null, null, attr.getValueString());
|
null, null, attr.getValueString());
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JList<>()"/>
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JList<>()"/>
|
||||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<ARTIFACT_TYPE>"/>
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<BlackboardArtifact.Type>"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
|
@ -27,6 +27,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -40,15 +41,14 @@ import org.openide.util.NbBundle;
|
|||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
public class ArtifactSelectionDialog extends javax.swing.JDialog {
|
public class ArtifactSelectionDialog extends javax.swing.JDialog {
|
||||||
|
|
||||||
private ArtifactModel model;
|
private ArtifactModel model;
|
||||||
private ArtifactRenderer renderer;
|
private ArtifactRenderer renderer;
|
||||||
private Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> artifactStates;
|
private Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections;
|
||||||
private List<BlackboardArtifact.ARTIFACT_TYPE> artifacts;
|
private List<BlackboardArtifact.Type> artifactTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form ArtifactSelectionDialog
|
* 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")
|
@SuppressWarnings("deprecation")
|
||||||
private void populateList() {
|
private void populateList() {
|
||||||
try {
|
try {
|
||||||
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> doNotReport = new ArrayList<>();
|
ArrayList<BlackboardArtifact.Type> doNotReport = new ArrayList<>();
|
||||||
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO);
|
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
|
||||||
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT); // output is too unstructured for table review.
|
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();
|
artifactTypes = Case.getCurrentCase().getSleuthkitCase().getArtifactTypesInUse();
|
||||||
artifacts.removeAll(doNotReport);
|
artifactTypes.removeAll(doNotReport);
|
||||||
Collections.sort(artifacts, new Comparator<BlackboardArtifact.ARTIFACT_TYPE>() {
|
Collections.sort(artifactTypes, new Comparator<BlackboardArtifact.Type>() {
|
||||||
@Override
|
@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());
|
return o1.getDisplayName().compareTo(o2.getDisplayName());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
artifactStates = new EnumMap<>(BlackboardArtifact.ARTIFACT_TYPE.class);
|
artifactTypeSelections = new HashMap<>();
|
||||||
for (BlackboardArtifact.ARTIFACT_TYPE type : artifacts) {
|
for (BlackboardArtifact.Type type : artifactTypes) {
|
||||||
artifactStates.put(type, Boolean.TRUE);
|
artifactTypeSelections.put(type, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getLogger(ArtifactSelectionDialog.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS
|
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
|
@Override
|
||||||
public void mousePressed(MouseEvent evt) {
|
public void mousePressed(MouseEvent evt) {
|
||||||
int index = artifactList.locationToIndex(evt.getPoint());
|
int index = artifactList.locationToIndex(evt.getPoint());
|
||||||
BlackboardArtifact.ARTIFACT_TYPE type = model.getElementAt(index);
|
BlackboardArtifact.Type type = model.getElementAt(index);
|
||||||
artifactStates.put(type, !artifactStates.get(type));
|
artifactTypeSelections.put(type, !artifactTypeSelections.get(type));
|
||||||
artifactList.repaint();
|
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"));
|
this.setTitle(NbBundle.getMessage(this.getClass(), "ArtifactSelectionDialog.dlgTitle.text"));
|
||||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
// set the popUp window / JFrame
|
// 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);
|
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
|
||||||
|
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
return artifactStates;
|
return artifactTypeSelections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,20 +221,20 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
|
|||||||
}//GEN-LAST:event_okButtonActionPerformed
|
}//GEN-LAST:event_okButtonActionPerformed
|
||||||
|
|
||||||
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
|
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
|
||||||
for (ARTIFACT_TYPE type : artifacts) {
|
for (BlackboardArtifact.Type type : artifactTypes) {
|
||||||
artifactStates.put(type, Boolean.TRUE);
|
artifactTypeSelections.put(type, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
artifactList.repaint();
|
artifactList.repaint();
|
||||||
}//GEN-LAST:event_selectAllButtonActionPerformed
|
}//GEN-LAST:event_selectAllButtonActionPerformed
|
||||||
|
|
||||||
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
|
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
|
||||||
for (ARTIFACT_TYPE type : artifacts) {
|
for (BlackboardArtifact.Type type : artifactTypes) {
|
||||||
artifactStates.put(type, Boolean.FALSE);
|
artifactTypeSelections.put(type, Boolean.FALSE);
|
||||||
}
|
}
|
||||||
artifactList.repaint();
|
artifactList.repaint();
|
||||||
}//GEN-LAST:event_deselectAllButtonActionPerformed
|
}//GEN-LAST:event_deselectAllButtonActionPerformed
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// 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.JScrollPane artifactScrollPane;
|
||||||
private javax.swing.JButton deselectAllButton;
|
private javax.swing.JButton deselectAllButton;
|
||||||
private javax.swing.JButton okButton;
|
private javax.swing.JButton okButton;
|
||||||
@ -236,16 +242,16 @@ public class ArtifactSelectionDialog extends javax.swing.JDialog {
|
|||||||
private javax.swing.JLabel titleLabel;
|
private javax.swing.JLabel titleLabel;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
private class ArtifactModel implements ListModel<ARTIFACT_TYPE> {
|
private class ArtifactModel implements ListModel<BlackboardArtifact.Type> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return artifacts.size();
|
return artifactTypes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ARTIFACT_TYPE getElementAt(int index) {
|
public BlackboardArtifact.Type getElementAt(int index) {
|
||||||
return artifacts.get(index);
|
return artifactTypes.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
@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) {
|
if (value != null) {
|
||||||
setEnabled(list.isEnabled());
|
setEnabled(list.isEnabled());
|
||||||
setSelected(artifactStates.get(value));
|
setSelected(artifactTypeSelections.get(value));
|
||||||
setFont(list.getFont());
|
setFont(list.getFont());
|
||||||
setBackground(list.getBackground());
|
setBackground(list.getBackground());
|
||||||
setForeground(list.getForeground());
|
setForeground(list.getForeground());
|
||||||
|
@ -71,8 +71,6 @@ ReportGenerator.artifactTable.taggedResults.text=Contains results that were tagg
|
|||||||
ReportGenerator.progress.processing=Now processing {0}...
|
ReportGenerator.progress.processing=Now processing {0}...
|
||||||
ReportGenerator.msgShow.skippingArtType.title=Skipping artifact type {0} in reports
|
ReportGenerator.msgShow.skippingArtType.title=Skipping artifact type {0} in reports
|
||||||
ReportGenerator.msgShow.skippingArtType.msg=Unknown columns to report on
|
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.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.makeBbArtTagTab.taggedRes.msg=This report only includes results tagged with\:
|
||||||
ReportGenerator.tagTable.header.resultType=Result Type
|
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;
|
break;
|
||||||
}
|
}
|
||||||
} else { // no defined artifact found for this dataType
|
} 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
|
in = getClass().getResourceAsStream("/org/sleuthkit/autopsy/report/images/star.png"); //NON-NLS
|
||||||
iconFileName = "star.png"; //NON-NLS
|
iconFileName = "star.png"; //NON-NLS
|
||||||
iconFilePath = path + File.separator + iconFileName;
|
iconFilePath = path + File.separator + iconFileName;
|
||||||
@ -984,8 +983,8 @@ class ReportHTML implements TableReportModule {
|
|||||||
StringBuilder head = new StringBuilder();
|
StringBuilder head = new StringBuilder();
|
||||||
head.append("<html>\n<head>\n<title>").append( //NON-NLS
|
head.append("<html>\n<head>\n<title>").append( //NON-NLS
|
||||||
NbBundle.getMessage(this.getClass(), "ReportHTML.writeSum.title")).append("</title>\n"); //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("<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("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("#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
|
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 = "";
|
geoPath = "";
|
||||||
String extractedToPath;
|
String extractedToPath;
|
||||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
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();
|
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();
|
lon = attribute.getValueDouble();
|
||||||
}
|
}
|
||||||
@ -150,11 +150,11 @@ class ReportKML implements GeneralReportModule {
|
|||||||
lat = 0;
|
lat = 0;
|
||||||
lon = 0;
|
lon = 0;
|
||||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
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();
|
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();
|
lon = attribute.getValueDouble();
|
||||||
}
|
}
|
||||||
@ -172,22 +172,22 @@ class ReportKML implements GeneralReportModule {
|
|||||||
String name = "";
|
String name = "";
|
||||||
String location = "";
|
String location = "";
|
||||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
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();
|
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();
|
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();
|
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();
|
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();
|
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();
|
location = attribute.getValueString();
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import java.awt.event.MouseAdapter;
|
|||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -50,8 +51,8 @@ final class ReportVisualPanel2 extends JPanel {
|
|||||||
private Map<String, Boolean> tagStates = new LinkedHashMap<>();
|
private Map<String, Boolean> tagStates = new LinkedHashMap<>();
|
||||||
private List<String> tags = new ArrayList<>();
|
private List<String> tags = new ArrayList<>();
|
||||||
ArtifactSelectionDialog dialog = new ArtifactSelectionDialog(new JFrame(), true);
|
ArtifactSelectionDialog dialog = new ArtifactSelectionDialog(new JFrame(), true);
|
||||||
private Map<ARTIFACT_TYPE, Boolean> artifactStates = new EnumMap<>(ARTIFACT_TYPE.class);
|
private Map<BlackboardArtifact.Type, Boolean> artifactStates = new HashMap<>();
|
||||||
private List<ARTIFACT_TYPE> artifacts = new ArrayList<>();
|
private List<BlackboardArtifact.Type> artifacts = new ArrayList<>();
|
||||||
private TagsListModel tagsModel;
|
private TagsListModel tagsModel;
|
||||||
private TagsListRenderer tagsRenderer;
|
private TagsListRenderer tagsRenderer;
|
||||||
|
|
||||||
@ -111,16 +112,20 @@ final class ReportVisualPanel2 extends JPanel {
|
|||||||
private void initArtifactTypes() {
|
private void initArtifactTypes() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> doNotReport = new ArrayList<>();
|
ArrayList<BlackboardArtifact.Type> doNotReport = new ArrayList<>();
|
||||||
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO);
|
doNotReport.add(new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID(),
|
||||||
doNotReport.add(BlackboardArtifact.ARTIFACT_TYPE.TSK_TOOL_OUTPUT); // output is too unstructured for table review
|
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);
|
artifacts.removeAll(doNotReport);
|
||||||
|
|
||||||
artifactStates = new EnumMap<>(ARTIFACT_TYPE.class);
|
artifactStates = new HashMap<>();
|
||||||
for (ARTIFACT_TYPE type : artifacts) {
|
for (BlackboardArtifact.Type type : artifacts) {
|
||||||
artifactStates.put(type, Boolean.TRUE);
|
artifactStates.put(type, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} 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
|
* @return the enabled/disabled state of all Artifacts
|
||||||
*/
|
*/
|
||||||
Map<ARTIFACT_TYPE, Boolean> getArtifactStates() {
|
Map<BlackboardArtifact.Type, Boolean> getArtifactStates() {
|
||||||
return artifactStates;
|
return artifactStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +166,7 @@ final class ReportVisualPanel2 extends JPanel {
|
|||||||
|
|
||||||
private boolean areArtifactsSelected() {
|
private boolean areArtifactsSelected() {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
for (Entry<ARTIFACT_TYPE, Boolean> entry : artifactStates.entrySet()) {
|
for (Entry<BlackboardArtifact.Type, Boolean> entry : artifactStates.entrySet()) {
|
||||||
if (entry.getValue()) {
|
if (entry.getValue()) {
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ import org.openide.util.actions.CallableSystemAction;
|
|||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
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")
|
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportWizardAction")
|
||||||
@ActionRegistration(displayName = "#CTL_ReportWizardAction", lazy = false)
|
@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
|
ReportGenerator generator = new ReportGenerator((Map<TableReportModule, Boolean>) wiz.getProperty("tableModuleStates"), //NON-NLS
|
||||||
(Map<GeneralReportModule, Boolean>) wiz.getProperty("generalModuleStates"), //NON-NLS
|
(Map<GeneralReportModule, Boolean>) wiz.getProperty("generalModuleStates"), //NON-NLS
|
||||||
(Map<FileReportModule, Boolean>) wiz.getProperty("fileModuleStates")); //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.generateFileListReports((Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
|
||||||
generator.generateGeneralReports();
|
generator.generateGeneralReports();
|
||||||
generator.displayProgressPanels();
|
generator.displayProgressPanels();
|
||||||
|
@ -440,6 +440,7 @@ public class TimeLineController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // TODO (EUR-733): Do not use SleuthkitCase.getLastObjectId
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
||||||
@NbBundle.Messages({"TimeLineController.errorTitle=Timeline error.",
|
@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.",
|
"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
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2014-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,10 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
|
package org.sleuthkit.autopsy.timeline.datamodel.eventtype;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.Optional;
|
||||||
import java.util.Map;
|
import java.util.function.Function;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -34,56 +33,56 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
*/
|
*/
|
||||||
public interface ArtifactEventType extends EventType {
|
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
|
* @return the Artifact type this event type is derived from
|
||||||
* there is no artifact type (eg file system events)
|
|
||||||
*/
|
*/
|
||||||
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
|
* given an artifact, pull out the time stamp, and compose the descriptions.
|
||||||
* the time stamp, and compose the descriptions. Each implementation of
|
* Each implementation of {@link ArtifactEventType} needs to implement
|
||||||
* {@link ArtifactEventType} needs to implement parseAttributesHelper() as
|
* parseAttributesHelper() as hook for {@link buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact)
|
||||||
* hook for {@link buildEventDescription(org.sleuthkit.datamodel.BlackboardArtifact)
|
|
||||||
* to invoke. Most subtypes can use this default implementation.
|
* to invoke. Most subtypes can use this default implementation.
|
||||||
*
|
*
|
||||||
* @param artf
|
* @param artf
|
||||||
* @param attrMap
|
|
||||||
*
|
*
|
||||||
* @return an {@link AttributeEventDescription} containing the timestamp
|
* @return an {@link AttributeEventDescription} containing the timestamp
|
||||||
* and description information
|
* and description information
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
default AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) throws TskCoreException {
|
default AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf) throws TskCoreException {
|
||||||
final BlackboardAttribute dateTimeAttr = attrMap.get(getDateTimeAttrubuteType());
|
final BlackboardAttribute dateTimeAttr = artf.getAttribute(getDateTimeAttrubuteType());
|
||||||
|
|
||||||
long time = dateTimeAttr.getValueLong();
|
long time = dateTimeAttr.getValueLong();
|
||||||
String shortDescription = getShortExtractor().apply(artf, attrMap);
|
String shortDescription = getShortExtractor().apply(artf);
|
||||||
String medDescription = shortDescription + " : " + getMedExtractor().apply(artf, attrMap);
|
String medDescription = shortDescription + " : " + getMedExtractor().apply(artf);
|
||||||
String fullDescription = medDescription + " : " + getFullExtractor().apply(artf, attrMap);
|
String fullDescription = medDescription + " : " + getFullExtractor().apply(artf);
|
||||||
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
|
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a function from an artifact and a map of its attributes, to a
|
* @return a function from an artifact to a String to use as part of the
|
||||||
* String to use as part of the full event description
|
* 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
|
* @return a function from an artifact to a String to use as part of the
|
||||||
* String to use as part of the medium event description
|
* 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
|
* @return a function from an artifact to a String to use as part of the
|
||||||
* String to use as part of the short event description
|
* 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
|
* bundles the per event information derived from a BlackBoard Artifact into
|
||||||
@ -124,14 +123,13 @@ public interface ArtifactEventType extends EventType {
|
|||||||
this.medDescription = medDescription;
|
this.medDescription = medDescription;
|
||||||
this.fullDescription = fullDescription;
|
this.fullDescription = fullDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a {@link AttributeEventDescription} derived from a
|
* Build a {@link AttributeEventDescription} derived from a
|
||||||
* {@link BlackboardArtifact}. This is a template method that relies on each
|
* {@link BlackboardArtifact}. This is a template method that relies on each
|
||||||
* {@link SubType}'s implementation of
|
* {@link ArtifactEventType}'s implementation of
|
||||||
* {@link SubType#parseAttributesHelper()} to know how to go from
|
* {@link ArtifactEventType#parseAttributesHelper()} to know how to go from
|
||||||
* {@link BlackboardAttribute}s to the event description.
|
* {@link BlackboardAttribute}s to the event description.
|
||||||
*
|
*
|
||||||
* @param artf the {@link BlackboardArtifact} to derive the event
|
* @param artf the {@link BlackboardArtifact} to derive the event
|
||||||
@ -149,48 +147,45 @@ public interface ArtifactEventType extends EventType {
|
|||||||
if (type.getArtifactType().getTypeID() != artf.getArtifactTypeID()) {
|
if (type.getArtifactType().getTypeID() != artf.getArtifactTypeID()) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
if (artf.getAttribute(type.getDateTimeAttrubuteType()) == null) {
|
||||||
/*
|
LOGGER.log(Level.WARNING, "Artifact {0} has no date/time attribute, skipping it.", artf.getArtifactID()); // NON-NLS
|
||||||
* 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
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//use the hook provided by this subtype implementation
|
//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) {
|
||||||
public String apply(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
|
return Optional.ofNullable(getAttributeSafe(artf, attributeType))
|
||||||
final BlackboardAttribute attr = attrMap.get(attribute);
|
.map(BlackboardAttribute::getDisplayString)
|
||||||
return (attr != null) ? StringUtils.defaultString(attr.getDisplayString()) : " ";
|
.map(StringUtils::defaultString)
|
||||||
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BlackboardAttribute.ATTRIBUTE_TYPE attribute;
|
private final BlackboardAttribute.Type attributeType;
|
||||||
|
|
||||||
public AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE attribute) {
|
public AttributeExtractor(BlackboardAttribute.Type attribute) {
|
||||||
this.attribute = 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
|
@Override
|
||||||
public String apply(BlackboardArtifact t, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> u) {
|
public String apply(BlackboardArtifact t) {
|
||||||
return "";
|
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
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2014-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Optional;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
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.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,116 +42,113 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
public enum MiscTypes implements EventType, ArtifactEventType {
|
public enum MiscTypes implements EventType, ArtifactEventType {
|
||||||
|
|
||||||
MESSAGE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.message.name"), "message.png", // NON-NLS
|
MESSAGE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.message.name"), "message.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_MESSAGE),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE)),
|
||||||
(artf, attrMap) -> {
|
artf -> {
|
||||||
final BlackboardAttribute dir = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION);
|
final BlackboardAttribute dir = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DIRECTION));
|
||||||
final BlackboardAttribute readStatus = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_READ_STATUS);
|
final BlackboardAttribute readStatus = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_READ_STATUS));
|
||||||
final BlackboardAttribute name = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME);
|
final BlackboardAttribute name = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_NAME));
|
||||||
final BlackboardAttribute phoneNumber = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER);
|
final BlackboardAttribute phoneNumber = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
|
||||||
final BlackboardAttribute subject = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT);
|
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)));
|
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, " ");
|
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
|
GPS_ROUTE(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSRoutes.name"), "gps-search.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_GPS_ROUTE),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_LOCATION)),
|
||||||
(artf, attrMap) -> {
|
artf -> {
|
||||||
final BlackboardAttribute latStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START);
|
final BlackboardAttribute latStart = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START));
|
||||||
final BlackboardAttribute longStart = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START);
|
final BlackboardAttribute longStart = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START));
|
||||||
final BlackboardAttribute latEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END);
|
final BlackboardAttribute latEnd = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END));
|
||||||
final BlackboardAttribute longEnd = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END);
|
final BlackboardAttribute longEnd = getAttributeSafe(artf, new BlackboardAttribute.Type(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
|
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
|
GPS_TRACKPOINT(NbBundle.getMessage(MiscTypes.class, "MiscTypes.GPSTrackpoint.name"), "gps-trackpoint.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_GPS_TRACKPOINT),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
||||||
(artf, attrMap) -> {
|
artf -> {
|
||||||
final BlackboardAttribute longitude = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE);
|
final BlackboardAttribute longitude = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE));
|
||||||
final BlackboardAttribute latitude = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
|
final BlackboardAttribute latitude = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE));
|
||||||
return (latitude != null ? latitude.getValueDouble() : "") + " " + (longitude != null ? longitude.getValueDouble() : ""); // NON-NLS
|
return stringValueOf(latitude) + " " + stringValueOf(longitude); // NON-NLS
|
||||||
},
|
},
|
||||||
(artf, attrMap) -> ""),
|
EMPTY_EXTRACTOR),
|
||||||
CALL_LOG(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Calls.name"), "calllog.png", // NON-NLS
|
CALL_LOG(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Calls.name"), "calllog.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_CALLLOG),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_START),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_NAME)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DIRECTION))),
|
||||||
EMAIL(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Email.name"), "mail-icon-16.png", // NON-NLS
|
EMAIL(NbBundle.getMessage(MiscTypes.class, "MiscTypes.Email.name"), "mail-icon-16.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_EMAIL_MSG),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_SENT),
|
||||||
(artifact, attrMap) -> {
|
artf -> {
|
||||||
final BlackboardAttribute emailFrom = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM);
|
final BlackboardAttribute emailFrom = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_FROM));
|
||||||
final BlackboardAttribute emailTo = attrMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO);
|
final BlackboardAttribute emailTo = getAttributeSafe(artf, new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_EMAIL_TO));
|
||||||
return (emailFrom != null ? emailFrom.getValueString() : "") + " to " + (emailTo != null ? emailTo.getValueString() : ""); // NON-NLS
|
return stringValueOf(emailFrom) + " to " + stringValueOf(emailTo); // NON-NLS
|
||||||
},
|
},
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SUBJECT)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)),
|
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
|
RECENT_DOCUMENTS(NbBundle.getMessage(MiscTypes.class, "MiscTypes.recentDocuments.name"), "recent_docs.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_RECENT_OBJECT),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH).andThen(
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH)).andThen(
|
||||||
(String t) -> (StringUtils.substringBeforeLast(StringUtils.substringBeforeLast(t, "\\"), "\\"))),
|
(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, "\\")),
|
(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
|
@Override
|
||||||
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) throws TskCoreException {
|
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf) throws TskCoreException {
|
||||||
final BlackboardAttribute dateTimeAttr = attrMap.get(getDateTimeAttrubuteType());
|
final BlackboardAttribute dateTimeAttr = artf.getAttribute(getDateTimeAttrubuteType());
|
||||||
|
|
||||||
long time = dateTimeAttr.getValueLong();
|
long time = dateTimeAttr.getValueLong();
|
||||||
|
|
||||||
//Non-default description construction
|
//Non-default description construction
|
||||||
String shortDescription = getShortExtractor().apply(artf, attrMap);
|
String shortDescription = getShortExtractor().apply(artf);
|
||||||
String medDescription = getMedExtractor().apply(artf, attrMap);
|
String medDescription = getMedExtractor().apply(artf);
|
||||||
String fullDescription = getFullExtractor().apply(artf, attrMap);
|
String fullDescription = getFullExtractor().apply(artf);
|
||||||
|
|
||||||
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
|
return new AttributeEventDescription(time, shortDescription, medDescription, fullDescription);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
INSTALLED_PROGRAM(NbBundle.getMessage(MiscTypes.class, "MiscTypes.installedPrograms.name"), "programs.png", // NON-NLS
|
INSTALLED_PROGRAM(NbBundle.getMessage(MiscTypes.class, "MiscTypes.installedPrograms.name"), "programs.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_INSTALLED_PROG),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PROG_NAME)),
|
||||||
new EmptyExtractor(),
|
EMPTY_EXTRACTOR,
|
||||||
new EmptyExtractor()),
|
EMPTY_EXTRACTOR),
|
||||||
EXIF(NbBundle.getMessage(MiscTypes.class, "MiscTypes.exif.name"), "camera-icon-16.png", // NON-NLS
|
EXIF(NbBundle.getMessage(MiscTypes.class, "MiscTypes.exif.name"), "camera-icon-16.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_METADATA_EXIF),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
|
||||||
(artifact, attributeMap) -> {
|
artf -> {
|
||||||
try {
|
try {
|
||||||
AbstractFile file = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
|
AbstractFile file = artf.getSleuthkitCase().getAbstractFileById(artf.getObjectID());
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
return file.getName();
|
return file.getName();
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} 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
|
DEVICES_ATTACHED(NbBundle.getMessage(MiscTypes.class, "MiscTypes.devicesAttached.name"), "usb_devices.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED,
|
TypeUtils.fromEnum(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL),
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID));
|
new AttributeExtractor(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_ID)));
|
||||||
|
|
||||||
static public String stringValueOf(BlackboardAttribute attr) {
|
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) {
|
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;
|
private final String iconBase;
|
||||||
|
|
||||||
@ -178,47 +177,32 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
return image;
|
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
|
@Override
|
||||||
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getFullExtractor() {
|
public Function<BlackboardArtifact, String> getFullExtractor() {
|
||||||
return longExtractor;
|
return longExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getMedExtractor() {
|
public Function<BlackboardArtifact, String> getMedExtractor() {
|
||||||
return medExtractor;
|
return medExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getShortExtractor() {
|
public Function<BlackboardArtifact, String> getShortExtractor() {
|
||||||
return shortExtractor;
|
return shortExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public BlackboardAttribute.ATTRIBUTE_TYPE getDateTimeAttrubuteType() {
|
public BlackboardAttribute.Type getDateTimeAttrubuteType() {
|
||||||
return dateTimeAttributeType;
|
return dateTimeAttributeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc }
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public EventTypeZoomLevel getZoomLevel() {
|
public EventTypeZoomLevel getZoomLevel() {
|
||||||
return EventTypeZoomLevel.SUB_TYPE;
|
return EventTypeZoomLevel.SUB_TYPE;
|
||||||
@ -226,7 +210,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
|
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
private final BlackboardArtifact.ARTIFACT_TYPE artifactType;
|
private final BlackboardArtifact.Type artifactType;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName() {
|
public String getDisplayName() {
|
||||||
@ -243,11 +227,11 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
return MiscTypes.valueOf(string);
|
return MiscTypes.valueOf(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MiscTypes(String displayName, String iconBase, BlackboardArtifact.ARTIFACT_TYPE artifactType,
|
private MiscTypes(String displayName, String iconBase, BlackboardArtifact.Type artifactType,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType,
|
BlackboardAttribute.Type dateTimeAttributeType,
|
||||||
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> shortExtractor,
|
Function<BlackboardArtifact, String> shortExtractor,
|
||||||
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> medExtractor,
|
Function<BlackboardArtifact, String> medExtractor,
|
||||||
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> longExtractor) {
|
Function<BlackboardArtifact, String> longExtractor) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
this.iconBase = iconBase;
|
this.iconBase = iconBase;
|
||||||
this.artifactType = artifactType;
|
this.artifactType = artifactType;
|
||||||
@ -269,7 +253,7 @@ public enum MiscTypes implements EventType, ArtifactEventType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlackboardArtifact.ARTIFACT_TYPE getArtifactType() {
|
public BlackboardArtifact.Type getArtifactType() {
|
||||||
return artifactType;
|
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
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2014 Basis Technology Corp.
|
* Copyright 2014-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* 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 com.google.common.net.InternetDomainName;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.function.Function;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
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"),
|
WEB_DOWNLOADS(NbBundle.getMessage(WebTypes.class, "WebTypes.webDownloads.name"),
|
||||||
"downloads.png", // NON-NLS
|
"downloads.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
|
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)) {
|
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
|
@Override
|
||||||
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
|
public AttributeEventDescription parseAttributesHelper(BlackboardArtifact artf) throws TskCoreException {
|
||||||
long time = attrMap.get(getDateTimeAttrubuteType()).getValueLong();
|
long time = artf.getAttribute(getDateTimeAttrubuteType()).getValueLong();
|
||||||
String domain = getShortExtractor().apply(artf, attrMap);
|
String domain = getShortExtractor().apply(artf);
|
||||||
String path = getMedExtractor().apply(artf, attrMap);
|
String path = getMedExtractor().apply(artf);
|
||||||
String fileName = StringUtils.substringAfterLast(path, "/");
|
String fileName = StringUtils.substringAfterLast(path, "/");
|
||||||
String url = getFullExtractor().apply(artf, attrMap);
|
String url = getFullExtractor().apply(artf);
|
||||||
|
|
||||||
//TODO: review non default description construction
|
//TODO: review non default description construction
|
||||||
String shortDescription = fileName + " from " + domain; // NON-NLS
|
String shortDescription = fileName + " from " + domain; // NON-NLS
|
||||||
@ -66,37 +61,37 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_COOKIE(NbBundle.getMessage(WebTypes.class, "WebTypes.webCookies.name"),
|
WEB_COOKIE(NbBundle.getMessage(WebTypes.class, "WebTypes.webCookies.name"),
|
||||||
"cookies.png", // NON-NLS
|
"cookies.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
|
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME,
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE))),
|
||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_BOOKMARK(NbBundle.getMessage(WebTypes.class, "WebTypes.webBookmarks.name"),
|
WEB_BOOKMARK(NbBundle.getMessage(WebTypes.class, "WebTypes.webBookmarks.name"),
|
||||||
"bookmarks.png", // NON-NLS
|
"bookmarks.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
|
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE))),
|
||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_HISTORY(NbBundle.getMessage(WebTypes.class, "WebTypes.webHistory.name"),
|
WEB_HISTORY(NbBundle.getMessage(WebTypes.class, "WebTypes.webHistory.name"),
|
||||||
"history.png", // NON-NLS
|
"history.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
|
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
TopPrivateDomainExtractor.getInstance(),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL)),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE)),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TITLE))),
|
||||||
//TODO: review description separators
|
//TODO: review description separators
|
||||||
WEB_SEARCH(NbBundle.getMessage(WebTypes.class, "WebTypes.webSearch.name"),
|
WEB_SEARCH(NbBundle.getMessage(WebTypes.class, "WebTypes.webSearch.name"),
|
||||||
"searchquery.png", // NON-NLS
|
"searchquery.png", // NON-NLS
|
||||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY,
|
TypeUtils.fromEnum(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY),
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED),
|
||||||
new AttributeExtractor(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT),
|
new AttributeExtractor(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)),
|
||||||
TopPrivateDomainExtractor.getInstance(),
|
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;
|
private final String iconBase;
|
||||||
|
|
||||||
@ -108,7 +103,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlackboardAttribute.ATTRIBUTE_TYPE getDateTimeAttrubuteType() {
|
public BlackboardAttribute.Type getDateTimeAttrubuteType() {
|
||||||
return dateTimeAttributeType;
|
return dateTimeAttributeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,30 +112,30 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
return EventTypeZoomLevel.SUB_TYPE;
|
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
|
@Override
|
||||||
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getFullExtractor() {
|
public Function<BlackboardArtifact, String> getFullExtractor() {
|
||||||
return longExtractor;
|
return longExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getMedExtractor() {
|
public Function<BlackboardArtifact, String> getMedExtractor() {
|
||||||
return medExtractor;
|
return medExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> getShortExtractor() {
|
public Function<BlackboardArtifact, String> getShortExtractor() {
|
||||||
return shortExtractor;
|
return shortExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
BlackboardArtifact.ARTIFACT_TYPE artifactType;
|
private final BlackboardArtifact.Type artifactType;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getIconBase() {
|
public String getIconBase() {
|
||||||
@ -148,15 +143,15 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlackboardArtifact.ARTIFACT_TYPE getArtifactType() {
|
public BlackboardArtifact.Type getArtifactType() {
|
||||||
return artifactType;
|
return artifactType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebTypes(String displayName, String iconBase, BlackboardArtifact.ARTIFACT_TYPE artifactType,
|
private WebTypes(String displayName, String iconBase, BlackboardArtifact.Type artifactType,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE dateTimeAttributeType,
|
BlackboardAttribute.Type dateTimeAttributeType,
|
||||||
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> shortExtractor,
|
Function<BlackboardArtifact, String> shortExtractor,
|
||||||
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> medExtractor,
|
Function<BlackboardArtifact, String> medExtractor,
|
||||||
BiFunction<BlackboardArtifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute>, String> longExtractor) {
|
Function<BlackboardArtifact, String> longExtractor) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
this.iconBase = iconBase;
|
this.iconBase = iconBase;
|
||||||
this.artifactType = artifactType;
|
this.artifactType = artifactType;
|
||||||
@ -196,8 +191,8 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(BlackboardArtifact artf, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attrMap) {
|
public String apply(BlackboardArtifact artf) {
|
||||||
String domainString = StringUtils.substringBefore(super.apply(artf, attrMap), "/");
|
String domainString = StringUtils.substringBefore(super.apply(artf), "/");
|
||||||
if (InternetDomainName.isValid(domainString)) {
|
if (InternetDomainName.isValid(domainString)) {
|
||||||
InternetDomainName domain = InternetDomainName.from(domainString);
|
InternetDomainName domain = InternetDomainName.from(domainString);
|
||||||
return (domain.isUnderPublicSuffix())
|
return (domain.isUnderPublicSuffix())
|
||||||
@ -209,8 +204,7 @@ public enum WebTypes implements EventType, ArtifactEventType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TopPrivateDomainExtractor() {
|
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);
|
updateProgress(workDone, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // TODO (EUR-733): Do not use SleuthkitCase.getLastObjectId
|
||||||
@Override
|
@Override
|
||||||
@NbBundle.Messages({"progressWindow.msg.refreshingFileTags=Refreshing file tags",
|
@NbBundle.Messages({"progressWindow.msg.refreshingFileTags=Refreshing file tags",
|
||||||
"progressWindow.msg.refreshingResultTags=Refreshing result tags",
|
"progressWindow.msg.refreshingResultTags=Refreshing result tags",
|
||||||
@ -654,7 +655,7 @@ public class EventsRepository {
|
|||||||
private void populateEventType(final ArtifactEventType type, EventDB.EventTransaction trans) {
|
private void populateEventType(final ArtifactEventType type, EventDB.EventTransaction trans) {
|
||||||
try {
|
try {
|
||||||
//get all the blackboard artifacts corresponding to the given event sub_type
|
//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();
|
final int numArtifacts = blackboardArtifacts.size();
|
||||||
restartProgressHandle(Bundle.progressWindow_populatingXevents(type.getDisplayName()), "", 0D, numArtifacts, true);
|
restartProgressHandle(Bundle.progressWindow_populatingXevents(type.getDisplayName()), "", 0D, numArtifacts, true);
|
||||||
for (int i = 0; i < numArtifacts; i++) {
|
for (int i = 0; i < numArtifacts; i++) {
|
||||||
|
@ -6,8 +6,8 @@ OpenIDE-Module-Name=ImageGallery
|
|||||||
OpenIDE-Module-Short-Description=Advanced image and video gallery
|
OpenIDE-Module-Short-Description=Advanced image and video gallery
|
||||||
ImageGalleryOptionsPanel.enabledForCaseBox.text=Enable Image Gallery updates for the current case.
|
ImageGalleryOptionsPanel.enabledForCaseBox.text=Enable Image Gallery updates for the current case.
|
||||||
ImageGalleryOptionsPanel.enabledByDefaultBox.text=Enable Image Gallery for new cases by default.
|
ImageGalleryOptionsPanel.enabledByDefaultBox.text=Enable Image Gallery for new cases by default.
|
||||||
ImageGalleryOptionsPanel.enabledForCaseBox.toolTipText=If Image Gallery is disabled, only the fact that an update is needed is recorded. If Image Gallery is enabled after ingest, it will do one bulk update based on the results form ingest. If Image Gallery is disabled, you will be prompted to enable it when attempting to open its window.
|
ImageGalleryOptionsPanel.enabledForCaseBox.toolTipText=If Image Gallery is disabled, only the fact that an update is needed is recorded. If Image Gallery is enabled after ingest, it will do one bulk update based on the results from ingest. If Image Gallery is disabled, you will be prompted to enable it when attempting to open its window.
|
||||||
ImageGalleryOptionsPanel.descriptionLabel.text=<html>To minimize its startup times, Image Gallery will constantly update its internal database. <br />This can cause ingest to be slower if you do not need the Image Gallery features. <br />Use these settings to disable Image Gallery if you do not need it.</html>
|
ImageGalleryOptionsPanel.descriptionLabel.text=<html>To minimize its startup times, Image Gallery will constantly update its internal database. <br />This can cause ingest to be slower if you do not need the Image Gallery features. <br />Use these settings to disable Image Gallery if you do not need it.</html>
|
||||||
ImageGalleryOptionsPanel.furtherDescriptionArea.text=If Image Gallery is disabled, only the fact that an update is needed is recorded. If Image Gallery is enabled after ingest, it will do one bulk update based on the results form ingest. If Image Gallery is disabled, you will be prompted to enable it when attempting to open its window.
|
ImageGalleryOptionsPanel.furtherDescriptionArea.text=If Image Gallery is disabled, only the fact that an update is needed is recorded. If Image Gallery is enabled after ingest, it will do one bulk update based on the results from ingest. If Image Gallery is disabled, you will be prompted to enable it when attempting to open its window.
|
||||||
ImageGalleryOptionsPanel.unavailableDuringInjestLabel.text=This setting is unavailable during ingest.
|
ImageGalleryOptionsPanel.unavailableDuringInjestLabel.text=This setting is unavailable during ingest.
|
||||||
ImageGalleryOptionsPanel.infoIconLabel.text=
|
ImageGalleryOptionsPanel.groupCategorizationWarningBox.text=Don't show a warning when overwriting categories, by acting on an entire group.
|
||||||
|
@ -35,6 +35,7 @@ import javafx.beans.Observable;
|
|||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||||
|
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||||
import javafx.beans.property.ReadOnlyIntegerProperty;
|
import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||||
import javafx.beans.property.ReadOnlyIntegerWrapper;
|
import javafx.beans.property.ReadOnlyIntegerWrapper;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
@ -95,6 +96,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
|
|
||||||
private final Executor execDelegate = Executors.newSingleThreadExecutor();
|
private final Executor execDelegate = Executors.newSingleThreadExecutor();
|
||||||
private Runnable showTree;
|
private Runnable showTree;
|
||||||
|
private Toolbar toolbar;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
@ -128,14 +130,13 @@ public final class ImageGalleryController implements Executor {
|
|||||||
*/
|
*/
|
||||||
private final SimpleBooleanProperty listeningEnabled = new SimpleBooleanProperty(false);
|
private final SimpleBooleanProperty listeningEnabled = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
private final ReadOnlyIntegerWrapper queueSizeProperty = new ReadOnlyIntegerWrapper(0);
|
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper regroupDisabled = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper regroupDisabled = new ReadOnlyBooleanWrapper(false);
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private final ReadOnlyBooleanWrapper stale = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper stale = new ReadOnlyBooleanWrapper(false);
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper metaDataCollapsed = new ReadOnlyBooleanWrapper(false);
|
private final ReadOnlyBooleanWrapper metaDataCollapsed = new ReadOnlyBooleanWrapper(false);
|
||||||
|
private final ReadOnlyDoubleWrapper thumbnailSize = new ReadOnlyDoubleWrapper(100);
|
||||||
|
|
||||||
private final FileIDSelectionModel selectionModel = new FileIDSelectionModel(this);
|
private final FileIDSelectionModel selectionModel = new FileIDSelectionModel(this);
|
||||||
|
|
||||||
@ -154,7 +155,6 @@ public final class ImageGalleryController implements Executor {
|
|||||||
|
|
||||||
private Node infoOverlay;
|
private Node infoOverlay;
|
||||||
private SleuthkitCase sleuthKitCase;
|
private SleuthkitCase sleuthKitCase;
|
||||||
// private NavPanel navPanel;
|
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getMetaDataCollapsed() {
|
public ReadOnlyBooleanProperty getMetaDataCollapsed() {
|
||||||
return metaDataCollapsed.getReadOnlyProperty();
|
return metaDataCollapsed.getReadOnlyProperty();
|
||||||
@ -164,6 +164,10 @@ public final class ImageGalleryController implements Executor {
|
|||||||
this.metaDataCollapsed.set(metaDataCollapsed);
|
this.metaDataCollapsed.set(metaDataCollapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlyDoubleProperty thumbnailSizeProperty() {
|
||||||
|
return thumbnailSize.getReadOnlyProperty();
|
||||||
|
}
|
||||||
|
|
||||||
private GroupViewState getViewState() {
|
private GroupViewState getViewState() {
|
||||||
return historyManager.getCurrentState();
|
return historyManager.getCurrentState();
|
||||||
}
|
}
|
||||||
@ -176,7 +180,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
return historyManager.currentState();
|
return historyManager.currentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized FileIDSelectionModel getSelectionModel() {
|
public FileIDSelectionModel getSelectionModel() {
|
||||||
return selectionModel;
|
return selectionModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,12 +192,16 @@ public final class ImageGalleryController implements Executor {
|
|||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void setListeningEnabled(boolean enabled) {
|
public void setListeningEnabled(boolean enabled) {
|
||||||
listeningEnabled.set(enabled);
|
synchronized (listeningEnabled) {
|
||||||
|
listeningEnabled.set(enabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized boolean isListeningEnabled() {
|
boolean isListeningEnabled() {
|
||||||
return listeningEnabled.get();
|
synchronized (listeningEnabled) {
|
||||||
|
return listeningEnabled.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
@ThreadConfined(type = ThreadConfined.ThreadType.ANY)
|
||||||
@ -249,12 +257,14 @@ public final class ImageGalleryController implements Executor {
|
|||||||
checkForGroups();
|
checkForGroups();
|
||||||
});
|
});
|
||||||
|
|
||||||
IngestManager.getInstance().addIngestModuleEventListener((PropertyChangeEvent evt) -> {
|
IngestManager ingestManager = IngestManager.getInstance();
|
||||||
Platform.runLater(this::updateRegroupDisabled);
|
PropertyChangeListener ingestEventHandler =
|
||||||
});
|
propertyChangeEvent -> Platform.runLater(this::updateRegroupDisabled);
|
||||||
IngestManager.getInstance().addIngestJobEventListener((PropertyChangeEvent evt) -> {
|
|
||||||
Platform.runLater(this::updateRegroupDisabled);
|
ingestManager.addIngestModuleEventListener(ingestEventHandler);
|
||||||
});
|
ingestManager.addIngestJobEventListener(ingestEventHandler);
|
||||||
|
|
||||||
|
queueSizeProperty.addListener(obs -> this.updateRegroupDisabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty getCanAdvance() {
|
public ReadOnlyBooleanProperty getCanAdvance() {
|
||||||
@ -281,8 +291,9 @@ public final class ImageGalleryController implements Executor {
|
|||||||
return historyManager.retreat();
|
return historyManager.retreat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private void updateRegroupDisabled() {
|
private void updateRegroupDisabled() {
|
||||||
regroupDisabled.set(getFileUpdateQueueSizeProperty().get() > 0 || IngestManager.getInstance().isIngestRunning());
|
regroupDisabled.set((queueSizeProperty.get() > 0) || IngestManager.getInstance().isIngestRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,7 +324,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
new ProgressIndicator()));
|
new ProgressIndicator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (getFileUpdateQueueSizeProperty().get() > 0) {
|
} else if (queueSizeProperty.get() > 0) {
|
||||||
replaceNotification(fullUIStackPane,
|
replaceNotification(fullUIStackPane,
|
||||||
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg3(),
|
new NoGroupsDialog(Bundle.ImageGalleryController_noGroupsDlg_msg3(),
|
||||||
new ProgressIndicator()));
|
new ProgressIndicator()));
|
||||||
@ -358,20 +369,14 @@ public final class ImageGalleryController implements Executor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartWorker() {
|
synchronized private DBWorkerThread restartWorker() {
|
||||||
if (dbWorkerThread != null) {
|
if (dbWorkerThread == null) {
|
||||||
|
dbWorkerThread = new DBWorkerThread(this);
|
||||||
|
dbWorkerThread.start();
|
||||||
|
} else {
|
||||||
// Keep using the same worker thread if one exists
|
// Keep using the same worker thread if one exists
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
dbWorkerThread = new DBWorkerThread();
|
return dbWorkerThread;
|
||||||
|
|
||||||
getFileUpdateQueueSizeProperty().addListener((Observable o) -> {
|
|
||||||
Platform.runLater(this::updateRegroupDisabled);
|
|
||||||
});
|
|
||||||
|
|
||||||
Thread th = new Thread(dbWorkerThread, "DB-Worker-Thread");
|
|
||||||
th.setDaemon(false); // we want it to go away when it is done
|
|
||||||
th.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -412,15 +417,18 @@ public final class ImageGalleryController implements Executor {
|
|||||||
setListeningEnabled(false);
|
setListeningEnabled(false);
|
||||||
ThumbnailCache.getDefault().clearCache();
|
ThumbnailCache.getDefault().clearCache();
|
||||||
historyManager.clear();
|
historyManager.clear();
|
||||||
|
groupManager.clear();
|
||||||
tagsManager.clearFollowUpTagName();
|
tagsManager.clearFollowUpTagName();
|
||||||
tagsManager.unregisterListener(groupManager);
|
tagsManager.unregisterListener(groupManager);
|
||||||
tagsManager.unregisterListener(categoryManager);
|
tagsManager.unregisterListener(categoryManager);
|
||||||
dbWorkerThread.cancelAllTasks();
|
dbWorkerThread.cancel();
|
||||||
dbWorkerThread = null;
|
dbWorkerThread = null;
|
||||||
restartWorker();
|
dbWorkerThread = restartWorker();
|
||||||
|
|
||||||
|
if (toolbar != null) {
|
||||||
|
toolbar.reset();
|
||||||
|
}
|
||||||
|
|
||||||
Toolbar.getDefault(this).reset();
|
|
||||||
groupManager.clear();
|
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
db.closeDBCon();
|
db.closeDBCon();
|
||||||
}
|
}
|
||||||
@ -432,17 +440,15 @@ public final class ImageGalleryController implements Executor {
|
|||||||
*
|
*
|
||||||
* @param innerTask
|
* @param innerTask
|
||||||
*/
|
*/
|
||||||
public void queueDBWorkerTask(InnerTask innerTask) {
|
public synchronized void queueDBWorkerTask(BackgroundTask innerTask) {
|
||||||
|
|
||||||
// @@@ We could make a lock for the worker thread
|
|
||||||
if (dbWorkerThread == null) {
|
if (dbWorkerThread == null) {
|
||||||
restartWorker();
|
dbWorkerThread = restartWorker();
|
||||||
}
|
}
|
||||||
dbWorkerThread.addTask(innerTask);
|
dbWorkerThread.addTask(innerTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
synchronized public DrawableFile<?> getFileFromId(Long fileID) throws TskCoreException {
|
synchronized public DrawableFile getFileFromId(Long fileID) throws TskCoreException {
|
||||||
if (Objects.isNull(db)) {
|
if (Objects.isNull(db)) {
|
||||||
LOGGER.log(Level.WARNING, "Could not get file from id, no DB set. The case is probably closed."); //NON-NLS
|
LOGGER.log(Level.WARNING, "Could not get file from id, no DB set. The case is probably closed."); //NON-NLS
|
||||||
return null;
|
return null;
|
||||||
@ -456,8 +462,12 @@ public final class ImageGalleryController implements Executor {
|
|||||||
Platform.runLater(this::checkForGroups);
|
Platform.runLater(this::checkForGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyIntegerProperty getFileUpdateQueueSizeProperty() {
|
public synchronized void setToolbar(Toolbar toolbar) {
|
||||||
return queueSizeProperty.getReadOnlyProperty();
|
if (this.toolbar != null) {
|
||||||
|
throw new IllegalStateException("Can not set the toolbar a second time!");
|
||||||
|
}
|
||||||
|
this.toolbar = toolbar;
|
||||||
|
thumbnailSize.bind(toolbar.thumbnailSizeProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyDoubleProperty regroupProgress() {
|
public ReadOnlyDoubleProperty regroupProgress() {
|
||||||
@ -497,29 +507,43 @@ public final class ImageGalleryController implements Executor {
|
|||||||
return undoManager;
|
return undoManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @@@ REVIEW IF THIS SHOLD BE STATIC...
|
public ReadOnlyIntegerProperty getDBTasksQueueSizeProperty() {
|
||||||
//TODO: concept seems like the controller deal with how much work to do at a given time
|
return queueSizeProperty.getReadOnlyProperty();
|
||||||
|
}
|
||||||
|
private final ReadOnlyIntegerWrapper queueSizeProperty = new ReadOnlyIntegerWrapper(0);
|
||||||
|
|
||||||
// @@@ review this class for synchronization issues (i.e. reset and cancel being called, add, etc.)
|
// @@@ review this class for synchronization issues (i.e. reset and cancel being called, add, etc.)
|
||||||
private class DBWorkerThread implements Runnable {
|
static private class DBWorkerThread extends Thread implements Cancellable {
|
||||||
|
|
||||||
|
private final ImageGalleryController controller;
|
||||||
|
|
||||||
|
DBWorkerThread(ImageGalleryController controller) {
|
||||||
|
super("DB-Worker-Thread");
|
||||||
|
setDaemon(false);
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
// true if the process was requested to stop. Currently no way to reset it
|
// true if the process was requested to stop. Currently no way to reset it
|
||||||
private volatile boolean cancelled = false;
|
private volatile boolean cancelled = false;
|
||||||
|
|
||||||
// list of tasks to run
|
// list of tasks to run
|
||||||
private final BlockingQueue<InnerTask> workQueue = new LinkedBlockingQueue<>();
|
private final BlockingQueue<BackgroundTask> workQueue = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel all of the queued up tasks and the currently scheduled task.
|
* Cancel all of the queued up tasks and the currently scheduled task.
|
||||||
* Note that after you cancel, you cannot submit new jobs to this
|
* Note that after you cancel, you cannot submit new jobs to this
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
public void cancelAllTasks() {
|
@Override
|
||||||
|
public boolean cancel() {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
for (InnerTask it : workQueue) {
|
for (BackgroundTask it : workQueue) {
|
||||||
it.cancel();
|
it.cancel();
|
||||||
}
|
}
|
||||||
workQueue.clear();
|
workQueue.clear();
|
||||||
queueSizeProperty.set(workQueue.size());
|
int size = workQueue.size();
|
||||||
|
Platform.runLater(() -> controller.queueSizeProperty.set(size));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -527,11 +551,10 @@ public final class ImageGalleryController implements Executor {
|
|||||||
*
|
*
|
||||||
* @param it
|
* @param it
|
||||||
*/
|
*/
|
||||||
public void addTask(InnerTask it) {
|
public void addTask(BackgroundTask it) {
|
||||||
workQueue.add(it);
|
workQueue.add(it);
|
||||||
Platform.runLater(() -> {
|
int size = workQueue.size();
|
||||||
queueSizeProperty.set(workQueue.size());
|
Platform.runLater(() -> controller.queueSizeProperty.set(size));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -539,19 +562,17 @@ public final class ImageGalleryController implements Executor {
|
|||||||
|
|
||||||
// nearly infinite loop waiting for tasks
|
// nearly infinite loop waiting for tasks
|
||||||
while (true) {
|
while (true) {
|
||||||
if (cancelled) {
|
if (cancelled || isInterrupted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
InnerTask it = workQueue.take();
|
BackgroundTask it = workQueue.take();
|
||||||
|
|
||||||
if (it.isCancelled() == false) {
|
if (it.isCancelled() == false) {
|
||||||
it.run();
|
it.run();
|
||||||
}
|
}
|
||||||
|
int size = workQueue.size();
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> controller.queueSizeProperty.set(size));
|
||||||
queueSizeProperty.set(workQueue.size());
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to run DB worker thread", ex); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Failed to run DB worker thread", ex); //NON-NLS
|
||||||
@ -569,7 +590,14 @@ public final class ImageGalleryController implements Executor {
|
|||||||
*/
|
*/
|
||||||
@NbBundle.Messages({"ImageGalleryController.InnerTask.progress.name=progress",
|
@NbBundle.Messages({"ImageGalleryController.InnerTask.progress.name=progress",
|
||||||
"ImageGalleryController.InnerTask.message.name=status"})
|
"ImageGalleryController.InnerTask.message.name=status"})
|
||||||
static public abstract class InnerTask implements Runnable, Cancellable {
|
static public abstract class BackgroundTask implements Runnable, Cancellable {
|
||||||
|
|
||||||
|
private final SimpleObjectProperty<Worker.State> state = new SimpleObjectProperty<>(Worker.State.READY);
|
||||||
|
private final SimpleDoubleProperty progress = new SimpleDoubleProperty(this, Bundle.ImageGalleryController_InnerTask_progress_name());
|
||||||
|
private final SimpleStringProperty message = new SimpleStringProperty(this, Bundle.ImageGalleryController_InnerTask_message_name());
|
||||||
|
|
||||||
|
protected BackgroundTask() {
|
||||||
|
}
|
||||||
|
|
||||||
public double getProgress() {
|
public double getProgress() {
|
||||||
return progress.get();
|
return progress.get();
|
||||||
@ -586,9 +614,6 @@ public final class ImageGalleryController implements Executor {
|
|||||||
public final void updateMessage(String Status) {
|
public final void updateMessage(String Status) {
|
||||||
this.message.set(Status);
|
this.message.set(Status);
|
||||||
}
|
}
|
||||||
private final SimpleObjectProperty<Worker.State> state = new SimpleObjectProperty<>(Worker.State.READY);
|
|
||||||
private final SimpleDoubleProperty progress = new SimpleDoubleProperty(this, Bundle.ImageGalleryController_InnerTask_progress_name());
|
|
||||||
private final SimpleStringProperty message = new SimpleStringProperty(this, Bundle.ImageGalleryController_InnerTask_message_name());
|
|
||||||
|
|
||||||
public SimpleDoubleProperty progressProperty() {
|
public SimpleDoubleProperty progressProperty() {
|
||||||
return progress;
|
return progress;
|
||||||
@ -602,24 +627,21 @@ public final class ImageGalleryController implements Executor {
|
|||||||
return state.get();
|
return state.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateState(Worker.State newState) {
|
|
||||||
state.set(newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Worker.State> stateProperty() {
|
public ReadOnlyObjectProperty<Worker.State> stateProperty() {
|
||||||
return new ReadOnlyObjectWrapper<>(state.get());
|
return new ReadOnlyObjectWrapper<>(state.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InnerTask() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
synchronized public boolean cancel() {
|
public synchronized boolean cancel() {
|
||||||
updateState(Worker.State.CANCELLED);
|
updateState(Worker.State.CANCELLED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized protected boolean isCancelled() {
|
protected void updateState(Worker.State newState) {
|
||||||
|
state.set(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized boolean isCancelled() {
|
||||||
return getState() == Worker.State.CANCELLED;
|
return getState() == Worker.State.CANCELLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -627,7 +649,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
/**
|
/**
|
||||||
* Abstract base class for tasks associated with a file in the database
|
* Abstract base class for tasks associated with a file in the database
|
||||||
*/
|
*/
|
||||||
static public abstract class FileTask extends InnerTask {
|
static public abstract class FileTask extends BackgroundTask {
|
||||||
|
|
||||||
private final AbstractFile file;
|
private final AbstractFile file;
|
||||||
private final DrawableDB taskDB;
|
private final DrawableDB taskDB;
|
||||||
@ -662,7 +684,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
DrawableFile<?> drawableFile = DrawableFile.create(getFile(), true, getTaskDB().isVideoFile(getFile()));
|
DrawableFile drawableFile = DrawableFile.create(getFile(), true, false);
|
||||||
getTaskDB().updateFile(drawableFile);
|
getTaskDB().updateFile(drawableFile);
|
||||||
} catch (NullPointerException ex) {
|
} catch (NullPointerException ex) {
|
||||||
// This is one of the places where we get many errors if the case is closed during processing.
|
// This is one of the places where we get many errors if the case is closed during processing.
|
||||||
@ -704,7 +726,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
@NbBundle.Messages({"BulkTask.committingDb.status=commiting image/video database",
|
@NbBundle.Messages({"BulkTask.committingDb.status=commiting image/video database",
|
||||||
"BulkTask.stopCopy.status=Stopping copy to drawable db task.",
|
"BulkTask.stopCopy.status=Stopping copy to drawable db task.",
|
||||||
"BulkTask.errPopulating.errMsg=There was an error populating Image Gallery database."})
|
"BulkTask.errPopulating.errMsg=There was an error populating Image Gallery database."})
|
||||||
abstract static private class BulkTransferTask extends InnerTask {
|
abstract static private class BulkTransferTask extends BackgroundTask {
|
||||||
|
|
||||||
static private final String FILE_EXTENSION_CLAUSE =
|
static private final String FILE_EXTENSION_CLAUSE =
|
||||||
"(name LIKE '%." //NON-NLS
|
"(name LIKE '%." //NON-NLS
|
||||||
@ -805,10 +827,11 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* adds them to the Drawable DB. Uses the presence of a mimetype as an
|
* adds them to the Drawable DB. Uses the presence of a mimetype as an
|
||||||
* approximation to 'analyzed'.
|
* approximation to 'analyzed'.
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"CopyAnalyzedFiles.committingDb.status=commiting image/video database",
|
||||||
|
"CopyAnalyzedFiles.stopCopy.status=Stopping copy to drawable db task.",
|
||||||
|
"CopyAnalyzedFiles.errPopulating.errMsg=There was an error populating Image Gallery database."})
|
||||||
static private class CopyAnalyzedFiles extends BulkTransferTask {
|
static private class CopyAnalyzedFiles extends BulkTransferTask {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(CopyAnalyzedFiles.class.getName());
|
|
||||||
|
|
||||||
CopyAnalyzedFiles(ImageGalleryController controller, DrawableDB taskDB, SleuthkitCase tskCase) {
|
CopyAnalyzedFiles(ImageGalleryController controller, DrawableDB taskDB, SleuthkitCase tskCase) {
|
||||||
super(controller, taskDB, tskCase);
|
super(controller, taskDB, tskCase);
|
||||||
}
|
}
|
||||||
@ -866,6 +889,7 @@ public final class ImageGalleryController implements Executor {
|
|||||||
* TODO: create methods to simplify progress value/text updates to both
|
* TODO: create methods to simplify progress value/text updates to both
|
||||||
* netbeans and ImageGallery progress/status
|
* netbeans and ImageGallery progress/status
|
||||||
*/
|
*/
|
||||||
|
@NbBundle.Messages({"PrePopulateDataSourceFiles.committingDb.status=commiting image/video database"})
|
||||||
static private class PrePopulateDataSourceFiles extends BulkTransferTask {
|
static private class PrePopulateDataSourceFiles extends BulkTransferTask {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(PrePopulateDataSourceFiles.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(PrePopulateDataSourceFiles.class.getName());
|
||||||
|
@ -27,42 +27,53 @@
|
|||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="unavailableDuringInjestLabel" min="-2" max="-2" attributes="0"/>
|
<Group type="102" attributes="0">
|
||||||
</Group>
|
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
<Component id="unavailableDuringInjestLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="102" alignment="0" attributes="0">
|
</Group>
|
||||||
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
<Component id="infoIconLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="enabledByDefaultBox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<Component id="enabledForCaseBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="furtherDescriptionArea" max="32767" attributes="0"/>
|
<Component id="descriptionLabel" alignment="1" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
|
||||||
|
<Component id="infoIconLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="furtherDescriptionArea" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<Component id="groupCategorizationWarningBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="enabledByDefaultBox" min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="36" max="32767" attributes="0"/>
|
||||||
<Component id="enabledForCaseBox" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="descriptionLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
|
<Component id="jSeparator1" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace pref="46" max="32767" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="descriptionLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="descriptionLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="enabledByDefaultBox" min="-2" max="-2" attributes="0"/>
|
<Component id="enabledByDefaultBox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="enabledForCaseBox" min="-2" max="-2" attributes="0"/>
|
<Component id="enabledForCaseBox" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="unavailableDuringInjestLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="unavailableDuringInjestLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="separate" max="-2" attributes="0"/>
|
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="infoIconLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="infoIconLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="furtherDescriptionArea" min="-2" max="-2" attributes="0"/>
|
<Component id="furtherDescriptionArea" min="-2" pref="100" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="45" max="-2" attributes="0"/>
|
<EmptySpace type="separate" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="groupCategorizationWarningBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -145,9 +156,6 @@
|
|||||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"/>
|
<Image iconType="3" name="/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/imagegallery/Bundle.properties" key="ImageGalleryOptionsPanel.infoIconLabel.text" replaceFormat="NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="unavailableDuringInjestLabel">
|
<Component class="javax.swing.JLabel" name="unavailableDuringInjestLabel">
|
||||||
@ -165,5 +173,14 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JSeparator" name="jSeparator1">
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="groupCategorizationWarningBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/imagegallery/Bundle.properties" key="ImageGalleryOptionsPanel.groupCategorizationWarningBox.text" replaceFormat="NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-15 Basis Technology Corp.
|
* Copyright 2013-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -18,17 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery;
|
package org.sleuthkit.autopsy.imagegallery;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
|
||||||
/** The Image/Video Gallery panel in the NetBeans provided Options Dialogs
|
/**
|
||||||
|
* The Image/Video Gallery panel in the NetBeans provided Options Dialogs
|
||||||
* accessed via Tools -> Options
|
* accessed via Tools -> Options
|
||||||
*
|
*
|
||||||
* Uses {@link ImageGalleryPreferences} and {@link PerCaseProperties} to
|
* Uses {@link ImageGalleryPreferences} and {@link PerCaseProperties} to persist
|
||||||
* persist settings
|
* settings
|
||||||
*/
|
*/
|
||||||
final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
@ -50,10 +50,10 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This method is called from within the constructor to
|
/**
|
||||||
* initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
* always regenerated by the Form Editor.
|
* regenerated by the Form Editor.
|
||||||
*/
|
*/
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
@ -64,6 +64,8 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
furtherDescriptionArea = new javax.swing.JTextArea();
|
furtherDescriptionArea = new javax.swing.JTextArea();
|
||||||
infoIconLabel = new javax.swing.JLabel();
|
infoIconLabel = new javax.swing.JLabel();
|
||||||
unavailableDuringInjestLabel = new javax.swing.JLabel();
|
unavailableDuringInjestLabel = new javax.swing.JLabel();
|
||||||
|
jSeparator1 = new javax.swing.JSeparator();
|
||||||
|
groupCategorizationWarningBox = new javax.swing.JCheckBox();
|
||||||
|
|
||||||
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
|
|
||||||
@ -98,12 +100,13 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
infoIconLabel.setFont(infoIconLabel.getFont().deriveFont(infoIconLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
infoIconLabel.setFont(infoIconLabel.getFont().deriveFont(infoIconLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
infoIconLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"))); // NOI18N
|
infoIconLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/info-icon-16.png"))); // NOI18N
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(infoIconLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.infoIconLabel.text")); // NOI18N
|
|
||||||
|
|
||||||
unavailableDuringInjestLabel.setFont(unavailableDuringInjestLabel.getFont().deriveFont(unavailableDuringInjestLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
unavailableDuringInjestLabel.setFont(unavailableDuringInjestLabel.getFont().deriveFont(unavailableDuringInjestLabel.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
unavailableDuringInjestLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/warning16.png"))); // NOI18N
|
unavailableDuringInjestLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/imagegallery/images/warning16.png"))); // NOI18N
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(unavailableDuringInjestLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.unavailableDuringInjestLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(unavailableDuringInjestLabel, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.unavailableDuringInjestLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(groupCategorizationWarningBox, NbBundle.getMessage(ImageGalleryOptionsPanel.class, "ImageGalleryOptionsPanel.groupCategorizationWarningBox.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -112,18 +115,23 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGap(21, 21, 21)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(unavailableDuringInjestLabel))
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
.addGap(21, 21, 21)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addComponent(unavailableDuringInjestLabel))
|
||||||
.addGap(21, 21, 21)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
.addComponent(infoIconLabel)
|
.addComponent(enabledByDefaultBox)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addComponent(enabledForCaseBox)
|
||||||
.addComponent(furtherDescriptionArea, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addComponent(descriptionLabel, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(enabledByDefaultBox)
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(enabledForCaseBox)
|
.addGap(21, 21, 21)
|
||||||
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(infoIconLabel)
|
||||||
.addContainerGap(46, Short.MAX_VALUE))
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(furtherDescriptionArea, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||||
|
.addComponent(groupCategorizationWarningBox))
|
||||||
|
.addGap(0, 36, Short.MAX_VALUE))
|
||||||
|
.addComponent(jSeparator1))
|
||||||
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -139,8 +147,12 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
.addGap(18, 18, 18)
|
.addGap(18, 18, 18)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(infoIconLabel)
|
.addComponent(infoIconLabel)
|
||||||
.addComponent(furtherDescriptionArea, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(furtherDescriptionArea, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addGap(45, 45, 45))
|
.addGap(18, 18, 18)
|
||||||
|
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(groupCategorizationWarningBox)
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@ -152,7 +164,6 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
// TODO add your handling code here:
|
// TODO add your handling code here:
|
||||||
}//GEN-LAST:event_enabledForCaseBoxActionPerformed
|
}//GEN-LAST:event_enabledForCaseBoxActionPerformed
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
void load() {
|
void load() {
|
||||||
enabledByDefaultBox.setSelected(ImageGalleryPreferences.isEnabledByDefault());
|
enabledByDefaultBox.setSelected(ImageGalleryPreferences.isEnabledByDefault());
|
||||||
if (Case.isCaseOpen() && IngestManager.getInstance().isIngestRunning() == false) {
|
if (Case.isCaseOpen() && IngestManager.getInstance().isIngestRunning() == false) {
|
||||||
@ -162,20 +173,21 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
enabledForCaseBox.setEnabled(false);
|
enabledForCaseBox.setEnabled(false);
|
||||||
enabledForCaseBox.setSelected(enabledByDefaultBox.isSelected());
|
enabledForCaseBox.setSelected(enabledByDefaultBox.isSelected());
|
||||||
}
|
}
|
||||||
|
groupCategorizationWarningBox.setSelected(ImageGalleryPreferences.isGroupCategorizationWarningDisabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc } */
|
|
||||||
void store() {
|
void store() {
|
||||||
ImageGalleryPreferences.setEnabledByDefault(enabledByDefaultBox.isSelected());
|
ImageGalleryPreferences.setEnabledByDefault(enabledByDefaultBox.isSelected());
|
||||||
ImageGalleryController.getDefault().setListeningEnabled(enabledForCaseBox.isSelected());
|
ImageGalleryController.getDefault().setListeningEnabled(enabledForCaseBox.isSelected());
|
||||||
if (Case.isCaseOpen()) {
|
if (Case.isCaseOpen()) {
|
||||||
new PerCaseProperties(Case.getCurrentCase()).setConfigSetting(ImageGalleryModule.getModuleName(), PerCaseProperties.ENABLED, Boolean.toString(enabledForCaseBox.isSelected()));
|
new PerCaseProperties(Case.getCurrentCase()).setConfigSetting(ImageGalleryModule.getModuleName(), PerCaseProperties.ENABLED, Boolean.toString(enabledForCaseBox.isSelected()));
|
||||||
}
|
}
|
||||||
|
ImageGalleryPreferences.setGroupCategorizationWarningDisabled(groupCategorizationWarningBox.isSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc }
|
/**
|
||||||
*
|
* @return true, since there is no way for this form to be invalid
|
||||||
* @return true, since there is no way for this form to be invalid */
|
*/
|
||||||
boolean valid() {
|
boolean valid() {
|
||||||
// TODO check whether form is consistent and complete
|
// TODO check whether form is consistent and complete
|
||||||
return true;
|
return true;
|
||||||
@ -186,7 +198,9 @@ final class ImageGalleryOptionsPanel extends javax.swing.JPanel {
|
|||||||
private javax.swing.JCheckBox enabledByDefaultBox;
|
private javax.swing.JCheckBox enabledByDefaultBox;
|
||||||
private javax.swing.JCheckBox enabledForCaseBox;
|
private javax.swing.JCheckBox enabledForCaseBox;
|
||||||
private javax.swing.JTextArea furtherDescriptionArea;
|
private javax.swing.JTextArea furtherDescriptionArea;
|
||||||
|
private javax.swing.JCheckBox groupCategorizationWarningBox;
|
||||||
private javax.swing.JLabel infoIconLabel;
|
private javax.swing.JLabel infoIconLabel;
|
||||||
|
private javax.swing.JSeparator jSeparator1;
|
||||||
private javax.swing.JLabel unavailableDuringInjestLabel;
|
private javax.swing.JLabel unavailableDuringInjestLabel;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013 Basis Technology Corp.
|
* Copyright 2013-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -22,14 +22,21 @@ import java.util.prefs.PreferenceChangeListener;
|
|||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
import org.openide.util.NbPreferences;
|
import org.openide.util.NbPreferences;
|
||||||
|
|
||||||
/** Persists Image Analyzer preference to a per user .properties file */
|
/**
|
||||||
class ImageGalleryPreferences {
|
* Persists Image Gallery preference to a per user .properties file
|
||||||
|
*/
|
||||||
|
public class ImageGalleryPreferences {
|
||||||
|
|
||||||
/** NBPreferences object used to persist settings */
|
/**
|
||||||
|
* NBPreferences object used to persist settings
|
||||||
|
*/
|
||||||
private static final Preferences preferences = NbPreferences.forModule(ImageGalleryPreferences.class);
|
private static final Preferences preferences = NbPreferences.forModule(ImageGalleryPreferences.class);
|
||||||
|
|
||||||
/** key for the listening enabled for new cases setting */
|
/**
|
||||||
|
* key for the listening enabled for new cases setting
|
||||||
|
*/
|
||||||
private static final String ENABLED_BY_DEFAULT = "enabled_by_default"; //NON-NLS
|
private static final String ENABLED_BY_DEFAULT = "enabled_by_default"; //NON-NLS
|
||||||
|
private static final String GROUP_CATEGORIZATION_WARNING_DISABLED = "group_categorization_warning_disabled"; //NON-NLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return setting of whether Image Analyzer should be automatically enabled
|
* Return setting of whether Image Analyzer should be automatically enabled
|
||||||
@ -38,15 +45,30 @@ class ImageGalleryPreferences {
|
|||||||
*
|
*
|
||||||
* @return true if new cases should have image analyzer enabled.
|
* @return true if new cases should have image analyzer enabled.
|
||||||
*/
|
*/
|
||||||
static boolean isEnabledByDefault() {
|
public static boolean isEnabledByDefault() {
|
||||||
final boolean aBoolean = preferences.getBoolean(ENABLED_BY_DEFAULT, true);
|
final boolean aBoolean = preferences.getBoolean(ENABLED_BY_DEFAULT, true);
|
||||||
return aBoolean;
|
return aBoolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setEnabledByDefault(boolean b) {
|
public static void setEnabledByDefault(boolean b) {
|
||||||
preferences.putBoolean(ENABLED_BY_DEFAULT, b);
|
preferences.putBoolean(ENABLED_BY_DEFAULT, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the warning about overwriting categories when acting on an
|
||||||
|
* entire group is disabled.
|
||||||
|
*
|
||||||
|
* @return true if the warning is disabled.
|
||||||
|
*/
|
||||||
|
public static boolean isGroupCategorizationWarningDisabled() {
|
||||||
|
final boolean aBoolean = preferences.getBoolean(GROUP_CATEGORIZATION_WARNING_DISABLED, false);
|
||||||
|
return aBoolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setGroupCategorizationWarningDisabled(boolean b) {
|
||||||
|
preferences.putBoolean(GROUP_CATEGORIZATION_WARNING_DISABLED, b);
|
||||||
|
}
|
||||||
|
|
||||||
static void addChangeListener(PreferenceChangeListener l) {
|
static void addChangeListener(PreferenceChangeListener l) {
|
||||||
preferences.addPreferenceChangeListener(l);
|
preferences.addPreferenceChangeListener(l);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,8 @@ public final class ImageGalleryTopComponent extends TopComponent implements Expl
|
|||||||
fullUIStack.getChildren().add(borderPane);
|
fullUIStack.getChildren().add(borderPane);
|
||||||
splitPane = new SplitPane();
|
splitPane = new SplitPane();
|
||||||
borderPane.setCenter(splitPane);
|
borderPane.setCenter(splitPane);
|
||||||
borderPane.setTop(Toolbar.getDefault(controller));
|
Toolbar toolbar = new Toolbar(controller);
|
||||||
|
borderPane.setTop(toolbar);
|
||||||
borderPane.setBottom(new StatusBar(controller));
|
borderPane.setBottom(new StatusBar(controller));
|
||||||
|
|
||||||
metaDataTable = new MetaDataPane(controller);
|
metaDataTable = new MetaDataPane(controller);
|
||||||
@ -168,6 +169,7 @@ public final class ImageGalleryTopComponent extends TopComponent implements Expl
|
|||||||
splitPane.setDividerPositions(0.1, 1.0);
|
splitPane.setDividerPositions(0.1, 1.0);
|
||||||
|
|
||||||
ImageGalleryController.getDefault().setStacks(fullUIStack, centralStack);
|
ImageGalleryController.getDefault().setStacks(fullUIStack, centralStack);
|
||||||
|
ImageGalleryController.getDefault().setToolbar(toolbar);
|
||||||
ImageGalleryController.getDefault().setShowTree(() -> tabPane.getSelectionModel().select(groupTree));
|
ImageGalleryController.getDefault().setShowTree(() -> tabPane.getSelectionModel().select(groupTree));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ public enum ThumbnailCache {
|
|||||||
* could not be generated
|
* could not be generated
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public Image get(DrawableFile<?> file) {
|
public Image get(DrawableFile file) {
|
||||||
try {
|
try {
|
||||||
return cache.get(file.getId(), () -> load(file));
|
return cache.get(file.getId(), () -> load(file));
|
||||||
} catch (UncheckedExecutionException | CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
|
} catch (UncheckedExecutionException | CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
|
||||||
@ -124,9 +124,9 @@ public enum ThumbnailCache {
|
|||||||
*
|
*
|
||||||
* @return an (possibly empty) optional containing a thumbnail
|
* @return an (possibly empty) optional containing a thumbnail
|
||||||
*/
|
*/
|
||||||
private Image load(DrawableFile<?> file) {
|
private Image load(DrawableFile file) {
|
||||||
|
|
||||||
if (FileTypeUtils.isGIF(file)) {
|
if (FileTypeUtils.isGIF(file.getAbstractFile())) {
|
||||||
//directly read gif to preserve potential animation,
|
//directly read gif to preserve potential animation,
|
||||||
//NOTE: not saved to disk!
|
//NOTE: not saved to disk!
|
||||||
return new Image(new BufferedInputStream(new ReadContentInputStream(file.getAbstractFile())), MAX_THUMBNAIL_SIZE, MAX_THUMBNAIL_SIZE, true, true);
|
return new Image(new BufferedInputStream(new ReadContentInputStream(file.getAbstractFile())), MAX_THUMBNAIL_SIZE, MAX_THUMBNAIL_SIZE, true, true);
|
||||||
@ -171,7 +171,7 @@ public enum ThumbnailCache {
|
|||||||
* @return a Optional containing a File to store the cached icon in or an
|
* @return a Optional containing a File to store the cached icon in or an
|
||||||
* empty optional if there was a problem.
|
* empty optional if there was a problem.
|
||||||
*/
|
*/
|
||||||
private static Optional<File> getCacheFile(DrawableFile<?> file) {
|
private static Optional<File> getCacheFile(DrawableFile file) {
|
||||||
try {
|
try {
|
||||||
return Optional.of(ImageUtils.getCachedThumbnailFile(file.getAbstractFile(), MAX_THUMBNAIL_SIZE));
|
return Optional.of(ImageUtils.getCachedThumbnailFile(file.getAbstractFile(), MAX_THUMBNAIL_SIZE));
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ public enum ThumbnailCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Image> getThumbnailTask(DrawableFile<?> file) {
|
public Task<Image> getThumbnailTask(DrawableFile file) {
|
||||||
final Image thumbnail = cache.getIfPresent(file.getId());
|
final Image thumbnail = cache.getIfPresent(file.getId());
|
||||||
if (thumbnail != null) {
|
if (thumbnail != null) {
|
||||||
return TaskUtils.taskFrom(() -> thumbnail);
|
return TaskUtils.taskFrom(() -> thumbnail);
|
||||||
|
@ -90,10 +90,10 @@ public class AddTagAction extends Action {
|
|||||||
DrawableTagsManager tagsManager = controller.getTagsManager();
|
DrawableTagsManager tagsManager = controller.getTagsManager();
|
||||||
for (Long fileID : selectedFiles) {
|
for (Long fileID : selectedFiles) {
|
||||||
try {
|
try {
|
||||||
final DrawableFile<?> file = controller.getFileFromId(fileID);
|
final DrawableFile file = controller.getFileFromId(fileID);
|
||||||
LOGGER.log(Level.INFO, "tagging {0} with {1} and comment {2}", new Object[]{file.getName(), tagName.getDisplayName(), comment}); //NON-NLS
|
LOGGER.log(Level.INFO, "tagging {0} with {1} and comment {2}", new Object[]{file.getName(), tagName.getDisplayName(), comment}); //NON-NLS
|
||||||
|
|
||||||
List<ContentTag> contentTags = tagsManager.getContentTagsByContent(file);
|
List<ContentTag> contentTags = tagsManager.getContentTags(file);
|
||||||
Optional<TagName> duplicateTagName = contentTags.stream()
|
Optional<TagName> duplicateTagName = contentTags.stream()
|
||||||
.map(ContentTag::getName)
|
.map(ContentTag::getName)
|
||||||
.filter(tagName::equals)
|
.filter(tagName::equals)
|
||||||
|
@ -76,7 +76,7 @@ public class CategorizeAction extends Action {
|
|||||||
this.selectedFileIDs = selectedFileIDs;
|
this.selectedFileIDs = selectedFileIDs;
|
||||||
this.createUndo = createUndo;
|
this.createUndo = createUndo;
|
||||||
setGraphic(cat.getGraphic());
|
setGraphic(cat.getGraphic());
|
||||||
setEventHandler(actionEvent -> addCatToFiles());
|
setEventHandler(actionEvent -> addCatToFiles(selectedFileIDs));
|
||||||
setAccelerator(new KeyCodeCombination(KeyCode.getKeyCode(Integer.toString(cat.getCategoryNumber()))));
|
setAccelerator(new KeyCodeCombination(KeyCode.getKeyCode(Integer.toString(cat.getCategoryNumber()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,10 @@ public class CategorizeAction extends Action {
|
|||||||
return new CategoryMenu(controller);
|
return new CategoryMenu(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCatToFiles() {
|
|
||||||
Logger.getAnonymousLogger().log(Level.INFO, "categorizing{0} as {1}", new Object[]{selectedFileIDs.toString(), cat.getDisplayName()}); //NON-NLS
|
final void addCatToFiles(Set<Long> ids) {
|
||||||
controller.queueDBWorkerTask(new CategorizeTask(selectedFileIDs, cat, createUndo));
|
Logger.getAnonymousLogger().log(Level.INFO, "categorizing{0} as {1}", new Object[]{ids.toString(), cat.getDisplayName()}); //NON-NLS
|
||||||
|
controller.queueDBWorkerTask(new CategorizeTask(ids, cat, createUndo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +113,7 @@ public class CategorizeAction extends Action {
|
|||||||
@NbBundle.Messages({"# {0} - fileID number",
|
@NbBundle.Messages({"# {0} - fileID number",
|
||||||
"CategorizeTask.errorUnable.msg=Unable to categorize {0}.",
|
"CategorizeTask.errorUnable.msg=Unable to categorize {0}.",
|
||||||
"CategorizeTask.errorUnable.title=Categorizing Error"})
|
"CategorizeTask.errorUnable.title=Categorizing Error"})
|
||||||
private class CategorizeTask extends ImageGalleryController.InnerTask {
|
private class CategorizeTask extends ImageGalleryController.BackgroundTask {
|
||||||
|
|
||||||
private final Set<Long> fileIDs;
|
private final Set<Long> fileIDs;
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ public class CategorizeAction extends Action {
|
|||||||
TagName catZeroTagName = categoryManager.getTagName(Category.ZERO);
|
TagName catZeroTagName = categoryManager.getTagName(Category.ZERO);
|
||||||
for (long fileID : fileIDs) {
|
for (long fileID : fileIDs) {
|
||||||
try {
|
try {
|
||||||
DrawableFile<?> file = controller.getFileFromId(fileID); //drawable db access
|
DrawableFile file = controller.getFileFromId(fileID); //drawable db access
|
||||||
if (createUndo) {
|
if (createUndo) {
|
||||||
Category oldCat = file.getCategory(); //drawable db access
|
Category oldCat = file.getCategory(); //drawable db access
|
||||||
TagName oldCatTagName = categoryManager.getTagName(oldCat);
|
TagName oldCatTagName = categoryManager.getTagName(oldCat);
|
||||||
@ -145,8 +146,8 @@ public class CategorizeAction extends Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<ContentTag> fileTags = tagsManager.getContentTagsByContent(file);
|
final List<ContentTag> fileTags = tagsManager.getContentTags(file);
|
||||||
if (tagName.equals(catZeroTagName)) {
|
if (tagName == categoryManager.getTagName(Category.ZERO)) {
|
||||||
// delete all cat tags for cat-0
|
// delete all cat tags for cat-0
|
||||||
fileTags.stream()
|
fileTags.stream()
|
||||||
.filter(tag -> CategoryManager.isCategoryTagName(tag.getName()))
|
.filter(tag -> CategoryManager.isCategoryTagName(tag.getName()))
|
||||||
@ -203,8 +204,8 @@ public class CategorizeAction extends Action {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
CategorizeAction categorizeAction = new CategorizeAction(controller, newCategory, this.oldCategories.keySet(), false);
|
new CategorizeAction(controller, newCategory, this.oldCategories.keySet(), false)
|
||||||
categorizeAction.addCatToFiles();
|
.handle(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,7 +217,7 @@ public class CategorizeAction extends Action {
|
|||||||
|
|
||||||
for (Map.Entry<Long, Category> entry : oldCategories.entrySet()) {
|
for (Map.Entry<Long, Category> entry : oldCategories.entrySet()) {
|
||||||
new CategorizeAction(controller, entry.getValue(), Collections.singleton(entry.getKey()), false)
|
new CategorizeAction(controller, entry.getValue(), Collections.singleton(entry.getKey()), false)
|
||||||
.addCatToFiles();
|
.handle(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,110 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.imagegallery.actions;
|
package org.sleuthkit.autopsy.imagegallery.actions;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.geometry.Orientation;
|
||||||
|
import javafx.geometry.VPos;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.ButtonBar;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.CheckBox;
|
||||||
|
import javafx.scene.control.ContentDisplay;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Separator;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryPreferences;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* An action that categorizes all the files in the currently active group with
|
||||||
|
* the given category.
|
||||||
*/
|
*/
|
||||||
public class CategorizeGroupAction extends CategorizeAction {
|
public class CategorizeGroupAction extends CategorizeAction {
|
||||||
|
|
||||||
public CategorizeGroupAction(Category cat, ImageGalleryController controller) {
|
private final static Logger LOGGER = Logger.getLogger(CategorizeGroupAction.class.getName());
|
||||||
super(controller, cat, new HashSet<>(controller.viewState().get().getGroup().getFileIDs()));
|
|
||||||
|
public CategorizeGroupAction(Category newCat, ImageGalleryController controller) {
|
||||||
|
super(controller, newCat, null);
|
||||||
|
setEventHandler(actionEvent -> {
|
||||||
|
ObservableList<Long> fileIDs = controller.viewState().get().getGroup().getFileIDs();
|
||||||
|
|
||||||
|
if (ImageGalleryPreferences.isGroupCategorizationWarningDisabled()) {
|
||||||
|
//if they have preveiously disabled the warning, just go ahead and apply categories.
|
||||||
|
addCatToFiles(ImmutableSet.copyOf(fileIDs));
|
||||||
|
} else {
|
||||||
|
final Map<Category, Long> catCountMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (Long fileID : fileIDs) {
|
||||||
|
try {
|
||||||
|
Category category = controller.getFileFromId(fileID).getCategory();
|
||||||
|
if (false == Category.ZERO.equals(category) && newCat.equals(category) == false) {
|
||||||
|
catCountMap.merge(category, 1L, Long::sum);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Failed to categorize files.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (catCountMap.isEmpty()) {
|
||||||
|
//if there are not going to be any categories overwritten, skip the warning.
|
||||||
|
addCatToFiles(ImmutableSet.copyOf(fileIDs));
|
||||||
|
} else {
|
||||||
|
showConfirmationDialog(catCountMap, newCat, fileIDs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({"CategorizeGroupAction.OverwriteButton.text=Overwrite",
|
||||||
|
"# {0} - number of files with the category", "# {1} - the name of the category",
|
||||||
|
"CategorizeGroupAction.fileCountMessage={0} with {1}",
|
||||||
|
"CategorizeGroupAction.dontShowAgain=Don't show this message again",
|
||||||
|
"CategorizeGroupAction.fileCountHeader=Files in the following categories will have their categories overwritten: "})
|
||||||
|
private void showConfirmationDialog(final Map<Category, Long> catCountMap, Category newCat, ObservableList<Long> fileIDs) {
|
||||||
|
|
||||||
|
ButtonType categorizeButtonType =
|
||||||
|
new ButtonType(Bundle.CategorizeGroupAction_OverwriteButton_text(), ButtonBar.ButtonData.APPLY);
|
||||||
|
|
||||||
|
VBox textFlow = new VBox();
|
||||||
|
|
||||||
|
for (Map.Entry<Category, Long> entry : catCountMap.entrySet()) {
|
||||||
|
if (entry.getKey().equals(newCat) == false) {
|
||||||
|
if (entry.getValue() > 0) {
|
||||||
|
Label label = new Label(Bundle.CategorizeGroupAction_fileCountMessage(entry.getValue(), entry.getKey().getDisplayName()),
|
||||||
|
entry.getKey().getGraphic());
|
||||||
|
label.setContentDisplay(ContentDisplay.RIGHT);
|
||||||
|
textFlow.getChildren().add(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckBox checkBox = new CheckBox(Bundle.CategorizeGroupAction_dontShowAgain());
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "", categorizeButtonType, ButtonType.CANCEL); //NON-NLS
|
||||||
|
Separator separator = new Separator(Orientation.HORIZONTAL);
|
||||||
|
separator.setPrefHeight(30);
|
||||||
|
separator.setValignment(VPos.BOTTOM);
|
||||||
|
VBox.setVgrow(separator, Priority.ALWAYS);
|
||||||
|
VBox vBox = new VBox(5, textFlow, separator, checkBox);
|
||||||
|
alert.getDialogPane().setContent(vBox);
|
||||||
|
alert.setHeaderText(Bundle.CategorizeGroupAction_fileCountHeader());
|
||||||
|
alert.showAndWait()
|
||||||
|
.filter(categorizeButtonType::equals)
|
||||||
|
.ifPresent(button -> {
|
||||||
|
//if they accept the overwrites, then apply them.
|
||||||
|
addCatToFiles(ImmutableSet.copyOf(fileIDs));
|
||||||
|
if (checkBox.isSelected()) {
|
||||||
|
//do we want to save this even on cancel also?
|
||||||
|
ImageGalleryPreferences.setGroupCategorizationWarningDisabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.Category;
|
|||||||
public class CategorizeSelectedFilesAction extends CategorizeAction {
|
public class CategorizeSelectedFilesAction extends CategorizeAction {
|
||||||
|
|
||||||
public CategorizeSelectedFilesAction(Category cat, ImageGalleryController controller) {
|
public CategorizeSelectedFilesAction(Category cat, ImageGalleryController controller) {
|
||||||
super(controller, cat, controller.getSelectionModel().getSelected());
|
super(controller, cat, null);
|
||||||
|
setEventHandler(actionEvent ->
|
||||||
|
addCatToFiles(controller.getSelectionModel().getSelected())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public class DeleteFollowUpTagAction extends Action {
|
|||||||
private static final Logger LOGGER = Logger.getLogger(DeleteFollowUpTagAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(DeleteFollowUpTagAction.class.getName());
|
||||||
|
|
||||||
@NbBundle.Messages("DeleteFollwUpTagAction.displayName=Delete Follow Up Tag")
|
@NbBundle.Messages("DeleteFollwUpTagAction.displayName=Delete Follow Up Tag")
|
||||||
public DeleteFollowUpTagAction(final ImageGalleryController controller, final DrawableFile<?> file) {
|
public DeleteFollowUpTagAction(final ImageGalleryController controller, final DrawableFile file) {
|
||||||
super(Bundle.DeleteFollwUpTagAction_displayName());
|
super(Bundle.DeleteFollwUpTagAction_displayName());
|
||||||
setEventHandler((ActionEvent t) -> {
|
setEventHandler((ActionEvent t) -> {
|
||||||
new SwingWorker<Void, Void>() {
|
new SwingWorker<Void, Void>() {
|
||||||
@ -52,7 +52,7 @@ public class DeleteFollowUpTagAction extends Action {
|
|||||||
try {
|
try {
|
||||||
final TagName followUpTagName = tagsManager.getFollowUpTagName();
|
final TagName followUpTagName = tagsManager.getFollowUpTagName();
|
||||||
|
|
||||||
List<ContentTag> contentTagsByContent = tagsManager.getContentTagsByContent(file);
|
List<ContentTag> contentTagsByContent = tagsManager.getContentTags(file);
|
||||||
for (ContentTag ct : contentTagsByContent) {
|
for (ContentTag ct : contentTagsByContent) {
|
||||||
if (ct.getName().getDisplayName().equals(followUpTagName.getDisplayName())) {
|
if (ct.getName().getDisplayName().equals(followUpTagName.getDisplayName())) {
|
||||||
tagsManager.deleteContentTag(ct);
|
tagsManager.deleteContentTag(ct);
|
||||||
|
@ -39,7 +39,7 @@ public class OpenExternalViewerAction extends Action {
|
|||||||
private static final Image EXTERNAL = new Image(OpenExternalViewerAction.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/external.png").toExternalForm()); //NON-NLS
|
private static final Image EXTERNAL = new Image(OpenExternalViewerAction.class.getResource("/org/sleuthkit/autopsy/imagegallery/images/external.png").toExternalForm()); //NON-NLS
|
||||||
private static final ActionEvent ACTION_EVENT = new ActionEvent(OpenExternalViewerAction.class, ActionEvent.ACTION_PERFORMED, ""); //Swing ActionEvent //NOI18N
|
private static final ActionEvent ACTION_EVENT = new ActionEvent(OpenExternalViewerAction.class, ActionEvent.ACTION_PERFORMED, ""); //Swing ActionEvent //NOI18N
|
||||||
|
|
||||||
public OpenExternalViewerAction(DrawableFile<?> file) {
|
public OpenExternalViewerAction(DrawableFile file) {
|
||||||
super(Bundle.OpenExternalViewerAction_displayName());
|
super(Bundle.OpenExternalViewerAction_displayName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +28,10 @@ import org.sleuthkit.datamodel.TagName;
|
|||||||
public class TagGroupAction extends AddTagAction {
|
public class TagGroupAction extends AddTagAction {
|
||||||
|
|
||||||
public TagGroupAction(final TagName tagName, ImageGalleryController controller) {
|
public TagGroupAction(final TagName tagName, ImageGalleryController controller) {
|
||||||
super(controller, tagName, ImmutableSet.copyOf(controller.viewState().get().getGroup().getFileIDs()));
|
super(controller, tagName, null);
|
||||||
|
setEventHandler(actionEvent ->
|
||||||
|
new AddTagAction(controller, tagName, ImmutableSet.copyOf(controller.viewState().get().getGroup().getFileIDs())).
|
||||||
|
handle(actionEvent)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,10 @@ import org.sleuthkit.datamodel.TagName;
|
|||||||
public class TagSelectedFilesAction extends AddTagAction {
|
public class TagSelectedFilesAction extends AddTagAction {
|
||||||
|
|
||||||
public TagSelectedFilesAction(final TagName tagName, ImageGalleryController controller) {
|
public TagSelectedFilesAction(final TagName tagName, ImageGalleryController controller) {
|
||||||
super(controller, tagName, controller.getSelectionModel().getSelected());
|
super(controller, tagName, null);
|
||||||
|
setEventHandler(actionEvent ->
|
||||||
|
new AddTagAction(controller, tagName, controller.getSelectionModel().getSelected()).
|
||||||
|
handle(actionEvent)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ public class CategoryManager {
|
|||||||
final DrawableTagsManager tagsManager = controller.getTagsManager();
|
final DrawableTagsManager tagsManager = controller.getTagsManager();
|
||||||
try {
|
try {
|
||||||
//remove old category tag(s) if necessary
|
//remove old category tag(s) if necessary
|
||||||
for (ContentTag ct : tagsManager.getContentTagsByContent(addedTag.getContent())) {
|
for (ContentTag ct : tagsManager.getContentTags(addedTag.getContent())) {
|
||||||
if (ct.getId() != addedTag.getId()
|
if (ct.getId() != addedTag.getId()
|
||||||
&& CategoryManager.isCategoryTagName(ct.getName())) {
|
&& CategoryManager.isCategoryTagName(ct.getName())) {
|
||||||
try {
|
try {
|
||||||
|
@ -111,13 +111,13 @@ public class DrawableAttribute<T extends Comparable<T>> {
|
|||||||
new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(),
|
new DrawableAttribute<>(AttributeName.CREATED_TIME, Bundle.DrawableAttribute_createdTime(),
|
||||||
true,
|
true,
|
||||||
"clock--plus.png", //NON-NLS
|
"clock--plus.png", //NON-NLS
|
||||||
f -> Collections.singleton(ContentUtils.getStringTime(f.getCrtime(), f)));
|
f -> Collections.singleton(ContentUtils.getStringTime(f.getCrtime(), f.getAbstractFile())));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MODIFIED_TIME =
|
public final static DrawableAttribute<String> MODIFIED_TIME =
|
||||||
new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(),
|
new DrawableAttribute<>(AttributeName.MODIFIED_TIME, Bundle.DrawableAttribute_modifiedTime(),
|
||||||
true,
|
true,
|
||||||
"clock--pencil.png", //NON-NLS
|
"clock--pencil.png", //NON-NLS
|
||||||
f -> Collections.singleton(ContentUtils.getStringTime(f.getMtime(), f)));
|
f -> Collections.singleton(ContentUtils.getStringTime(f.getMtime(), f.getAbstractFile())));
|
||||||
|
|
||||||
public final static DrawableAttribute<String> MAKE =
|
public final static DrawableAttribute<String> MAKE =
|
||||||
new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(),
|
new DrawableAttribute<>(AttributeName.MAKE, Bundle.DrawableAttribute_cameraMake(),
|
||||||
@ -168,9 +168,9 @@ public class DrawableAttribute<T extends Comparable<T>> {
|
|||||||
Arrays.asList(NAME, ANALYZED, CATEGORY, TAGS, PATH, CREATED_TIME,
|
Arrays.asList(NAME, ANALYZED, CATEGORY, TAGS, PATH, CREATED_TIME,
|
||||||
MODIFIED_TIME, MD5_HASH, HASHSET, MAKE, MODEL, OBJ_ID, WIDTH, HEIGHT, MIME_TYPE);
|
MODIFIED_TIME, MD5_HASH, HASHSET, MAKE, MODEL, OBJ_ID, WIDTH, HEIGHT, MIME_TYPE);
|
||||||
|
|
||||||
private final Function<DrawableFile<?>, Collection<T>> extractor;
|
private final Function<DrawableFile, Collection<T>> extractor;
|
||||||
|
|
||||||
private DrawableAttribute(AttributeName name, String displayName, Boolean isDBColumn, String imageName, Function<DrawableFile<?>, Collection<T>> extractor) {
|
private DrawableAttribute(AttributeName name, String displayName, Boolean isDBColumn, String imageName, Function<DrawableFile, Collection<T>> extractor) {
|
||||||
this.attrName = name;
|
this.attrName = name;
|
||||||
this.displayName = new ReadOnlyStringWrapper(displayName);
|
this.displayName = new ReadOnlyStringWrapper(displayName);
|
||||||
this.isDBColumn = isDBColumn;
|
this.isDBColumn = isDBColumn;
|
||||||
@ -223,7 +223,7 @@ public class DrawableAttribute<T extends Comparable<T>> {
|
|||||||
return displayName.get();
|
return displayName.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<T> getValue(DrawableFile<?> f) {
|
public Collection<T> getValue(DrawableFile f) {
|
||||||
return extractor.apply(f);
|
return extractor.apply(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,9 +497,9 @@ public final class DrawableDB {
|
|||||||
ArrayList<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, fileID);
|
ArrayList<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, fileID);
|
||||||
|
|
||||||
for (BlackboardArtifact a : artifacts) {
|
for (BlackboardArtifact a : artifacts) {
|
||||||
List<BlackboardAttribute> attributes = a.getAttributes(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
|
BlackboardAttribute attribute = a.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
|
||||||
for (BlackboardAttribute attr : attributes) {
|
if (attribute != null) {
|
||||||
hashNames.add(attr.getValueString());
|
hashNames.add(attribute.getValueString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableSet(hashNames);
|
return Collections.unmodifiableSet(hashNames);
|
||||||
@ -569,23 +569,23 @@ public final class DrawableDB {
|
|||||||
return removeFile;
|
return removeFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFile(DrawableFile<?> f) {
|
public void updateFile(DrawableFile f) {
|
||||||
DrawableTransaction trans = beginTransaction();
|
DrawableTransaction trans = beginTransaction();
|
||||||
updateFile(f, trans);
|
updateFile(f, trans);
|
||||||
commitTransaction(trans, true);
|
commitTransaction(trans, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertFile(DrawableFile<?> f) {
|
public void insertFile(DrawableFile f) {
|
||||||
DrawableTransaction trans = beginTransaction();
|
DrawableTransaction trans = beginTransaction();
|
||||||
insertFile(f, trans);
|
insertFile(f, trans);
|
||||||
commitTransaction(trans, true);
|
commitTransaction(trans, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertFile(DrawableFile<?> f, DrawableTransaction tr) {
|
public void insertFile(DrawableFile f, DrawableTransaction tr) {
|
||||||
insertOrUpdateFile(f, tr, insertFileStmt);
|
insertOrUpdateFile(f, tr, insertFileStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFile(DrawableFile<?> f, DrawableTransaction tr) {
|
public void updateFile(DrawableFile f, DrawableTransaction tr) {
|
||||||
insertOrUpdateFile(f, tr, updateFileStmt);
|
insertOrUpdateFile(f, tr, updateFileStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +602,7 @@ public final class DrawableDB {
|
|||||||
* @param tr a transaction to use, must not be null
|
* @param tr a transaction to use, must not be null
|
||||||
* @param stmt the statement that does the actull inserting
|
* @param stmt the statement that does the actull inserting
|
||||||
*/
|
*/
|
||||||
private void insertOrUpdateFile(DrawableFile<?> f, @Nonnull DrawableTransaction tr, @Nonnull PreparedStatement stmt) {
|
private void insertOrUpdateFile(DrawableFile f, @Nonnull DrawableTransaction tr, @Nonnull PreparedStatement stmt) {
|
||||||
|
|
||||||
if (tr.isClosed()) {
|
if (tr.isClosed()) {
|
||||||
throw new IllegalArgumentException("can't update database with closed transaction");
|
throw new IllegalArgumentException("can't update database with closed transaction");
|
||||||
@ -686,7 +686,7 @@ public final class DrawableDB {
|
|||||||
tr.commit(notify);
|
tr.commit(notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isFileAnalyzed(DrawableFile<?> f) {
|
public Boolean isFileAnalyzed(DrawableFile f) {
|
||||||
return isFileAnalyzed(f.getId());
|
return isFileAnalyzed(f.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,7 +979,7 @@ public final class DrawableDB {
|
|||||||
* @throws TskCoreException if unable to get a file from the currently open
|
* @throws TskCoreException if unable to get a file from the currently open
|
||||||
* {@link SleuthkitCase}
|
* {@link SleuthkitCase}
|
||||||
*/
|
*/
|
||||||
private DrawableFile<?> getFileFromID(Long id, boolean analyzed) throws TskCoreException {
|
private DrawableFile getFileFromID(Long id, boolean analyzed) throws TskCoreException {
|
||||||
try {
|
try {
|
||||||
AbstractFile f = tskCase.getAbstractFileById(id);
|
AbstractFile f = tskCase.getAbstractFileById(id);
|
||||||
return DrawableFile.create(f, analyzed, isVideoFile(f));
|
return DrawableFile.create(f, analyzed, isVideoFile(f));
|
||||||
@ -997,7 +997,7 @@ public final class DrawableDB {
|
|||||||
* @throws TskCoreException if unable to get a file from the currently open
|
* @throws TskCoreException if unable to get a file from the currently open
|
||||||
* {@link SleuthkitCase}
|
* {@link SleuthkitCase}
|
||||||
*/
|
*/
|
||||||
public DrawableFile<?> getFileFromID(Long id) throws TskCoreException {
|
public DrawableFile getFileFromID(Long id) throws TskCoreException {
|
||||||
try {
|
try {
|
||||||
AbstractFile f = tskCase.getAbstractFileById(id);
|
AbstractFile f = tskCase.getAbstractFileById(id);
|
||||||
return DrawableFile.create(f,
|
return DrawableFile.create(f,
|
||||||
@ -1242,8 +1242,8 @@ public final class DrawableDB {
|
|||||||
String fileIdsList = "(" + StringUtils.join(fileIDs, ",") + " )";
|
String fileIdsList = "(" + StringUtils.join(fileIDs, ",") + " )";
|
||||||
|
|
||||||
//count the fileids that are in the given list and don't have a non-zero category assigned to them.
|
//count the fileids that are in the given list and don't have a non-zero category assigned to them.
|
||||||
String name =
|
String name
|
||||||
"SELECT COUNT(obj_id) FROM tsk_files where obj_id IN " + fileIdsList //NON-NLS
|
= "SELECT COUNT(obj_id) FROM tsk_files where obj_id IN " + fileIdsList //NON-NLS
|
||||||
+ " AND obj_id NOT IN (SELECT obj_id FROM content_tags WHERE content_tags.tag_name_id IN " + catTagNameIDs + ")"; //NON-NLS
|
+ " AND obj_id NOT IN (SELECT obj_id FROM content_tags WHERE content_tags.tag_name_id IN " + catTagNameIDs + ")"; //NON-NLS
|
||||||
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(name);
|
try (SleuthkitCase.CaseDbQuery executeQuery = controller.getSleuthKitCase().executeQuery(name);
|
||||||
ResultSet resultSet = executeQuery.getResultSet();) {
|
ResultSet resultSet = executeQuery.getResultSet();) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-15 Basis Technology Corp.
|
* Copyright 2011-2016 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,6 +19,7 @@
|
|||||||
package org.sleuthkit.autopsy.imagegallery.datamodel;
|
package org.sleuthkit.autopsy.imagegallery.datamodel;
|
||||||
|
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -42,39 +43,36 @@ import org.sleuthkit.autopsy.imagegallery.ThumbnailCache;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.utils.TaskUtils;
|
import org.sleuthkit.autopsy.imagegallery.utils.TaskUtils;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
import org.sleuthkit.datamodel.ContentVisitor;
|
import org.sleuthkit.datamodel.ContentTag;
|
||||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.SleuthkitItemVisitor;
|
|
||||||
import org.sleuthkit.datamodel.Tag;
|
import org.sleuthkit.datamodel.Tag;
|
||||||
import org.sleuthkit.datamodel.TagName;
|
import org.sleuthkit.datamodel.TagName;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @TODO: There is something I don't understand or have done wrong about
|
* A file that contains visual information such as an image or video.
|
||||||
* implementing this class,as it is unreadable by
|
|
||||||
* {@link ReadContentInputStream}. As a work around we keep a reference to the
|
|
||||||
* original {@link AbstractFile} to use when reading the image. -jm
|
|
||||||
*/
|
*/
|
||||||
public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile {
|
public abstract class DrawableFile {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(DrawableFile.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(DrawableFile.class.getName());
|
||||||
|
|
||||||
public static DrawableFile<?> create(AbstractFile abstractFileById, boolean analyzed) {
|
public static DrawableFile create(AbstractFile abstractFileById, boolean analyzed) {
|
||||||
return create(abstractFileById, analyzed, FileTypeUtils.isVideoFile(abstractFileById));
|
return create(abstractFileById, analyzed, FileTypeUtils.isVideoFile(abstractFileById));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skip the database query if we have already determined the file type.
|
* Skip the database query if we have already determined the file type.
|
||||||
*/
|
*/
|
||||||
public static DrawableFile<?> create(AbstractFile abstractFileById, boolean analyzed, boolean isVideo) {
|
public static DrawableFile create(AbstractFile abstractFileById, boolean analyzed, boolean isVideo) {
|
||||||
return isVideo
|
return isVideo
|
||||||
? new VideoFile<>(abstractFileById, analyzed)
|
? new VideoFile(abstractFileById, analyzed)
|
||||||
: new ImageFile<>(abstractFileById, analyzed);
|
: new ImageFile(abstractFileById, analyzed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DrawableFile<?> create(Long id, boolean analyzed) throws TskCoreException, IllegalStateException {
|
public static DrawableFile create(Long id, boolean analyzed) throws TskCoreException, IllegalStateException {
|
||||||
return create(Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id), analyzed);
|
return create(Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id), analyzed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +80,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
|
|
||||||
private String drawablePath;
|
private String drawablePath;
|
||||||
|
|
||||||
private final T file;
|
private final AbstractFile file;
|
||||||
|
|
||||||
private final SimpleBooleanProperty analyzed;
|
private final SimpleBooleanProperty analyzed;
|
||||||
|
|
||||||
@ -92,89 +90,77 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
|
|
||||||
private String model;
|
private String model;
|
||||||
|
|
||||||
protected DrawableFile(T file, Boolean analyzed) {
|
protected DrawableFile(AbstractFile file, Boolean analyzed) {
|
||||||
/*
|
|
||||||
* @TODO: the two 'new Integer(0).shortValue()' values and null are
|
|
||||||
* placeholders because the super constructor expects values i can't get
|
|
||||||
* easily at the moment. I assume this is related to why
|
|
||||||
* ReadContentInputStream can't read from DrawableFiles.
|
|
||||||
*/
|
|
||||||
|
|
||||||
super(file.getSleuthkitCase(),
|
|
||||||
file.getId(),
|
|
||||||
file.getAttrType(),
|
|
||||||
file.getAttrId(),
|
|
||||||
file.getName(),
|
|
||||||
file.getType(),
|
|
||||||
file.getMetaAddr(),
|
|
||||||
(int) file.getMetaSeq(),
|
|
||||||
file.getDirType(),
|
|
||||||
file.getMetaType(),
|
|
||||||
null,
|
|
||||||
new Integer(0).shortValue(),
|
|
||||||
file.getSize(),
|
|
||||||
file.getCtime(),
|
|
||||||
file.getCrtime(),
|
|
||||||
file.getAtime(),
|
|
||||||
file.getMtime(),
|
|
||||||
new Integer(0).shortValue(),
|
|
||||||
file.getUid(),
|
|
||||||
file.getGid(),
|
|
||||||
file.getMd5Hash(),
|
|
||||||
file.getKnown(),
|
|
||||||
file.getParentPath(),
|
|
||||||
file.getMIMEType());
|
|
||||||
this.analyzed = new SimpleBooleanProperty(analyzed);
|
this.analyzed = new SimpleBooleanProperty(analyzed);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean isVideo();
|
public abstract boolean isVideo();
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRoot() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(SleuthkitItemVisitor<T> v) {
|
|
||||||
return file.accept(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(ContentVisitor<T> v) {
|
|
||||||
return file.accept(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Content> getChildren() throws TskCoreException {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Long> getChildrenIds() throws TskCoreException {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pair<DrawableAttribute<?>, Collection<?>>> getAttributesList() {
|
public List<Pair<DrawableAttribute<?>, Collection<?>>> getAttributesList() {
|
||||||
return DrawableAttribute.getValues().stream()
|
return DrawableAttribute.getValues().stream()
|
||||||
.map(this::makeAttributeValuePair)
|
.map(this::makeAttributeValuePair)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMIMEType() {
|
||||||
|
return file.getMIMEType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return file.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCtime() {
|
||||||
|
return file.getCtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCrtime() {
|
||||||
|
return file.getCrtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAtime() {
|
||||||
|
return file.getAtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMtime() {
|
||||||
|
return file.getMtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMd5Hash() {
|
||||||
|
return file.getMd5Hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return file.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAtimeAsDate() {
|
||||||
|
return file.getAtimeAsDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized String getUniquePath() throws TskCoreException {
|
||||||
|
return file.getUniquePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SleuthkitCase getSleuthkitCase() {
|
||||||
|
return file.getSleuthkitCase();
|
||||||
|
}
|
||||||
|
|
||||||
private Pair<DrawableAttribute<?>, Collection<?>> makeAttributeValuePair(DrawableAttribute<?> t) {
|
private Pair<DrawableAttribute<?>, Collection<?>> makeAttributeValuePair(DrawableAttribute<?> t) {
|
||||||
return new Pair<>(t, t.getValue(DrawableFile.this));
|
return new Pair<>(t, t.getValue(DrawableFile.this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getModel() {
|
public String getModel() {
|
||||||
if (model == null) {
|
if (model == null) {
|
||||||
model = WordUtils.capitalizeFully((String) getValueOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL));
|
model = WordUtils.capitalizeFully((String) getValueOfBBAttribute(ARTIFACT_TYPE.TSK_METADATA_EXIF, ATTRIBUTE_TYPE.TSK_DEVICE_MODEL));
|
||||||
}
|
}
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMake() {
|
public String getMake() {
|
||||||
if (make == null) {
|
if (make == null) {
|
||||||
make = WordUtils.capitalizeFully((String) getValueOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE));
|
make = WordUtils.capitalizeFully((String) getValueOfBBAttribute(ARTIFACT_TYPE.TSK_METADATA_EXIF, ATTRIBUTE_TYPE.TSK_DEVICE_MAKE));
|
||||||
}
|
}
|
||||||
return make;
|
return make;
|
||||||
}
|
}
|
||||||
@ -182,18 +168,18 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
public Set<TagName> getTagNames() {
|
public Set<TagName> getTagNames() {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return getSleuthkitCase().getContentTagsByContent(this).stream()
|
return getContentTags().stream()
|
||||||
.map(Tag::getName)
|
.map(Tag::getName)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName(), ex); //NON-NLS
|
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName(), ex); //NON-NLS
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "there is no case open; failed to look up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName()); //NON-NLS
|
Logger.getAnonymousLogger().log(Level.WARNING, "there is no case open; failed to look up " + DrawableAttribute.TAGS.getDisplayName() + " for " + getContentPathSafe(), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object getValueOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE artType, BlackboardAttribute.ATTRIBUTE_TYPE attrType) {
|
protected Object getValueOfBBAttribute(ARTIFACT_TYPE artType, ATTRIBUTE_TYPE attrType) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
//why doesn't file.getArtifacts() work?
|
//why doesn't file.getArtifacts() work?
|
||||||
@ -203,8 +189,8 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
for (BlackboardArtifact artf : artifacts) {
|
for (BlackboardArtifact artf : artifacts) {
|
||||||
if (artf.getArtifactTypeID() == artType.getTypeID()) {
|
if (artf.getArtifactTypeID() == artType.getTypeID()) {
|
||||||
for (BlackboardAttribute attr : artf.getAttributes()) {
|
for (BlackboardAttribute attr : artf.getAttributes()) {
|
||||||
if (attr.getAttributeTypeID() == attrType.getTypeID()) {
|
if (attr.getAttributeType().getTypeID() == attrType.getTypeID()) {
|
||||||
switch (attr.getValueType()) {
|
switch (attr.getAttributeType().getValueType()) {
|
||||||
case BYTE:
|
case BYTE:
|
||||||
return attr.getValueBytes();
|
return attr.getValueBytes();
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
@ -223,7 +209,8 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up {0}/{1}" + " " + " for {2}", new Object[]{artType.getDisplayName(), attrType.getDisplayName(), getName()}); //NON-NLS
|
Logger.getAnonymousLogger().log(Level.WARNING, ex,
|
||||||
|
() -> MessageFormat.format("problem looking up {0}/{1}" + " " + " for {2}", new Object[]{artType.getDisplayName(), attrType.getDisplayName(), getContentPathSafe()})); //NON-NLS
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -247,7 +234,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
*/
|
*/
|
||||||
private void updateCategory() {
|
private void updateCategory() {
|
||||||
try {
|
try {
|
||||||
category.set(getSleuthkitCase().getContentTagsByContent(this).stream()
|
category.set(getContentTags().stream()
|
||||||
.map(Tag::getName).filter(CategoryManager::isCategoryTagName)
|
.map(Tag::getName).filter(CategoryManager::isCategoryTagName)
|
||||||
.map(TagName::getDisplayName)
|
.map(TagName::getDisplayName)
|
||||||
.map(Category::fromDisplayName)
|
.map(Category::fromDisplayName)
|
||||||
@ -255,12 +242,16 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
.orElse(Category.ZERO)
|
.orElse(Category.ZERO)
|
||||||
);
|
);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "problem looking up category for file " + this.getName() + ex.getLocalizedMessage()); //NON-NLS
|
LOGGER.log(Level.WARNING, "problem looking up category for " + this.getContentPathSafe(), ex); //NON-NLS
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// We get here many times if the case is closed during ingest, so don't print out a ton of warnings.
|
// We get here many times if the case is closed during ingest, so don't print out a ton of warnings.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ContentTag> getContentTags() throws TskCoreException {
|
||||||
|
return getSleuthkitCase().getContentTagsByContent(file);
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Image getThumbnail() {
|
public Image getThumbnail() {
|
||||||
try {
|
try {
|
||||||
@ -317,7 +308,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
return analyzed.get();
|
return analyzed.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getAbstractFile() {
|
public AbstractFile getAbstractFile() {
|
||||||
return this.file;
|
return this.file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,12 +324,16 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
drawablePath = StringUtils.removeEnd(getUniquePath(), getName());
|
drawablePath = StringUtils.removeEnd(getUniquePath(), getName());
|
||||||
return drawablePath;
|
return drawablePath;
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
LOGGER.log(Level.WARNING, "failed to get drawablePath from {0}", getName()); //NON-NLS
|
LOGGER.log(Level.WARNING, "failed to get drawablePath from " + getContentPathSafe(), ex); //NON-NLS
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getHashSetNames() throws TskCoreException {
|
||||||
|
return file.getHashSetNames();
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Set<String> getHashSetNamesUnchecked() {
|
public Set<String> getHashSetNamesUnchecked() {
|
||||||
try {
|
try {
|
||||||
@ -359,7 +354,7 @@ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile
|
|||||||
*/
|
*/
|
||||||
public String getContentPathSafe() {
|
public String getContentPathSafe() {
|
||||||
try {
|
try {
|
||||||
return this.getUniquePath();
|
return getUniquePath();
|
||||||
} catch (TskCoreException tskCoreException) {
|
} catch (TskCoreException tskCoreException) {
|
||||||
String contentName = this.getName();
|
String contentName = this.getName();
|
||||||
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NOI18N NON-NLS
|
LOGGER.log(Level.SEVERE, "Failed to get unique path for " + contentName, tskCoreException); //NOI18N NON-NLS
|
||||||
|
@ -185,21 +185,35 @@ public class DrawableTagsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets content tags count by content.
|
* Gets content tags by content.
|
||||||
*
|
*
|
||||||
* @param The content of interest.
|
* @param content The content of interest.
|
||||||
*
|
*
|
||||||
* @return A list, possibly empty, of the tags that have been applied to the
|
* @return A list, possibly empty, of the tags that have been applied to the
|
||||||
* artifact.
|
* content.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException if there was an error reading from the db
|
||||||
*/
|
*/
|
||||||
public List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException {
|
public List<ContentTag> getContentTags(Content content) throws TskCoreException {
|
||||||
synchronized (autopsyTagsManagerLock) {
|
synchronized (autopsyTagsManagerLock) {
|
||||||
return autopsyTagsManager.getContentTagsByContent(content);
|
return autopsyTagsManager.getContentTagsByContent(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets content tags by DrawableFile.
|
||||||
|
*
|
||||||
|
* @param drawable The DrawableFile of interest.
|
||||||
|
*
|
||||||
|
* @return A list, possibly empty, of the tags that have been applied to the
|
||||||
|
* DrawableFile.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException if there was an error reading from the db
|
||||||
|
*/
|
||||||
|
public List<ContentTag> getContentTags(DrawableFile drawable) throws TskCoreException {
|
||||||
|
return getContentTags(drawable.getAbstractFile());
|
||||||
|
}
|
||||||
|
|
||||||
public TagName getTagName(String displayName) throws TskCoreException {
|
public TagName getTagName(String displayName) throws TskCoreException {
|
||||||
synchronized (autopsyTagsManagerLock) {
|
synchronized (autopsyTagsManagerLock) {
|
||||||
try {
|
try {
|
||||||
@ -213,7 +227,7 @@ public class DrawableTagsManager {
|
|||||||
} catch (TagsManager.TagNameAlreadyExistsException ex) {
|
} catch (TagsManager.TagNameAlreadyExistsException ex) {
|
||||||
throw new TskCoreException("tagame exists but wasn't found", ex);
|
throw new TskCoreException("tagame exists but wasn't found", ex);
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException ex) {
|
} catch (NullPointerException | IllegalStateException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Case was closed out from underneath", ex); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Case was closed out from underneath", ex); //NON-NLS
|
||||||
throw new TskCoreException("Case was closed out from underneath", ex);
|
throw new TskCoreException("Case was closed out from underneath", ex);
|
||||||
}
|
}
|
||||||
@ -228,7 +242,7 @@ public class DrawableTagsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentTag addContentTag(DrawableFile<?> file, TagName tagName, String comment) throws TskCoreException {
|
public ContentTag addContentTag(DrawableFile file, TagName tagName, String comment) throws TskCoreException {
|
||||||
synchronized (autopsyTagsManagerLock) {
|
synchronized (autopsyTagsManagerLock) {
|
||||||
return autopsyTagsManager.addContentTag(file.getAbstractFile(), tagName, comment);
|
return autopsyTagsManager.addContentTag(file.getAbstractFile(), tagName, comment);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.imagegallery.datamodel;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
@ -31,17 +30,12 @@ import org.sleuthkit.datamodel.AbstractFile;
|
|||||||
* wrapper(/decorator?/adapter?) around {@link AbstractFile} and provides
|
* wrapper(/decorator?/adapter?) around {@link AbstractFile} and provides
|
||||||
* methods to get an thumbnail sized and a full sized {@link Image}.
|
* methods to get an thumbnail sized and a full sized {@link Image}.
|
||||||
*/
|
*/
|
||||||
public class ImageFile<T extends AbstractFile> extends DrawableFile<T> {
|
public class ImageFile extends DrawableFile {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ImageFile.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ImageFile.class.getName());
|
||||||
|
|
||||||
static {
|
ImageFile(AbstractFile f, Boolean analyzed) {
|
||||||
ImageIO.scanForPlugins();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageFile(T f, Boolean analyzed) {
|
|
||||||
super(f, analyzed);
|
super(f, analyzed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,13 +36,13 @@ import org.sleuthkit.autopsy.coreutils.VideoUtils;
|
|||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
|
||||||
public class VideoFile<T extends AbstractFile> extends DrawableFile<T> {
|
public class VideoFile extends DrawableFile {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(VideoFile.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(VideoFile.class.getName());
|
||||||
|
|
||||||
private static final Image VIDEO_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png"); //NON-NLS
|
private static final Image VIDEO_ICON = new Image("org/sleuthkit/autopsy/imagegallery/images/Clapperboard.png"); //NON-NLS
|
||||||
|
|
||||||
VideoFile(T file, Boolean analyzed) {
|
VideoFile(AbstractFile file, Boolean analyzed) {
|
||||||
super(file, analyzed);
|
super(file, analyzed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ public class GroupManager {
|
|||||||
* file is a part of
|
* file is a part of
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
synchronized public Set<GroupKey<?>> getGroupKeysForFile(DrawableFile<?> file) {
|
synchronized public Set<GroupKey<?>> getGroupKeysForFile(DrawableFile file) {
|
||||||
Set<GroupKey<?>> resultSet = new HashSet<>();
|
Set<GroupKey<?>> resultSet = new HashSet<>();
|
||||||
for (Comparable<?> val : groupBy.getValue(file)) {
|
for (Comparable<?> val : groupBy.getValue(file)) {
|
||||||
if (groupBy == DrawableAttribute.TAGS) {
|
if (groupBy == DrawableAttribute.TAGS) {
|
||||||
@ -194,7 +194,7 @@ public class GroupManager {
|
|||||||
synchronized public Set<GroupKey<?>> getGroupKeysForFileID(Long fileID) {
|
synchronized public Set<GroupKey<?>> getGroupKeysForFileID(Long fileID) {
|
||||||
try {
|
try {
|
||||||
if (nonNull(db)) {
|
if (nonNull(db)) {
|
||||||
DrawableFile<?> file = db.getFileFromID(fileID);
|
DrawableFile file = db.getFileFromID(fileID);
|
||||||
return getGroupKeysForFile(file);
|
return getGroupKeysForFile(file);
|
||||||
} else {
|
} else {
|
||||||
Logger.getLogger(GroupManager.class.getName()).log(Level.WARNING, "Failed to load file with id: {0} from database. There is no database assigned.", fileID); //NON-NLS
|
Logger.getLogger(GroupManager.class.getName()).log(Level.WARNING, "Failed to load file with id: {0} from database. There is no database assigned.", fileID); //NON-NLS
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import java.lang.*?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.geometry.*?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.ProgressBar?>
|
||||||
<?import javafx.scene.image.*?>
|
<?import javafx.scene.image.Image?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
|
||||||
<fx:root id="AnchorPane" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
<fx:root id="AnchorPane" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.AnchorPane" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
<children>
|
<children>
|
||||||
<BorderPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<BorderPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<right>
|
<right>
|
||||||
<HBox alignment="CENTER_RIGHT" prefHeight="-1.0" prefWidth="-1.0" BorderPane.alignment="CENTER_RIGHT">
|
<HBox alignment="CENTER_RIGHT" prefHeight="-1.0" prefWidth="-1.0" spacing="5.0" BorderPane.alignment="CENTER_RIGHT">
|
||||||
<children>
|
<children>
|
||||||
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="NEVER">
|
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="NEVER">
|
||||||
<children>
|
<children>
|
||||||
@ -18,7 +22,10 @@
|
|||||||
<Label id="fileUpdateLabel" fx:id="fileUpdateTaskLabel" alignment="CENTER" contentDisplay="CENTER" graphicTextGap="0.0" labelFor="$fileTaskProgresBar" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="-1.0" text="0 File Update Tasks" StackPane.alignment="CENTER">
|
<Label id="fileUpdateLabel" fx:id="fileUpdateTaskLabel" alignment="CENTER" contentDisplay="CENTER" graphicTextGap="0.0" labelFor="$fileTaskProgresBar" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="-1.0" text="0 File Update Tasks" StackPane.alignment="CENTER">
|
||||||
<StackPane.margin>
|
<StackPane.margin>
|
||||||
<Insets left="3.0" right="3.0" />
|
<Insets left="3.0" right="3.0" />
|
||||||
</StackPane.margin></Label>
|
</StackPane.margin>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
||||||
|
</padding></Label>
|
||||||
</children>
|
</children>
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets />
|
<Insets />
|
||||||
@ -27,10 +34,13 @@
|
|||||||
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="NEVER">
|
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="NEVER">
|
||||||
<children>
|
<children>
|
||||||
<ProgressBar fx:id="bgTaskProgressBar" maxHeight="-1.0" maxWidth="-1.0" minHeight="-Infinity" minWidth="-1.0" prefHeight="24.0" prefWidth="-1.0" progress="0.0" StackPane.alignment="CENTER" />
|
<ProgressBar fx:id="bgTaskProgressBar" maxHeight="-1.0" maxWidth="-1.0" minHeight="-Infinity" minWidth="-1.0" prefHeight="24.0" prefWidth="-1.0" progress="0.0" StackPane.alignment="CENTER" />
|
||||||
<Label fx:id="bgTaskLabel" alignment="CENTER" cache="false" contentDisplay="CENTER" disable="false" focusTraversable="false" labelFor="$uiTaskProgressBar" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="" StackPane.alignment="CENTER">
|
<Label fx:id="bgTaskLabel" alignment="CENTER" cache="false" contentDisplay="CENTER" disable="false" focusTraversable="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="" StackPane.alignment="CENTER">
|
||||||
<StackPane.margin>
|
<StackPane.margin>
|
||||||
<Insets left="3.0" right="3.0" />
|
<Insets left="3.0" right="3.0" />
|
||||||
</StackPane.margin></Label>
|
</StackPane.margin>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
||||||
|
</padding></Label>
|
||||||
</children>
|
</children>
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets right="5.0" />
|
<Insets right="5.0" />
|
||||||
@ -42,19 +52,6 @@
|
|||||||
</BorderPane.margin>
|
</BorderPane.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
</right>
|
</right>
|
||||||
<center>
|
|
||||||
<HBox>
|
|
||||||
<children>
|
|
||||||
<Label fx:id="statusLabel" maxWidth="-Infinity" minWidth="-Infinity" wrapText="true" BorderPane.alignment="CENTER" HBox.hgrow="ALWAYS">
|
|
||||||
<BorderPane.margin>
|
|
||||||
<Insets left="10.0" right="10.0" />
|
|
||||||
</BorderPane.margin>
|
|
||||||
<HBox.margin>
|
|
||||||
<Insets left="10.0" right="10.0" />
|
|
||||||
</HBox.margin></Label>
|
|
||||||
</children>
|
|
||||||
</HBox>
|
|
||||||
</center>
|
|
||||||
<left><Label fx:id="staleLabel" text="Some data may be out of date. Enable listening to ingest to update." BorderPane.alignment="CENTER">
|
<left><Label fx:id="staleLabel" text="Some data may be out of date. Enable listening to ingest to update." BorderPane.alignment="CENTER">
|
||||||
<graphic><ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
<graphic><ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-14 Basis Technology Corp.
|
* Copyright 2013-16 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -19,8 +19,6 @@
|
|||||||
package org.sleuthkit.autopsy.imagegallery.gui;
|
package org.sleuthkit.autopsy.imagegallery.gui;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
@ -38,21 +36,12 @@ public class StatusBar extends AnchorPane {
|
|||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ResourceBundle resources;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private URL location;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ProgressBar fileTaskProgresBar;
|
private ProgressBar fileTaskProgresBar;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label fileUpdateTaskLabel;
|
private Label fileUpdateTaskLabel;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Label statusLabel;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label bgTaskLabel;
|
private Label bgTaskLabel;
|
||||||
|
|
||||||
@ -64,31 +53,24 @@ public class StatusBar extends AnchorPane {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@NbBundle.Messages({"StatusBar.fileUpdateTaskLabel.text= File Update Tasks",
|
@NbBundle.Messages({"StatusBar.fileUpdateTaskLabel.text= File Update Tasks",
|
||||||
"StatusBar.bgTaskLabel.text=Regrouping",
|
"StatusBar.bgTaskLabel.text=Regrouping",
|
||||||
"StatuBar.toolTip=Some data may be out of date. Enable Image Gallery in Tools | Options | Image /Video Gallery , after ingest is complete to update the Image Gallery data."})
|
"StatuBar.toolTip=Some data may be out of date. Enable Image Gallery in Tools | Options | Image /Video Gallery , after ingest is complete to update the Image Gallery data."})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert fileTaskProgresBar != null : "fx:id=\"fileTaskProgresBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert fileTaskProgresBar != null : "fx:id=\"fileTaskProgresBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
assert fileUpdateTaskLabel != null : "fx:id=\"fileUpdateTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert fileUpdateTaskLabel != null : "fx:id=\"fileUpdateTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
assert statusLabel != null : "fx:id=\"statusLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
|
||||||
assert bgTaskLabel != null : "fx:id=\"bgTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert bgTaskLabel != null : "fx:id=\"bgTaskLabel\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
assert bgTaskProgressBar != null : "fx:id=\"bgTaskProgressBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
assert bgTaskProgressBar != null : "fx:id=\"bgTaskProgressBar\" was not injected: check your FXML file 'StatusBar.fxml'.";
|
||||||
|
|
||||||
fileUpdateTaskLabel.textProperty().bind(controller.getFileUpdateQueueSizeProperty().asString().concat(Bundle.StatusBar_fileUpdateTaskLabel_text()));//;setText(newSize.toString() + " File Update Tasks");
|
fileUpdateTaskLabel.textProperty().bind(controller.getDBTasksQueueSizeProperty().asString().concat(Bundle.StatusBar_fileUpdateTaskLabel_text()));
|
||||||
fileTaskProgresBar.progressProperty().bind(controller.getFileUpdateQueueSizeProperty().negate());
|
fileTaskProgresBar.progressProperty().bind(controller.getDBTasksQueueSizeProperty().negate());
|
||||||
// controller.getFileUpdateQueueSizeProperty().addListener((ov, oldSize, newSize) -> {
|
|
||||||
// Platform.runLater(() -> {
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
controller.regroupProgress().addListener((ov, oldSize, newSize) -> {
|
controller.regroupProgress().addListener((ov, oldSize, newSize) -> {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
if(controller.regroupProgress().lessThan(1.0).get()){
|
if (controller.regroupProgress().lessThan(1.0).get()) {
|
||||||
// Regrouping in progress
|
// Regrouping in progress
|
||||||
bgTaskProgressBar.progressProperty().setValue(-1.0);
|
bgTaskProgressBar.progressProperty().setValue(-1.0);
|
||||||
bgTaskLabel.setText(Bundle.StatusBar_bgTaskLabel_text());
|
bgTaskLabel.setText(Bundle.StatusBar_bgTaskLabel_text());
|
||||||
} else{
|
} else {
|
||||||
// Clear the progress bar
|
// Clear the progress bar
|
||||||
bgTaskProgressBar.progressProperty().setValue(0.0);
|
bgTaskProgressBar.progressProperty().setValue(0.0);
|
||||||
bgTaskLabel.setText("");
|
bgTaskLabel.setText("");
|
||||||
@ -96,10 +78,7 @@ public class StatusBar extends AnchorPane {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Platform.runLater(() -> staleLabel.setTooltip(new Tooltip(Bundle.StatuBar_toolTip())));
|
||||||
Platform.runLater(() -> {
|
|
||||||
staleLabel.setTooltip(new Tooltip(Bundle.StatuBar_toolTip()));
|
|
||||||
});
|
|
||||||
staleLabel.visibleProperty().bind(controller.stale());
|
staleLabel.visibleProperty().bind(controller.stale());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,14 +95,4 @@ public class StatusBar extends AnchorPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLabelText(final String newText) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
statusLabel.setText(newText);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLabeltext() {
|
|
||||||
return statusLabel.getText();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import javafx.application.Platform;
|
|||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.property.DoubleProperty;
|
import javafx.beans.property.DoubleProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.ComboBox;
|
import javafx.scene.control.ComboBox;
|
||||||
@ -35,8 +34,6 @@ import javafx.scene.control.MenuItem;
|
|||||||
import javafx.scene.control.Slider;
|
import javafx.scene.control.Slider;
|
||||||
import javafx.scene.control.SplitMenuButton;
|
import javafx.scene.control.SplitMenuButton;
|
||||||
import javafx.scene.control.ToolBar;
|
import javafx.scene.control.ToolBar;
|
||||||
import javax.swing.SortOrder;
|
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
@ -74,8 +71,6 @@ public class Toolbar extends ToolBar {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label groupByLabel;
|
private Label groupByLabel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label tagImageViewLabel;
|
private Label tagImageViewLabel;
|
||||||
|
|
||||||
@ -85,10 +80,6 @@ public class Toolbar extends ToolBar {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label thumbnailSizeLabel;
|
private Label thumbnailSizeLabel;
|
||||||
|
|
||||||
private static Toolbar instance;
|
|
||||||
|
|
||||||
private final SimpleObjectProperty<SortOrder> orderProperty = new SimpleObjectProperty<>(SortOrder.ASCENDING);
|
|
||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
private SortChooser<DrawableGroup, GroupSortBy> sortChooser;
|
private SortChooser<DrawableGroup, GroupSortBy> sortChooser;
|
||||||
|
|
||||||
@ -102,25 +93,18 @@ public class Toolbar extends ToolBar {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public DoubleProperty sizeSliderValue() {
|
public DoubleProperty thumbnailSizeProperty() {
|
||||||
return sizeSlider.valueProperty();
|
return sizeSlider.valueProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static synchronized public Toolbar getDefault(ImageGalleryController controller) {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new Toolbar(controller);
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@NbBundle.Messages({"Toolbar.groupByLabel=Group By:",
|
@NbBundle.Messages({"Toolbar.groupByLabel=Group By:",
|
||||||
"Toolbar.sortByLabel=Sort By:",
|
"Toolbar.sortByLabel=Sort By:",
|
||||||
"Toolbar.ascRadio=Ascending",
|
"Toolbar.ascRadio=Ascending",
|
||||||
"Toolbar.descRadio=Descending",
|
"Toolbar.descRadio=Descending",
|
||||||
"Toolbar.tagImageViewLabel=Tag Group's Files:",
|
"Toolbar.tagImageViewLabel=Tag Group's Files:",
|
||||||
"Toolbar.categoryImageViewLabel=Categorize Group's Files:",
|
"Toolbar.categoryImageViewLabel=Categorize Group's Files:",
|
||||||
"Toolbar.thumbnailSizeLabel=Thumbnail Size (px):"})
|
"Toolbar.thumbnailSizeLabel=Thumbnail Size (px):"})
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert catGroupMenuButton != null : "fx:id=\"catSelectedMenubutton\" was not injected: check your FXML file 'Toolbar.fxml'.";
|
assert catGroupMenuButton != null : "fx:id=\"catSelectedMenubutton\" was not injected: check your FXML file 'Toolbar.fxml'.";
|
||||||
assert groupByBox != null : "fx:id=\"groupByBox\" was not injected: check your FXML file 'Toolbar.fxml'.";
|
assert groupByBox != null : "fx:id=\"groupByBox\" was not injected: check your FXML file 'Toolbar.fxml'.";
|
||||||
@ -148,11 +132,6 @@ public class Toolbar extends ToolBar {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
groupByLabel.setText(Bundle.Toolbar_groupByLabel());
|
|
||||||
tagImageViewLabel.setText(Bundle.Toolbar_tagImageViewLabel());
|
|
||||||
categoryImageViewLabel.setText(Bundle.Toolbar_categoryImageViewLabel());
|
|
||||||
thumbnailSizeLabel.setText(Bundle.Toolbar_thumbnailSizeLabel());
|
|
||||||
|
|
||||||
CategorizeGroupAction cat5GroupAction = new CategorizeGroupAction(Category.FIVE, controller);
|
CategorizeGroupAction cat5GroupAction = new CategorizeGroupAction(Category.FIVE, controller);
|
||||||
catGroupMenuButton.setOnAction(cat5GroupAction);
|
catGroupMenuButton.setOnAction(cat5GroupAction);
|
||||||
catGroupMenuButton.setText(cat5GroupAction.getText());
|
catGroupMenuButton.setText(cat5GroupAction.getText());
|
||||||
@ -165,6 +144,11 @@ public class Toolbar extends ToolBar {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
groupByLabel.setText(Bundle.Toolbar_groupByLabel());
|
||||||
|
tagImageViewLabel.setText(Bundle.Toolbar_tagImageViewLabel());
|
||||||
|
categoryImageViewLabel.setText(Bundle.Toolbar_categoryImageViewLabel());
|
||||||
|
thumbnailSizeLabel.setText(Bundle.Toolbar_thumbnailSizeLabel());
|
||||||
|
|
||||||
groupByBox.setItems(FXCollections.observableList(DrawableAttribute.getGroupableAttrs()));
|
groupByBox.setItems(FXCollections.observableList(DrawableAttribute.getGroupableAttrs()));
|
||||||
groupByBox.getSelectionModel().select(DrawableAttribute.PATH);
|
groupByBox.getSelectionModel().select(DrawableAttribute.PATH);
|
||||||
groupByBox.getSelectionModel().selectedItemProperty().addListener(queryInvalidationListener);
|
groupByBox.getSelectionModel().selectedItemProperty().addListener(queryInvalidationListener);
|
||||||
@ -182,8 +166,6 @@ public class Toolbar extends ToolBar {
|
|||||||
queryInvalidationListener.invalidated(observable);
|
queryInvalidationListener.invalidated(observable);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sortChooser.sortOrderProperty().addListener(queryInvalidationListener);
|
sortChooser.sortOrderProperty().addListener(queryInvalidationListener);
|
||||||
sortChooser.setComparator(GroupSortBy.PRIORITY);
|
sortChooser.setComparator(GroupSortBy.PRIORITY);
|
||||||
getItems().add(1, sortChooser);
|
getItems().add(1, sortChooser);
|
||||||
@ -202,13 +184,11 @@ public class Toolbar extends ToolBar {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
groupByBox.getSelectionModel().select(DrawableAttribute.PATH);
|
groupByBox.getSelectionModel().select(DrawableAttribute.PATH);
|
||||||
// sortByBox.getSelectionModel().select(GroupSortBy.NONE);
|
|
||||||
// orderGroup.selectToggle(ascRadio);
|
|
||||||
sizeSlider.setValue(SIZE_SLIDER_DEFAULT);
|
sizeSlider.setValue(SIZE_SLIDER_DEFAULT);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Toolbar(ImageGalleryController controller) {
|
public Toolbar(ImageGalleryController controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
FXMLConstructor.construct(this, "Toolbar.fxml"); //NON-NLS
|
FXMLConstructor.construct(this, "Toolbar.fxml"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ public class VideoPlayer extends BorderPane {
|
|||||||
mp.seek(Duration.millis(timeSlider.getValue()));
|
mp.seek(Duration.millis(timeSlider.getValue()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final VideoFile<?> file;
|
private final VideoFile file;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@NbBundle.Messages({"# {0} - exception type",
|
@NbBundle.Messages({"# {0} - exception type",
|
||||||
@ -236,7 +236,7 @@ public class VideoPlayer extends BorderPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public VideoPlayer(MediaPlayer mp, VideoFile<?> file) {
|
public VideoPlayer(MediaPlayer mp, VideoFile file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.mp = mp;
|
this.mp = mp;
|
||||||
FXMLConstructor.construct(this, "MediaControl.fxml"); //NON-NLS
|
FXMLConstructor.construct(this, "MediaControl.fxml"); //NON-NLS
|
||||||
|
@ -31,13 +31,10 @@ import javafx.scene.image.Image;
|
|||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import org.openide.util.NbBundle;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
import org.sleuthkit.autopsy.imagegallery.FXMLConstructor;
|
||||||
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
import org.sleuthkit.autopsy.imagegallery.ImageGalleryController;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.DrawableFile;
|
||||||
import org.sleuthkit.autopsy.imagegallery.gui.Toolbar;
|
|
||||||
import org.sleuthkit.datamodel.AbstractContent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GUI component that represents a single image as a tile with an icon, a label,
|
* GUI component that represents a single image as a tile with an icon, a label,
|
||||||
@ -66,8 +63,8 @@ public class DrawableTile extends DrawableTileBase {
|
|||||||
setCache(true);
|
setCache(true);
|
||||||
setCacheHint(CacheHint.SPEED);
|
setCacheHint(CacheHint.SPEED);
|
||||||
nameLabel.prefWidthProperty().bind(imageView.fitWidthProperty());
|
nameLabel.prefWidthProperty().bind(imageView.fitWidthProperty());
|
||||||
imageView.fitHeightProperty().bind(Toolbar.getDefault(getController()).sizeSliderValue());
|
imageView.fitHeightProperty().bind(getController().thumbnailSizeProperty());
|
||||||
imageView.fitWidthProperty().bind(Toolbar.getDefault(getController()).sizeSliderValue());
|
imageView.fitWidthProperty().bind(getController().thumbnailSizeProperty());
|
||||||
|
|
||||||
selectionModel.lastSelectedProperty().addListener(new WeakChangeListener<>(lastSelectionListener));
|
selectionModel.lastSelectedProperty().addListener(new WeakChangeListener<>(lastSelectionListener));
|
||||||
|
|
||||||
@ -108,12 +105,12 @@ public class DrawableTile extends DrawableTileBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Task<Image> newReadImageTask(DrawableFile<?> file) {
|
Task<Image> newReadImageTask(DrawableFile file) {
|
||||||
return file.getThumbnailTask();
|
return file.getThumbnailTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getTextForLabel() {
|
protected String getTextForLabel() {
|
||||||
return getFile().map(AbstractContent::getName).orElse("");
|
return getFile().map(DrawableFile::getName).orElse("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ public abstract class DrawableTileBase extends DrawableUIBase {
|
|||||||
t.consume();
|
t.consume();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContextMenu buildContextMenu(DrawableFile<?> file) {
|
private ContextMenu buildContextMenu(DrawableFile file) {
|
||||||
final ArrayList<MenuItem> menuItems = new ArrayList<>();
|
final ArrayList<MenuItem> menuItems = new ArrayList<>();
|
||||||
|
|
||||||
menuItems.add(CategorizeAction.getCategoriesMenu(getController()));
|
menuItems.add(CategorizeAction.getCategoriesMenu(getController()));
|
||||||
|
@ -66,7 +66,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
|
|
||||||
private final ImageGalleryController controller;
|
private final ImageGalleryController controller;
|
||||||
|
|
||||||
private Optional<DrawableFile<?>> fileOpt = Optional.empty();
|
private Optional<DrawableFile> fileOpt = Optional.empty();
|
||||||
|
|
||||||
private Optional<Long> fileIDOpt = Optional.empty();
|
private Optional<Long> fileIDOpt = Optional.empty();
|
||||||
private volatile Task<Image> imageTask;
|
private volatile Task<Image> imageTask;
|
||||||
@ -89,12 +89,12 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
this.fileIDOpt = fileIDOpt;
|
this.fileIDOpt = fileIDOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setFileOpt(Optional<DrawableFile<?>> fileOpt) {
|
synchronized void setFileOpt(Optional<DrawableFile> fileOpt) {
|
||||||
this.fileOpt = fileOpt;
|
this.fileOpt = fileOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
synchronized public Optional<DrawableFile<?>> getFile() {
|
synchronized public Optional<DrawableFile> getFile() {
|
||||||
if (fileIDOpt.isPresent()) {
|
if (fileIDOpt.isPresent()) {
|
||||||
if (fileOpt.isPresent() && fileOpt.get().getId() == fileIDOpt.get()) {
|
if (fileOpt.isPresent() && fileOpt.get().getId() == fileIDOpt.get()) {
|
||||||
return fileOpt;
|
return fileOpt;
|
||||||
@ -131,7 +131,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized Node doReadImageTask(DrawableFile<?> file) {
|
synchronized Node doReadImageTask(DrawableFile file) {
|
||||||
Task<Image> myTask = newReadImageTask(file);
|
Task<Image> myTask = newReadImageTask(file);
|
||||||
imageTask = myTask;
|
imageTask = myTask;
|
||||||
Node progressNode = newProgressIndicator(myTask);
|
Node progressNode = newProgressIndicator(myTask);
|
||||||
@ -191,7 +191,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private void showImage(DrawableFile<?> file, Task<Image> imageTask) {
|
private void showImage(DrawableFile file, Task<Image> imageTask) {
|
||||||
//Note that all error conditions are allready logged in readImageTask.succeeded()
|
//Note that all error conditions are allready logged in readImageTask.succeeded()
|
||||||
try {
|
try {
|
||||||
Image fxImage = imageTask.get();
|
Image fxImage = imageTask.get();
|
||||||
@ -210,7 +210,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
void showErrorNode(String errorMessage, DrawableFile<?> file) {
|
void showErrorNode(String errorMessage, DrawableFile file) {
|
||||||
Button createButton = ActionUtils.createButton(new OpenExternalViewerAction(file));
|
Button createButton = ActionUtils.createButton(new OpenExternalViewerAction(file));
|
||||||
|
|
||||||
VBox vBox = new VBox(10, new Label(errorMessage), createButton);
|
VBox vBox = new VBox(10, new Label(errorMessage), createButton);
|
||||||
@ -218,5 +218,5 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView
|
|||||||
imageBorder.setCenter(vBox);
|
imageBorder.setCenter(vBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Task<Image> newReadImageTask(DrawableFile<?> file);
|
abstract Task<Image> newReadImageTask(DrawableFile file);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public interface DrawableView {
|
|||||||
|
|
||||||
Region getCategoryBorderRegion();
|
Region getCategoryBorderRegion();
|
||||||
|
|
||||||
Optional<DrawableFile<?>> getFile();
|
Optional<DrawableFile> getFile();
|
||||||
|
|
||||||
void setFile(final Long fileID);
|
void setFile(final Long fileID);
|
||||||
|
|
||||||
|
@ -128,7 +128,6 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.DrawableGroup;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewMode;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewMode;
|
||||||
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewState;
|
import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupViewState;
|
||||||
import org.sleuthkit.autopsy.imagegallery.gui.GuiUtils;
|
import org.sleuthkit.autopsy.imagegallery.gui.GuiUtils;
|
||||||
import org.sleuthkit.autopsy.imagegallery.gui.Toolbar;
|
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -308,7 +307,7 @@ public class GroupPane extends BorderPane {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncCatToggle(DrawableFile<?> file) {
|
void syncCatToggle(DrawableFile file) {
|
||||||
getToggleForCategory(file.getCategory()).setSelected(true);
|
getToggleForCategory(file.getCategory()).setSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +417,7 @@ public class GroupPane extends BorderPane {
|
|||||||
flashAnimation.setAutoReverse(true);
|
flashAnimation.setAutoReverse(true);
|
||||||
|
|
||||||
//configure gridView cell properties
|
//configure gridView cell properties
|
||||||
DoubleBinding cellSize = Toolbar.getDefault(controller).sizeSliderValue().add(75);
|
DoubleBinding cellSize = controller.thumbnailSizeProperty().add(75);
|
||||||
gridView.cellHeightProperty().bind(cellSize);
|
gridView.cellHeightProperty().bind(cellSize);
|
||||||
gridView.cellWidthProperty().bind(cellSize);
|
gridView.cellWidthProperty().bind(cellSize);
|
||||||
gridView.setCellFactory((GridView<Long> param) -> new DrawableCell());
|
gridView.setCellFactory((GridView<Long> param) -> new DrawableCell());
|
||||||
|
@ -201,7 +201,7 @@ public class MetaDataPane extends DrawableUIBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Task<Image> newReadImageTask(DrawableFile<?> file) {
|
Task<Image> newReadImageTask(DrawableFile file) {
|
||||||
return file.getThumbnailTask();
|
return file.getThumbnailTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ import org.sleuthkit.autopsy.imagegallery.datamodel.VideoFile;
|
|||||||
import org.sleuthkit.autopsy.imagegallery.gui.VideoPlayer;
|
import org.sleuthkit.autopsy.imagegallery.gui.VideoPlayer;
|
||||||
import static org.sleuthkit.autopsy.imagegallery.gui.drawableviews.DrawableUIBase.exec;
|
import static org.sleuthkit.autopsy.imagegallery.gui.drawableviews.DrawableUIBase.exec;
|
||||||
import static org.sleuthkit.autopsy.imagegallery.gui.drawableviews.DrawableView.CAT_BORDER_WIDTH;
|
import static org.sleuthkit.autopsy.imagegallery.gui.drawableviews.DrawableView.CAT_BORDER_WIDTH;
|
||||||
import org.sleuthkit.datamodel.AbstractContent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the files of a group one at a time. Designed to be embedded in a
|
* Displays the files of a group one at a time. Designed to be embedded in a
|
||||||
@ -186,16 +185,16 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
synchronized protected void updateContent() {
|
synchronized protected void updateContent() {
|
||||||
disposeContent();
|
disposeContent();
|
||||||
if (getFile().isPresent()) {
|
if (getFile().isPresent()) {
|
||||||
DrawableFile<?> file = getFile().get();
|
DrawableFile file = getFile().get();
|
||||||
if (file.isVideo()) {
|
if (file.isVideo()) {
|
||||||
doMediaLoadTask((VideoFile<?>) file);
|
doMediaLoadTask((VideoFile) file);
|
||||||
} else {
|
} else {
|
||||||
doReadImageTask(file);
|
doReadImageTask(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized private Node doMediaLoadTask(VideoFile<?> file) {
|
synchronized private Node doMediaLoadTask(VideoFile file) {
|
||||||
|
|
||||||
//specially handling for videos
|
//specially handling for videos
|
||||||
MediaLoadTask myTask = new MediaLoadTask(file);
|
MediaLoadTask myTask = new MediaLoadTask(file);
|
||||||
@ -225,7 +224,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private void showMedia(DrawableFile<?> file, Task<Node> mediaTask) {
|
private void showMedia(DrawableFile file, Task<Node> mediaTask) {
|
||||||
//Note that all error conditions are allready logged in readImageTask.succeeded()
|
//Note that all error conditions are allready logged in readImageTask.succeeded()
|
||||||
try {
|
try {
|
||||||
Node mediaNode = mediaTask.get();
|
Node mediaNode = mediaTask.get();
|
||||||
@ -265,7 +264,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getTextForLabel() {
|
protected String getTextForLabel() {
|
||||||
return getFile().map(AbstractContent::getName).orElse("") + " " + getSupplementalText();
|
return getFile().map(DrawableFile::getName).orElse("") + " " + getSupplementalText();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -308,7 +307,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
@Override
|
@Override
|
||||||
@ThreadConfined(type = ThreadType.ANY)
|
@ThreadConfined(type = ThreadType.ANY)
|
||||||
public Category updateCategory() {
|
public Category updateCategory() {
|
||||||
Optional<DrawableFile<?>> file = getFile();
|
Optional<DrawableFile> file = getFile();
|
||||||
if (file.isPresent()) {
|
if (file.isPresent()) {
|
||||||
Category updateCategory = super.updateCategory();
|
Category updateCategory = super.updateCategory();
|
||||||
Platform.runLater(() -> getGroupPane().syncCatToggle(file.get()));
|
Platform.runLater(() -> getGroupPane().syncCatToggle(file.get()));
|
||||||
@ -319,7 +318,7 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Task<Image> newReadImageTask(DrawableFile<?> file) {
|
Task<Image> newReadImageTask(DrawableFile file) {
|
||||||
return file.getReadFullSizeImageTask();
|
return file.getReadFullSizeImageTask();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -328,9 +327,9 @@ public class SlideShowView extends DrawableTileBase {
|
|||||||
"MediaLoadTask.messageText=Reading video: {0}"})
|
"MediaLoadTask.messageText=Reading video: {0}"})
|
||||||
private class MediaLoadTask extends Task<Node> {
|
private class MediaLoadTask extends Task<Node> {
|
||||||
|
|
||||||
private final VideoFile<?> file;
|
private final VideoFile file;
|
||||||
|
|
||||||
MediaLoadTask(VideoFile<?> file) {
|
MediaLoadTask(VideoFile file) {
|
||||||
updateMessage(Bundle.MediaLoadTask_messageText(file.getName()));
|
updateMessage(Bundle.MediaLoadTask_messageText(file.getName()));
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
@ -274,9 +274,10 @@ public class ExtractedContentViewer implements DataContentViewer {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// Get the associated artifact attribute and return its value as the ID
|
// Get the associated artifact attribute and return its value as the ID
|
||||||
List<BlackboardAttribute> blackboardAttributes = artifact.getAttributes(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT);
|
BlackboardAttribute blackboardAttribute = artifact.getAttribute(
|
||||||
if (!blackboardAttributes.isEmpty()) {
|
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||||
return blackboardAttributes.get(0).getValueLong();
|
if (blackboardAttribute != null) {
|
||||||
|
return blackboardAttribute.getValueLong();
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting associated artifact attributes", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Error getting associated artifact attributes", ex); //NON-NLS
|
||||||
|
@ -52,12 +52,12 @@ class KeywordCachedArtifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void add(BlackboardAttribute attribute) {
|
void add(BlackboardAttribute attribute) {
|
||||||
attributes.put(attribute.getAttributeTypeID(), attribute);
|
attributes.put(attribute.getAttributeType().getTypeID(), attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(Collection<BlackboardAttribute> attributes) {
|
void add(Collection<BlackboardAttribute> attributes) {
|
||||||
for (BlackboardAttribute attr : attributes) {
|
for (BlackboardAttribute attr : attributes) {
|
||||||
this.attributes.put(attr.getAttributeTypeID(), attr);
|
this.attributes.put(attr.getAttributeType().getTypeID(), attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user