Merge remote-tracking branch 'upstream/develop' into TL-list-view

This commit is contained in:
Richard Cordovano 2016-05-27 13:08:19 -04:00
commit baef70a6bf
26 changed files with 637 additions and 522 deletions

View File

@ -58,7 +58,7 @@ the needed places (i.e. '/usr/local').
3) For 32-bit targets, get GStreamer Setup. GStreamer is used to view video files. 3) For 32-bit targets, get GStreamer Setup. GStreamer is used to view video files.
You can either download it and install it or manually by unzipping the You can either download it and install it or manually by unzipping the
version that is included in the 'thirdparty/gstreamer' folder. You version that is included in the 'thirdparty/gstreamer' folder. You
will need the 'bin' and 'lib/gstreamer-1.0' folders to be in your will need the 'bin' and 'lib/gstreamer-0.10' folders to be in your
Windows PATH environment variable. Windows PATH environment variable.
NOTE: This has not been fully tested in non-Windows environments NOTE: This has not been fully tested in non-Windows environments

View File

@ -282,6 +282,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
/** /**
* Constructor for the Case class * Constructor for the Case class
*/ */
@SuppressWarnings("deprecation")
private Case(CaseMetadata caseMetadata, SleuthkitCase db) { private Case(CaseMetadata caseMetadata, SleuthkitCase db) {
this.caseMetadata = caseMetadata; this.caseMetadata = caseMetadata;
this.db = db; this.db = db;
@ -835,6 +836,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
/** /**
* Closes this case. This methods close the xml and clear all the fields. * Closes this case. This methods close the xml and clear all the fields.
*/ */
@SuppressWarnings("deprecation")
public void closeCase() throws CaseActionException { public void closeCase() throws CaseActionException {
changeCase(null); changeCase(null);
try { try {

View File

@ -109,10 +109,13 @@ public final class Blackboard implements Closeable {
} }
/** /**
* Cloese this blackboard and releases any resources associated with it. * Closes the blackboard.
* @throws IOException *
* @throws IOException If there is a problem closing the blackboard.
* @deprecated blackboard clients should not close the blackboard.
*/ */
@Override @Override
@Deprecated
public void close() throws IOException { public void close() throws IOException {
} }

View File

@ -1,16 +1,3 @@
FileManager.findFiles.exception.msg=Attempted to use FileManager after it was closed.
FileManager.findFiles2.exception.msg=Attempted to use FileManager after it was closed.
FileManager.findFiles3.exception.msg=Attempted to use FileManager after it was closed.
FileManager.openFiles.exception.msg=Attempted to use FileManager after it was closed.
FileManager.addDerivedFile.exception.msg=Attempted to use FileManager after it was closed.
FileManager.addCarvedFile.exception.msg=Attempted to use FileManager after it was closed.
FileManager.addLocalFilesDirs.exception.notReadable.msg=One of the local files/dirs to add is not readable\: {0}, aborting the process before any files added
FileManager.addLocalFilesDirs.exception.cantAdd.msg=One of the local files/dirs could not be added\: {0}
FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg=Error creating local file set dir\: {0}
FileManager.addLocalDirInt.exception.closed.msg=Attempted to use FileManager after it was closed.
FileManager.addLocalDirInt.exception.doesntExist.msg=Attempted to add a local dir that does not exist\: {0}
FileManager.addLocalDirInt.exception.notReadable.msg=Attempted to add a local dir that is not readable\: {0}
FileManager.addLocalDirInt2.exception.closed.msg=Attempted to use FileManager after it was closed.
TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1})
TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1}) TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1})
TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset

View File

@ -1,16 +1,3 @@
FileManager.findFiles.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.findFiles2.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.findFiles3.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.openFiles.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addDerivedFile.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addCarvedFile.exception.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addLocalFilesDirs.exception.notReadable.msg=\u8ffd\u52a0\u3059\u308b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4e2d\u306b\u8aad\u307f\u53d6\u308c\u306a\u3044\u3082\u306e\u304c\uff11\u500b\u3042\u308a\u307e\u3059\uff1a{0}\u3001\u30d5\u30a1\u30a4\u30eb\u304c\u8ffd\u52a0\u3055\u308c\u308b\u524d\u306b\u51e6\u7406\u3092\u4e2d\u6b62\u3057\u307e\u3059
FileManager.addLocalFilesDirs.exception.cantAdd.msg=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\uff0f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\uff11\u500b\u306f\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff1a{0}
FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg=\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u30bb\u30c3\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u8d77\u3053\u308a\u307e\u3057\u305f\uff1a {0}
FileManager.addLocalDirInt.exception.closed.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
FileManager.addLocalDirInt.exception.doesntExist.msg=\u5b58\u5728\u3057\u306a\u3044\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u8ffd\u52a0\u3092\u8a66\u307f\u307e\u3057\u305f\: {0}
FileManager.addLocalDirInt.exception.notReadable.msg=\u8aad\u307f\u53d6\u308a\u3067\u304d\u306a\u3044\u30ed\u30fc\u30ab\u30eb\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u8ffd\u52a0\u3092\u8a66\u307f\u307e\u3057\u305f\: {0}
FileManager.addLocalDirInt2.exception.closed.msg=FileManager\u3092\u9589\u3058\u305f\u5f8c\u306b\u4f7f\u7528\u3092\u8a66\u307f\u307e\u3057\u305f\u3002
TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059 TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059
TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059 TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059
TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset

View File

@ -26,9 +26,8 @@ import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode; import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
import org.sleuthkit.autopsy.ingest.IngestServices; import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
@ -36,7 +35,6 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DerivedFile; import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.LayoutFile; import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -47,56 +45,36 @@ import org.sleuthkit.datamodel.LocalFilesDataSource;
import org.sleuthkit.datamodel.TskDataException; import org.sleuthkit.datamodel.TskDataException;
/** /**
* Abstraction to facilitate access to localFiles and directories. * A manager that provides methods for retrieving files from the current case
* and for adding local files, carved files, and derived files to the current
* case.
*/ */
public class FileManager implements Closeable { public class FileManager implements Closeable {
private SleuthkitCase tskCase; /**
private static final Logger logger = Logger.getLogger(FileManager.class.getName()); * Constructs a manager that provides methods for retrieving files from the
private volatile int curNumFileSets; //current number of filesets (root virt dir objects) * current case and for adding local files, carved files, and derived files
* to the current case.
public FileManager(SleuthkitCase tskCase) { *
this.tskCase = tskCase; */
init(); FileManager() {
} }
/** /**
* initialize the file manager for the case * Finds all files and directories with a given file name. The name search
*/ * is for full or partial matches and is case insensitive (a case
private synchronized void init() { * insensitive SQL LIKE clause is used to query the case database).
//get the number of local file sets in db
List<VirtualDirectory> virtRoots;
curNumFileSets = 0;
try {
virtRoots = tskCase.getVirtualDirectoryRoots();
for (VirtualDirectory vd : virtRoots) {
if (vd.getName().startsWith(VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX)) {
++curNumFileSets;
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error initializing FileManager and getting number of local file sets"); //NON-NLS
}
}
/**
* Finds a set of localFiles that meets the name criteria in all data
* sources in the current case.
* *
* @param fileName Pattern of the name of the file or directory to match * @param fileName The full or partial file name.
* (case insensitive, used in LIKE SQL statement).
* *
* @return a list of AbstractFile for localFiles/directories whose name * @return The matching files and directories.
* matches the given fileName *
* @throws TskCoreException if there is a problem querying the case
* database.
*/ */
public synchronized List<AbstractFile> findFiles(String fileName) throws TskCoreException { public List<AbstractFile> findFiles(String fileName) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>(); List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = Case.getCurrentCase().getSleuthkitCase().getRootObjects();
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles.exception.msg"));
}
List<Content> dataSources = tskCase.getRootObjects();
for (Content dataSource : dataSources) { for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName)); result.addAll(findFiles(dataSource, fileName));
} }
@ -104,113 +82,107 @@ public class FileManager implements Closeable {
} }
/** /**
* Finds a set of localFiles that meets the name criteria in all data * Finds all files and directories with a given file name and parent file or
* sources in the current case. * directory name. The name searches are for full or partial matches and are
* case insensitive (a case insensitive SQL LIKE clause is used to query the
* case database).
* *
* @param fileName Pattern of the name of the file or directory to match * @param fileName The full or partial file name.
* (case insensitive, used in LIKE SQL statement). * @param parentName The full or partial parent file or directory name.
* @param dirName Pattern of the name of the parent directory to use as the
* root of the search (case insensitive, used in LIKE SQL
* statement).
* *
* @return a list of AbstractFile for localFiles/directories whose name * @return The matching files and directories.
* matches fileName and whose parent directory contains dirName. *
* @throws TskCoreException if there is a problem querying the case
* database.
*/ */
public synchronized List<AbstractFile> findFiles(String fileName, String dirName) throws TskCoreException { public List<AbstractFile> findFiles(String fileName, String parentName) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>(); List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = Case.getCurrentCase().getSleuthkitCase().getRootObjects();
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles2.exception.msg"));
}
List<Content> dataSources = tskCase.getRootObjects();
for (Content dataSource : dataSources) { for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName, dirName)); result.addAll(findFiles(dataSource, fileName, parentName));
} }
return result; return result;
} }
/** /**
* Finds a set of localFiles that meets the name criteria in all data * Finds all files and directories with a given file name and parent file or
* sources in the current case. * directory. The name search is for full or partial matches and is case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
* *
* @param fileName Pattern of the name of the file or directory to match * @param fileName The full or partial file name.
* (case insensitive, used in LIKE SQL statement). * @param parent The parent file or directory.
* @param parentFile Object of root/parent directory to restrict search to.
* *
* @return a list of AbstractFile for localFiles/directories whose name * @return The matching files and directories.
* matches fileName and that were inside a directory described by *
* parentFsContent. * @throws TskCoreException if there is a problem querying the case
* database.
*/ */
public synchronized List<AbstractFile> findFiles(String fileName, AbstractFile parentFile) throws TskCoreException { public List<AbstractFile> findFiles(String fileName, AbstractFile parent) throws TskCoreException {
List<AbstractFile> result = new ArrayList<>(); List<AbstractFile> result = new ArrayList<>();
List<Content> dataSources = Case.getCurrentCase().getSleuthkitCase().getRootObjects();
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles3.exception.msg"));
}
List<Content> dataSources = tskCase.getRootObjects();
for (Content dataSource : dataSources) { for (Content dataSource : dataSources) {
result.addAll(findFiles(dataSource, fileName, parentFile)); result.addAll(findFiles(dataSource, fileName, parent));
} }
return result; return result;
} }
/** /**
* Finds a set of localFiles that meets the name criteria. * Finds all files and directories with a given file name in a given data
* source (image, local/logical files set, etc.). The name search is for
* full or partial matches and is case insensitive (a case insensitive SQL
* LIKE clause is used to query the case database).
* *
* @param dataSource Root data source to limit search results to (Image, * @param dataSource The data source.
* VirtualDirectory, etc.). * @param fileName The full or partial file name.
* @param fileName Pattern of the name of the file or directory to match
* (case insensitive, used in LIKE SQL statement).
* *
* @return a list of AbstractFile for localFiles/directories whose name * @return The matching files and directories.
* matches the given fileName *
* @throws TskCoreException if there is a problem querying the case
* database.
*/ */
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName) throws TskCoreException { public List<AbstractFile> findFiles(Content dataSource, String fileName) throws TskCoreException {
if (tskCase == null) { return Case.getCurrentCase().getSleuthkitCase().findFiles(dataSource, fileName);
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles.exception.msg"));
}
return tskCase.findFiles(dataSource, fileName);
} }
/** /**
* Finds a set of localFiles that meets the name criteria. * Finds all files and directories with a given file name and parent file or
* directory name in a given data source (image, local/logical files set,
* etc.). The name searches are for full or partial matches and are case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
* *
* @param dataSource Root data source to limit search results to (Image, * @param dataSource The data source.
* VirtualDirectory, etc.). * @param fileName The full or partial file name.
* @param fileName Pattern of the name of the file or directory to match * @param parentName The full or partial parent file or directory name.
* (case insensitive, used in LIKE SQL statement).
* @param dirName Pattern of the name of the parent directory to use as
* the root of the search (case insensitive, used in LIKE
* SQL statement).
* *
* @return a list of AbstractFile for localFiles/directories whose name * @return The matching files and directories.
* matches fileName and whose parent directory contains dirName. *
* @throws TskCoreException if there is a problem querying the case
* database.
*/ */
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, String dirName) throws TskCoreException { public List<AbstractFile> findFiles(Content dataSource, String fileName, String parentName) throws TskCoreException {
if (tskCase == null) { return Case.getCurrentCase().getSleuthkitCase().findFiles(dataSource, fileName, parentName);
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles2.exception.msg"));
}
return tskCase.findFiles(dataSource, fileName, dirName);
} }
/** /**
* Finds a set of localFiles that meets the name criteria. * Finds all files and directories with a given file name and given parent
* file or directory in a given data source (image, local/logical files set,
* etc.). The name search is for full or partial matches and is case
* insensitive (a case insensitive SQL LIKE clause is used to query the case
* database).
* *
* @param dataSource Root data source to limit search results to (Image, * @param dataSource The data source.
* VirtualDirectory, etc.). * @param fileName The full or partial file name.
* @param fileName Pattern of the name of the file or directory to match * @param parent The parent file or directory.
* (case insensitive, used in LIKE SQL statement).
* @param parentFile Object of root/parent directory to restrict search to.
* *
* @return a list of AbstractFile for localFiles/directories whose name * @return The matching files and directories.
* matches fileName and that were inside a directory described by *
* parentFsContent. * @throws TskCoreException if there is a problem querying the case
* database.
*/ */
public synchronized List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parentFile) throws TskCoreException { public List<AbstractFile> findFiles(Content dataSource, String fileName, AbstractFile parent) throws TskCoreException {
if (tskCase == null) { return findFiles(dataSource, fileName, parent.getName());
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.findFiles3.exception.msg"));
}
return findFiles(dataSource, fileName, parentFile.getName());
} }
/** /**
@ -221,173 +193,116 @@ public class FileManager implements Closeable {
* *
* @return a list of AbstractFile that have the given file path. * @return a list of AbstractFile that have the given file path.
*/ */
public synchronized List<AbstractFile> openFiles(Content dataSource, String filePath) throws TskCoreException { /**
if (tskCase == null) { * Finds all files and directories with a given file name and path in a
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.openFiles.exception.msg")); * given data source (image, local/logical files set, etc.). The name search
} * is for full or partial matches and is case insensitive (a case
return tskCase.openFiles(dataSource, filePath); * insensitive SQL LIKE clause is used to query the case database). Any path
* components at the volume level and above are removed for the search.
*
* @param dataSource The data source.
* @param fileName The full or partial file name.
* @param filePath The file path (path components volume at the volume
* level or above will be removed).
*
* @return The matching files and directories.
*
* @throws TskCoreException if there is a problem querying the case
* database.
*/
public List<AbstractFile> openFiles(Content dataSource, String filePath) throws TskCoreException {
return Case.getCurrentCase().getSleuthkitCase().openFiles(dataSource, filePath);
} }
/** /**
* Creates a derived file, adds it to the database and returns it. * Adds a derived file to the case.
* *
* @param fileName file name the derived file * @param fileName The name of the file.
* @param localPath local path of the derived file, including the file * @param localPath The local path of the file, relative to the case
* name. The path is relative to the case folder. * folder and including the file name.
* @param size size of the derived file in bytes * @param size The size of the file in bytes.
* @param ctime * @param ctime The change time of the file.
* @param crtime * @param crtime The create time of the file
* @param atime * @param atime The accessed time of the file.
* @param mtime * @param mtime The modified time of the file.
* @param isFile whether a file or directory, true if a file * @param isFile True if a file, false if a directory.
* @param parentFile the parent file object this the new file was * @param parentFile The parent file from which the file was derived.
* derived from, either a fs file or parent derived * @param rederiveDetails The details needed to re-derive file (will be
* file/dikr\\r * specific to the derivation method), currently
* @param rederiveDetails details needed to re-derive file (will be specific * unused.
* to the derivation method), currently unused * @param toolName The name of the derivation method or tool,
* @param toolName name of derivation method/tool, currently unused * currently unused.
* @param toolVersion version of derivation method/tool, currently * @param toolVersion The version of the derivation method or tool,
* unused * currently unused.
* @param otherDetails details of derivation method/tool, currently * @param otherDetails Other details of the derivation method or tool,
* unused * currently unused.
* *
* @return newly created derived file object added to the database * @return A DerivedFile object representing the derived file.
*
* @throws TskCoreException exception thrown if the object creation failed
* due to a critical system error or of the file
* manager has already been closed
* *
* @throws TskCoreException if there is a problem adding the file to the
* case database.
*/ */
public synchronized DerivedFile addDerivedFile(String fileName, String localPath, long size, public DerivedFile addDerivedFile(String fileName,
String localPath,
long size,
long ctime, long crtime, long atime, long mtime, long ctime, long crtime, long atime, long mtime,
boolean isFile, AbstractFile parentFile, boolean isFile,
AbstractFile parentFile,
String rederiveDetails, String toolName, String toolVersion, String otherDetails) throws TskCoreException { String rederiveDetails, String toolName, String toolVersion, String otherDetails) throws TskCoreException {
if (tskCase == null) { return Case.getCurrentCase().getSleuthkitCase().addDerivedFile(fileName, localPath, size,
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addDerivedFile.exception.msg"));
}
return tskCase.addDerivedFile(fileName, localPath, size,
ctime, crtime, atime, mtime, ctime, crtime, atime, mtime,
isFile, parentFile, rederiveDetails, toolName, toolVersion, otherDetails); isFile, parentFile, rederiveDetails, toolName, toolVersion, otherDetails);
} }
/** /**
* Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume * Adds a carved file to the '$CarvedFiles' virtual directory of a data
* or image given by systemId. * source, volume or file system.
* *
* @param carvedFileName the name of the carved file (containing appropriate * @param fileName The name of the file.
* extension) * @param fileSize The size of the file.
* @param carvedFileSize size of the carved file to add * @param parentObjId The object id of the parent data source, volume or
* @param systemId the ID of the parent volume or file system * file system.
* @param sectors a list of SectorGroups giving this sectors that * @param layout A list of the offsets and sizes that gives the layout
* make up this carved file. * of the file within its parent.
* *
* @throws TskCoreException exception thrown when critical tsk error * @return A LayoutFile object representing the carved file.
* occurred and carved file could not be added *
* @throws TskCoreException if there is a problem adding the file to the
* case database.
*/ */
public synchronized LayoutFile addCarvedFile(String carvedFileName, long carvedFileSize, public synchronized LayoutFile addCarvedFile(String fileName, long fileSize, long parentObjId, List<TskFileRange> layout) throws TskCoreException {
long systemId, List<TskFileRange> sectors) throws TskCoreException { return Case.getCurrentCase().getSleuthkitCase().addCarvedFile(fileName, fileSize, parentObjId, layout);
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addCarvedFile.exception.msg"));
}
return tskCase.addCarvedFile(carvedFileName, carvedFileSize, systemId, sectors);
} }
/** /**
* Adds a collection of carved localFiles to the VirtualDirectory * Adds a collection of carved files to the '$CarvedFiles' virtual directory
* '$CarvedFiles' in the volume or image given by systemId. Creates * of a data source, volume or file system.
* $CarvedFiles if it does not exist already.
* *
* @param filesToAdd a list of CarvedFileContainer localFiles to add as * @param A collection of CarvedFileContainer objects, one per carved file,
* carved localFiles * all of which must have the same parent object id.
* *
* @return List<LayoutFile> This is a list of the localFiles added to the * @return A collection of LayoutFile object representing the carved files.
* database
* *
* @throws org.sleuthkit.datamodel.TskCoreException * @throws TskCoreException if there is a problem adding the files to the
* case database.
*/ */
public List<LayoutFile> addCarvedFiles(List<CarvedFileContainer> filesToAdd) throws TskCoreException { public List<LayoutFile> addCarvedFiles(List<CarvedFileContainer> filesToAdd) throws TskCoreException {
if (tskCase == null) { return Case.getCurrentCase().getSleuthkitCase().addCarvedFiles(filesToAdd);
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addCarvedFile.exception.msg"));
} else {
return tskCase.addCarvedFiles(filesToAdd);
}
} }
/** /**
* * Interface for receiving a notification for each file or directory added
* Interface for receiving notifications on folders being added via a * to the case database by a FileManager add files operation.
* callback
*/ */
public interface FileAddProgressUpdater { public interface FileAddProgressUpdater {
/** /**
* Called when new folders has been added * Called after a file or directory is added to the case database.
* *
* @param newFile the file/folder added to the Case * @param An AbstractFile represeting the added file or directory.
*/ */
public void fileAdded(AbstractFile newFile); void fileAdded(AbstractFile newFile);
}
/**
* Add a set of local/logical localFiles and dirs.
*
* @param localAbsPaths list of absolute paths to local localFiles and
* dirs
* @param addProgressUpdater notifier to receive progress notifications on
* folders added, or null if not used
*
* @return file set root VirtualDirectory contained containing all
* AbstractFile objects added
*
* @throws TskCoreException exception thrown if the object creation failed
* due to a critical system error or of the file
* manager has already been closed. There is no
* "revert" logic if one of the additions fails.
* The addition stops with the first error
* encountered.
*/
public synchronized VirtualDirectory addLocalFilesDirs(List<String> localAbsPaths, FileAddProgressUpdater addProgressUpdater) throws TskCoreException {
List<java.io.File> rootsToAdd;
try {
rootsToAdd = getFilesAndDirectories(localAbsPaths);
} catch (TskDataException ex) {
throw new TskCoreException(ex.getLocalizedMessage(), ex);
}
CaseDbTransaction trans = tskCase.beginTransaction();
// make a virtual top-level directory for this set of localFiles/dirs
final VirtualDirectory fileSetRootDir = addLocalFileSetRootDir(trans);
try {
// recursively add each item in the set
for (java.io.File localRootToAdd : rootsToAdd) {
AbstractFile localFileAdded = addLocalDirInt(trans, fileSetRootDir, localRootToAdd, addProgressUpdater);
if (localFileAdded == null) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFilesDirs.exception.cantAdd.msg",
localRootToAdd.getAbsolutePath());
logger.log(Level.SEVERE, msg);
throw new TskCoreException(msg);
} else {
//added.add(localFileAdded);
//send new content event
//for now reusing ingest events, in future this will be replaced by datamodel / observer sending out events
// @@@ Is this the right place for this? A directory tree refresh will be triggered, so this may be creating a race condition
// since the transaction is not yet committed.
IngestServices.getInstance().fireModuleContentEvent(new ModuleContentEvent(localFileAdded));
}
}
trans.commit();
} catch (TskCoreException ex) {
trans.rollback();
}
return fileSetRootDir;
} }
/** /**
@ -423,16 +338,21 @@ public class FileManager implements Closeable {
CaseDbTransaction trans = null; CaseDbTransaction trans = null;
try { try {
String rootDirectoryName = rootVirtualDirectoryName; String rootDirectoryName = rootVirtualDirectoryName;
int newLocalFilesSetCount = curNumFileSets + 1; if (rootDirectoryName.isEmpty()) {
if (rootVirtualDirectoryName.isEmpty()) { rootDirectoryName = generateFilesDataSourceName();
rootDirectoryName = VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX + newLocalFilesSetCount;
} }
trans = tskCase.beginTransaction();
LocalFilesDataSource dataSource = tskCase.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans); /*
* Add the root virtual directory and its local/logical file
* children to the case database.
*/
SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase();
trans = caseDb.beginTransaction();
LocalFilesDataSource dataSource = caseDb.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans);
VirtualDirectory rootDirectory = dataSource.getRootDirectory(); VirtualDirectory rootDirectory = dataSource.getRootDirectory();
List<AbstractFile> filesAdded = new ArrayList<>(); List<AbstractFile> filesAdded = new ArrayList<>();
for (java.io.File localFile : localFiles) { for (java.io.File localFile : localFiles) {
AbstractFile fileAdded = addLocalDirInt(trans, rootDirectory, localFile, progressUpdater); AbstractFile fileAdded = addLocalFile(trans, rootDirectory, localFile, progressUpdater);
if (null != fileAdded) { if (null != fileAdded) {
filesAdded.add(fileAdded); filesAdded.add(fileAdded);
} else { } else {
@ -440,13 +360,16 @@ public class FileManager implements Closeable {
} }
} }
trans.commit(); trans.commit();
if (rootVirtualDirectoryName.isEmpty()) {
curNumFileSets = newLocalFilesSetCount; /*
} * Publish content added events for the added files and directories.
*/
for (AbstractFile fileAdded : filesAdded) { for (AbstractFile fileAdded : filesAdded) {
IngestServices.getInstance().fireModuleContentEvent(new ModuleContentEvent(fileAdded)); IngestServices.getInstance().fireModuleContentEvent(new ModuleContentEvent(fileAdded));
} }
return dataSource; return dataSource;
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
if (null != trans) { if (null != trans) {
trans.rollback(); trans.rollback();
@ -455,6 +378,34 @@ public class FileManager implements Closeable {
} }
} }
/**
* Generates a name for the root virtual directory for the data source.
*
* NOTE: Although this method is guarded by the file manager's monitor,
* there is currently a minimal chance of default name duplication for
* multi-user cases with multiple FileManagers running on different nodes.
*
* @return A default name for a local/logical files data source of the form:
* LogicalFileSet[N].
*
* @throws TskCoreException If there is a problem querying the case
* database.
*/
private synchronized String generateFilesDataSourceName() throws TskCoreException {
int localFileDataSourcesCounter = 0;
try {
List<VirtualDirectory> localFileDataSources = Case.getCurrentCase().getSleuthkitCase().getVirtualDirectoryRoots();
for (VirtualDirectory vd : localFileDataSources) {
if (vd.getName().startsWith(VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX)) {
++localFileDataSourcesCounter;
}
}
return VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX + (localFileDataSourcesCounter + 1);
} catch (TskCoreException ex) {
throw new TskCoreException("Error querying for existing local file data sources with defualt names", ex);
}
}
/** /**
* Converts a list of local/logical file and/or directory paths to a list of * Converts a list of local/logical file and/or directory paths to a list of
* file objects. * file objects.
@ -472,7 +423,7 @@ public class FileManager implements Closeable {
for (String path : localFilePaths) { for (String path : localFilePaths) {
java.io.File localFile = new java.io.File(path); java.io.File localFile = new java.io.File(path);
if (!localFile.exists() || !localFile.canRead()) { if (!localFile.exists() || !localFile.canRead()) {
throw new TskDataException(NbBundle.getMessage(this.getClass(), "FileManager.addLocalFilesDirs.exception.notReadable.msg", localFile.getAbsolutePath())); throw new TskDataException(String.format("File at %s does not exist or cannot be read", localFile.getAbsolutePath()));
} }
localFiles.add(localFile); localFiles.add(localFile);
} }
@ -480,130 +431,101 @@ public class FileManager implements Closeable {
} }
/** /**
* Adds a new virtual directory root object with FileSet X name and * Adds a file or directory of logical/local files data source to the case
* consecutive sequence number characteristic to every add operation * database, recursively adding the contents of directories.
*
* @return the virtual dir root container created
*
* @throws TskCoreException
*/
private VirtualDirectory addLocalFileSetRootDir(CaseDbTransaction trans) throws TskCoreException {
VirtualDirectory created = null;
int newFileSetCount = curNumFileSets + 1;
final String fileSetName = VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX + newFileSetCount;
try {
created = tskCase.addVirtualDirectory(0, fileSetName, trans);
curNumFileSets = newFileSetCount;
} catch (TskCoreException ex) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg",
fileSetName);
logger.log(Level.SEVERE, msg, ex);
throw new TskCoreException(msg, ex);
}
return created;
}
/**
* Helper (internal) method to recursively add contents of a folder. Node
* passed in can be a file or directory. Children of directories are added.
* *
* @param trans A case database transaction. * @param trans A case database transaction.
* @param parentVd Dir that is the parent of localFile * @param parentDirectory The root virtual direcotry of the data source.
* @param localFile File/Dir that we are adding * @param localFile The local/logical file or directory.
* @param addProgressUpdater notifier to receive progress notifications on * @param addProgressUpdater notifier to receive progress notifications on
* folders added, or null if not used * folders added, or null if not used
* *
* @returns File object of file added or new virtualdirectory for the * @returns File object of file added or new virtualdirectory for the
* directory. * directory.
* @throws TskCoreException * @param progressUpdater Called after each file/directory is added to
* the case database.
*
* @return An AbstractFile representation of the local/logical file.
*
* @throws TskCoreException If there is a problem completing a database
* operation.
*/ */
private AbstractFile addLocalDirInt(CaseDbTransaction trans, VirtualDirectory parentVd, private AbstractFile addLocalFile(CaseDbTransaction trans, VirtualDirectory parentDirectory, java.io.File localFile, FileAddProgressUpdater progressUpdater) throws TskCoreException {
java.io.File localFile, FileAddProgressUpdater addProgressUpdater) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.closed.msg"));
}
//final String localName = localDir.getName();
if (!localFile.exists()) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.doesntExist.msg",
localFile.getAbsolutePath()));
}
if (!localFile.canRead()) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.notReadable.msg",
localFile.getAbsolutePath()));
}
if (localFile.isDirectory()) { if (localFile.isDirectory()) {
//create virtual folder (we don't have a notion of a 'local folder') /*
final VirtualDirectory childVd = tskCase.addVirtualDirectory(parentVd.getId(), localFile.getName(), trans); * Add the directory as a virtual directory.
if (childVd != null && addProgressUpdater != null) { */
addProgressUpdater.fileAdded(childVd); VirtualDirectory virtualDirectory = Case.getCurrentCase().getSleuthkitCase().addVirtualDirectory(parentDirectory.getId(), localFile.getName(), trans);
} progressUpdater.fileAdded(virtualDirectory);
//add children recursively
final java.io.File[] childrenFiles = localFile.listFiles(); /*
if (childrenFiles != null) { * Add its children, if any.
for (java.io.File childFile : childrenFiles) { */
addLocalDirInt(trans, childVd, childFile, addProgressUpdater); final java.io.File[] childFiles = localFile.listFiles();
if (childFiles != null && childFiles.length > 0) {
for (java.io.File childFile : childFiles) {
addLocalFile(trans, virtualDirectory, childFile, progressUpdater);
} }
} }
return childVd;
return virtualDirectory;
} else { } else {
//add leaf file, base case return Case.getCurrentCase().getSleuthkitCase().addLocalFile(localFile.getName(), localFile.getAbsolutePath(), localFile.length(),
return this.addLocalFileInt(parentVd, localFile, trans); 0, 0, 0, 0,
localFile.isFile(), parentDirectory, trans);
} }
} }
/** /**
* Adds a single local/logical file to the case. Adds it to the database. * Adds a set of local/logical files and/or directories to the case database
* Does not refresh the views of data. Assumes that the local file exists * as data source.
* and can be read. This checking is done by addLocalDirInt().
* *
* @param parentFile parent file object container (such as virtual * @param localFilePaths A list of local/logical file and/or directory
* directory, another local file, or fscontent File), * localFilePaths.
* @param localFile File that we are adding * @param progressUpdater Called after each file/directory is added to the
* @param trans A case database transaction. * case database.
* *
* @return newly created local file object added to the database * @return The root virtual directory for the local/logical files data
* source.
* *
* @throws TskCoreException exception thrown if the object creation failed * @throws TskCoreException If any of the local file paths is for a file or
* due to a critical system error or of the file * directory that does not exist or cannot be read,
* manager has already been closed * or there is a problem completing a database
* operation.
* @deprecated Use addLocalFilesDataSource instead.
*/ */
private synchronized LocalFile addLocalFileInt(AbstractFile parentFile, java.io.File localFile, CaseDbTransaction trans) throws TskCoreException { @Deprecated
public VirtualDirectory addLocalFilesDirs(List<String> localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException {
if (tskCase == null) { try {
throw new TskCoreException( return addLocalFilesDataSource("", "", "", localFilePaths, progressUpdater).getRootDirectory();
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt2.exception.closed.msg")); } catch (TskDataException ex) {
throw new TskCoreException(ex.getLocalizedMessage(), ex);
} }
long size = localFile.length();
boolean isFile = localFile.isFile();
long ctime = 0;
long crtime = 0;
long atime = 0;
long mtime = 0;
String fileName = localFile.getName();
LocalFile lf = tskCase.addLocalFile(fileName, localFile.getAbsolutePath(), size,
ctime, crtime, atime, mtime,
isFile, parentFile, trans);
return lf;
} }
/**
* Constructs a manager that provides methods for retrieving files from the
* current case and for adding local files, carved files, and derived files
* to the current case.
*
* @param caseDb The case database.
*
* @deprecated Use Case.getCurrentCase().getServices().getFileManager()
* instead.
*/
@Deprecated
public FileManager(SleuthkitCase caseDb) {
}
/**
* Closes the file manager.
*
* @throws IOException If there is a problem closing the file manager.
* @deprecated File manager clients should not close the file manager.
*/
@Override @Override
public synchronized void close() throws IOException { @Deprecated
tskCase = null; public void close() throws IOException {
} }
} }

View File

@ -2,11 +2,10 @@
* *
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012-2015 Basis Technology Corp. * Copyright 2011-2016 Basis Technology Corp.
* * Contact: carrier <at> sleuthkit <dot> org
* Copyright 2012 42six Solutions. * Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com * Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,7 +30,8 @@ import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
/** /**
* A class to manage various services. * A collection of case-level services (e.g., file manager, tags manager,
* keyword search, blackboard).
*/ */
public class Services implements Closeable { public class Services implements Closeable {
@ -41,11 +41,22 @@ public class Services implements Closeable {
private final KeywordSearchService keywordSearchService; private final KeywordSearchService keywordSearchService;
private final Blackboard blackboard; private final Blackboard blackboard;
public Services(SleuthkitCase tskCase) { /**
fileManager = new FileManager(tskCase); * Constructs a collection of case-level services (e.g., file manager, tags
* manager, keyword search, blackboard).
*
* @param caseDb The case database for the current case.
*
* @deprecated Use Case.getCurrentCase().getServices() instead.
*
* TODO (AUT-2158): Prevent public construction of the Services class.
*/
@Deprecated
public Services(SleuthkitCase caseDb) {
fileManager = new FileManager();
services.add(fileManager); services.add(fileManager);
tagsManager = new TagsManager(tskCase); tagsManager = new TagsManager();
services.add(tagsManager); services.add(tagsManager);
keywordSearchService = Lookup.getDefault().lookup(KeywordSearchService.class); keywordSearchService = Lookup.getDefault().lookup(KeywordSearchService.class);
@ -55,23 +66,51 @@ public class Services implements Closeable {
services.add(blackboard); services.add(blackboard);
} }
/**
* Gets the file manager service for the current case.
*
* @return The file manager service for the current case.
*/
public FileManager getFileManager() { public FileManager getFileManager() {
return fileManager; return fileManager;
} }
/**
* Gets the tags manager service for the current case.
*
* @return The tags manager service for the current case.
*/
public TagsManager getTagsManager() { public TagsManager getTagsManager() {
return tagsManager; return tagsManager;
} }
/**
* Gets the keyword search service for the current case.
*
* @return The keyword search service for the current case.
*/
public KeywordSearchService getKeywordSearchService() { public KeywordSearchService getKeywordSearchService() {
return keywordSearchService; return keywordSearchService;
} }
/**
* Gets the blackboard service for the current case.
*
* @return The blackboard service for the current case.
*/
public Blackboard getBlackboard() { public Blackboard getBlackboard() {
return blackboard; return blackboard;
} }
/**
* Closes the services for the current case.
*
* @throws IOException if there is a problem closing the services.
* @deprecated Services clients other than the case should not close the
* services.
*/
@Override @Override
@Deprecated
public void close() throws IOException { public void close() throws IOException {
for (Closeable service : services) { for (Closeable service : services) {
service.close(); service.close();

View File

@ -32,7 +32,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -45,7 +44,6 @@ public class TagsManager implements Closeable {
private static final Logger logger = Logger.getLogger(TagsManager.class.getName()); private static final Logger logger = Logger.getLogger(TagsManager.class.getName());
private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS
private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS
private final SleuthkitCase caseDb;
private final HashMap<String, TagName> uniqueTagNames = new HashMap<>(); private final HashMap<String, TagName> uniqueTagNames = new HashMap<>();
private boolean tagNamesLoaded = false; private boolean tagNamesLoaded = false;
@ -53,11 +51,8 @@ public class TagsManager implements Closeable {
* Constructs a per case Autopsy service that manages the creation, * Constructs a per case Autopsy service that manages the creation,
* updating, and deletion of tags applied to content and blackboard * updating, and deletion of tags applied to content and blackboard
* artifacts by users. * artifacts by users.
*
* @param caseDb The case database for the current case.
*/ */
TagsManager(SleuthkitCase caseDb) { TagsManager() {
this.caseDb = caseDb;
} }
/** /**
@ -71,7 +66,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<TagName> getAllTagNames() throws TskCoreException { public synchronized List<TagName> getAllTagNames() throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getAllTagNames(); return Case.getCurrentCase().getSleuthkitCase().getAllTagNames();
} }
/** /**
@ -85,7 +80,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<TagName> getTagNamesInUse() throws TskCoreException { public synchronized List<TagName> getTagNamesInUse() throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getTagNamesInUse(); return Case.getCurrentCase().getSleuthkitCase().getTagNamesInUse();
} }
/** /**
@ -159,7 +154,7 @@ public class TagsManager implements Closeable {
/* /*
* Add the tag name to the case. * Add the tag name to the case.
*/ */
TagName newTagName = caseDb.addTagName(displayName, description, color); TagName newTagName = Case.getCurrentCase().getSleuthkitCase().addTagName(displayName, description, color);
/* /*
* Add the tag name to the tags settings. * Add the tag name to the tags settings.
@ -245,7 +240,7 @@ public class TagsManager implements Closeable {
} }
} }
tag = caseDb.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset); tag = Case.getCurrentCase().getSleuthkitCase().addContentTag(content, tagName, comment, beginByteOffset, endByteOffset);
} }
try { try {
@ -267,7 +262,7 @@ public class TagsManager implements Closeable {
public void deleteContentTag(ContentTag tag) throws TskCoreException { public void deleteContentTag(ContentTag tag) throws TskCoreException {
synchronized (this) { synchronized (this) {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
caseDb.deleteContentTag(tag); Case.getCurrentCase().getSleuthkitCase().deleteContentTag(tag);
} }
try { try {
@ -287,7 +282,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<ContentTag> getAllContentTags() throws TskCoreException { public synchronized List<ContentTag> getAllContentTags() throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getAllContentTags(); return Case.getCurrentCase().getSleuthkitCase().getAllContentTags();
} }
/** /**
@ -302,7 +297,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException { public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getContentTagsCountByTagName(tagName); return Case.getCurrentCase().getSleuthkitCase().getContentTagsCountByTagName(tagName);
} }
/** /**
@ -317,7 +312,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized ContentTag getContentTagByTagID(long tagID) throws TskCoreException { public synchronized ContentTag getContentTagByTagID(long tagID) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getContentTagByID(tagID); return Case.getCurrentCase().getSleuthkitCase().getContentTagByID(tagID);
} }
/** /**
@ -333,7 +328,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<ContentTag> getContentTagsByTagName(TagName tagName) throws TskCoreException { public synchronized List<ContentTag> getContentTagsByTagName(TagName tagName) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getContentTagsByTagName(tagName); return Case.getCurrentCase().getSleuthkitCase().getContentTagsByTagName(tagName);
} }
/** /**
@ -349,7 +344,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException { public synchronized List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getContentTagsByContent(content); return Case.getCurrentCase().getSleuthkitCase().getContentTagsByContent(content);
} }
/** /**
@ -388,7 +383,7 @@ public class TagsManager implements Closeable {
if (null == comment) { if (null == comment) {
throw new IllegalArgumentException("Passed null comment argument"); throw new IllegalArgumentException("Passed null comment argument");
} }
tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment); tag = Case.getCurrentCase().getSleuthkitCase().addBlackboardArtifactTag(artifact, tagName, comment);
} }
try { try {
@ -410,7 +405,7 @@ public class TagsManager implements Closeable {
public void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException { public void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException {
synchronized (this) { synchronized (this) {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
caseDb.deleteBlackboardArtifactTag(tag); Case.getCurrentCase().getSleuthkitCase().deleteBlackboardArtifactTag(tag);
} }
try { try {
@ -430,7 +425,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException { public synchronized List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getAllBlackboardArtifactTags(); return Case.getCurrentCase().getSleuthkitCase().getAllBlackboardArtifactTags();
} }
/** /**
@ -446,7 +441,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException { public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsCountByTagName(tagName); return Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTagsCountByTagName(tagName);
} }
/** /**
@ -461,7 +456,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized BlackboardArtifactTag getBlackboardArtifactTagByTagID(long tagID) throws TskCoreException { public synchronized BlackboardArtifactTag getBlackboardArtifactTagByTagID(long tagID) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagByID(tagID); return Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTagByID(tagID);
} }
/** /**
@ -477,7 +472,7 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException { public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsByTagName(tagName); return Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTagsByTagName(tagName);
} }
/** /**
@ -493,13 +488,18 @@ public class TagsManager implements Closeable {
*/ */
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException { public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException {
lazyLoadExistingTagNames(); lazyLoadExistingTagNames();
return caseDb.getBlackboardArtifactTagsByArtifact(artifact); return Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTagsByArtifact(artifact);
} }
/** /**
* Saves the avaialble tag names to secondary storage. * Closes the tags manager, saving the avaialble tag names to secondary
* storage.
*
* @throws IOException If there is a problem closing the tags manager.
* @deprecated Tags manager clients should not close the tags manager.
*/ */
@Override @Override
@Deprecated
public synchronized void close() throws IOException { public synchronized void close() throws IOException {
saveTagNamesToTagsSettings(); saveTagNamesToTagsSettings();
} }
@ -524,7 +524,7 @@ public class TagsManager implements Closeable {
*/ */
private void addTagNamesFromCurrentCase() { private void addTagNamesFromCurrentCase() {
try { try {
List<TagName> currentTagNames = caseDb.getAllTagNames(); List<TagName> currentTagNames = Case.getCurrentCase().getSleuthkitCase().getAllTagNames();
for (TagName tagName : currentTagNames) { for (TagName tagName : currentTagNames) {
uniqueTagNames.put(tagName.getDisplayName(), tagName); uniqueTagNames.put(tagName.getDisplayName(), tagName);
} }
@ -550,7 +550,7 @@ public class TagsManager implements Closeable {
String[] tagNameAttributes = tagNameTuple.split(","); String[] tagNameAttributes = tagNameTuple.split(",");
if (!uniqueTagNames.containsKey(tagNameAttributes[0])) { if (!uniqueTagNames.containsKey(tagNameAttributes[0])) {
try { try {
TagName tagName = caseDb.addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2])); TagName tagName = Case.getCurrentCase().getSleuthkitCase().addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2]));
uniqueTagNames.put(tagName.getDisplayName(), tagName); uniqueTagNames.put(tagName.getDisplayName(), tagName);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS
@ -566,7 +566,7 @@ public class TagsManager implements Closeable {
private void addPredefinedTagNames() { private void addPredefinedTagNames() {
if (!uniqueTagNames.containsKey(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))) { if (!uniqueTagNames.containsKey(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))) {
try { try {
TagName tagName = caseDb.addTagName( TagName tagName = Case.getCurrentCase().getSleuthkitCase().addTagName(
NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), "", TagName.HTML_COLOR.NONE); NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), "", TagName.HTML_COLOR.NONE);
uniqueTagNames.put(tagName.getDisplayName(), tagName); uniqueTagNames.put(tagName.getDisplayName(), tagName);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {

View File

@ -53,6 +53,6 @@ SearchNode.getName.text=Search Result
SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.equalTo=equal to
SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than
SizeSearchPanel.sizeCompareComboBox.lessThan=less than SizeSearchPanel.sizeCompareComboBox.lessThan=less than
MimeTypePanel.jCheckBox1.text=MIME Type:
MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected MimeTypePanel.jLabel1.text=*Note: Multiple MIME types can be selected
FileSearchPanel.searchButton.text=Search FileSearchPanel.searchButton.text=Search
MimeTypePanel.mimeTypeCheckBox.text=MIME Type:

View File

@ -180,6 +180,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dateCheckBoxActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JComboBox" name="timeZoneComboBox"> <Component class="javax.swing.JComboBox" name="timeZoneComboBox">
<Properties> <Properties>

View File

@ -74,6 +74,7 @@ class DateSearchPanel extends javax.swing.JPanel {
copyMenuItem.addActionListener(actList); copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList);
this.setComponentsEnabled();
} }
JCheckBox getAccessedCheckBox() { JCheckBox getAccessedCheckBox() {
@ -116,6 +117,23 @@ class DateSearchPanel extends javax.swing.JPanel {
} }
} }
private void setComponentsEnabled() {
boolean enable = this.dateCheckBox.isSelected();
this.dateFromTextField.setEnabled(enable);
this.dateFromButtonCalendar.setEnabled(enable);
this.jLabel1.setEnabled(enable);
this.dateToTextField.setEnabled(enable);
this.dateToButtonCalendar.setEnabled(enable);
this.jLabel2.setEnabled(enable);
this.jLabel3.setEnabled(enable);
this.jLabel4.setEnabled(enable);
this.timeZoneComboBox.setEnabled(enable);
this.modifiedCheckBox.setEnabled(enable);
this.accessedCheckBox.setEnabled(enable);
this.changedCheckBox.setEnabled(enable);
this.createdCheckBox.setEnabled(enable);
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -170,6 +188,11 @@ class DateSearchPanel extends javax.swing.JPanel {
jLabel4.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel4.text")); // NOI18N jLabel4.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel4.text")); // NOI18N
dateCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateCheckBox.text")); // NOI18N dateCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateCheckBox.text")); // NOI18N
dateCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dateCheckBoxActionPerformed(evt);
}
});
jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
@ -324,6 +347,10 @@ class DateSearchPanel extends javax.swing.JPanel {
} }
}//GEN-LAST:event_dateToPopupChanged }//GEN-LAST:event_dateToPopupChanged
private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed
this.setComponentsEnabled();
}//GEN-LAST:event_dateCheckBoxActionPerformed
/** /**
* Validate and set the datetime field on the screen given a datetime * Validate and set the datetime field on the screen given a datetime
* string. * string.

View File

@ -53,6 +53,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.knownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.knownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="knownCheckBoxActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="unknownOptionCheckBox"> <Component class="javax.swing.JCheckBox" name="unknownOptionCheckBox">
<Properties> <Properties>

View File

@ -37,6 +37,7 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
*/ */
KnownStatusSearchPanel() { KnownStatusSearchPanel() {
initComponents(); initComponents();
setComponentsEnabled();
} }
JCheckBox getKnownCheckBox() { JCheckBox getKnownCheckBox() {
@ -55,6 +56,13 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
return unknownOptionCheckBox; return unknownOptionCheckBox;
} }
private void setComponentsEnabled() {
boolean enabled = this.knownCheckBox.isSelected();
this.unknownOptionCheckBox.setEnabled(enabled);
this.knownOptionCheckBox.setEnabled(enabled);
this.knownBadOptionCheckBox.setEnabled(enabled);
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -70,6 +78,11 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
knownBadOptionCheckBox = new javax.swing.JCheckBox(); knownBadOptionCheckBox = new javax.swing.JCheckBox();
knownCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownCheckBox.text")); // NOI18N knownCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownCheckBox.text")); // NOI18N
knownCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
knownCheckBoxActionPerformed(evt);
}
});
unknownOptionCheckBox.setSelected(true); unknownOptionCheckBox.setSelected(true);
unknownOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.unknownOptionCheckBox.text")); // NOI18N unknownOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.unknownOptionCheckBox.text")); // NOI18N
@ -117,6 +130,10 @@ class KnownStatusSearchPanel extends javax.swing.JPanel {
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_knownOptionCheckBoxActionPerformed }//GEN-LAST:event_knownOptionCheckBoxActionPerformed
private void knownCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_knownCheckBoxActionPerformed
setComponentsEnabled();
}//GEN-LAST:event_knownCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox knownBadOptionCheckBox; private javax.swing.JCheckBox knownBadOptionCheckBox;
private javax.swing.JCheckBox knownCheckBox; private javax.swing.JCheckBox knownCheckBox;

View File

@ -25,13 +25,13 @@
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="jCheckBox1" min="-2" max="-2" attributes="0"/> <Component id="mimeTypeCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/> <Component id="jScrollPane1" pref="298" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="jLabel1" min="-2" pref="246" max="-2" attributes="0"/> <Component id="jLabel1" min="-2" pref="246" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -44,12 +44,12 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="jCheckBox1" min="-2" max="-2" attributes="0"/> <Component id="mimeTypeCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="106" max="32767" attributes="0"/> <Component id="jScrollPane1" pref="106" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/> <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -62,7 +62,7 @@
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents> <SubComponents>
<Component class="javax.swing.JList" name="jList1"> <Component class="javax.swing.JList" name="mimeTypeList">
<Properties> <Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.AbstractListModel&lt;String&gt;() {&#xa; String[] strings = getMimeTypeArray();&#xa; public int getSize() { return strings.length; }&#xa; public String getElementAt(int i) { return strings[i]; }&#xa;}" type="code"/> <Connection code="new javax.swing.AbstractListModel&lt;String&gt;() {&#xa; String[] strings = getMimeTypeArray();&#xa; public int getSize() { return strings.length; }&#xa; public String getElementAt(int i) { return strings[i]; }&#xa;}" type="code"/>
@ -77,12 +77,15 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JCheckBox" name="jCheckBox1"> <Component class="javax.swing.JCheckBox" name="mimeTypeCheckBox">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="MimeTypePanel.jCheckBox1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="MimeTypePanel.mimeTypeCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="mimeTypeCheckBoxActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JLabel" name="jLabel1"> <Component class="javax.swing.JLabel" name="jLabel1">
<Properties> <Properties>

View File

@ -5,17 +5,16 @@
*/ */
package org.sleuthkit.autopsy.filesearch; package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.apache.tika.mime.MediaType; import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypes; import org.apache.tika.mime.MimeTypes;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
/** /**
* *
@ -32,6 +31,7 @@ public class MimeTypePanel extends javax.swing.JPanel {
*/ */
public MimeTypePanel() { public MimeTypePanel() {
initComponents(); initComponents();
setComponentsEnabled();
} }
private String[] getMimeTypeArray() { private String[] getMimeTypeArray() {
@ -63,11 +63,17 @@ public class MimeTypePanel extends javax.swing.JPanel {
} }
List<String> getMimeTypesSelected() { List<String> getMimeTypesSelected() {
return this.jList1.getSelectedValuesList(); return this.mimeTypeList.getSelectedValuesList();
} }
boolean isSelected() { boolean isSelected() {
return this.jCheckBox1.isSelected(); return this.mimeTypeCheckBox.isSelected();
}
void setComponentsEnabled() {
boolean enabled = this.isSelected();
this.mimeTypeList.setEnabled(enabled);
this.jLabel1.setEnabled(enabled);
} }
/** /**
@ -80,22 +86,27 @@ public class MimeTypePanel extends javax.swing.JPanel {
private void initComponents() { private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane(); jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList<String>(); mimeTypeList = new javax.swing.JList<>();
jCheckBox1 = new javax.swing.JCheckBox(); mimeTypeCheckBox = new javax.swing.JCheckBox();
jLabel1 = new javax.swing.JLabel(); jLabel1 = new javax.swing.JLabel();
setMinimumSize(new java.awt.Dimension(150, 150)); setMinimumSize(new java.awt.Dimension(150, 150));
setPreferredSize(new java.awt.Dimension(100, 100)); setPreferredSize(new java.awt.Dimension(100, 100));
jList1.setModel(new javax.swing.AbstractListModel<String>() { mimeTypeList.setModel(new javax.swing.AbstractListModel<String>() {
String[] strings = getMimeTypeArray(); String[] strings = getMimeTypeArray();
public int getSize() { return strings.length; } public int getSize() { return strings.length; }
public String getElementAt(int i) { return strings[i]; } public String getElementAt(int i) { return strings[i]; }
}); });
jList1.setMinimumSize(new java.awt.Dimension(0, 200)); mimeTypeList.setMinimumSize(new java.awt.Dimension(0, 200));
jScrollPane1.setViewportView(jList1); jScrollPane1.setViewportView(mimeTypeList);
org.openide.awt.Mnemonics.setLocalizedText(jCheckBox1, org.openide.util.NbBundle.getMessage(MimeTypePanel.class, "MimeTypePanel.jCheckBox1.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(mimeTypeCheckBox, org.openide.util.NbBundle.getMessage(MimeTypePanel.class, "MimeTypePanel.mimeTypeCheckBox.text")); // NOI18N
mimeTypeCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
mimeTypeCheckBoxActionPerformed(evt);
}
});
jLabel1.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel1.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(MimeTypePanel.class, "MimeTypePanel.jLabel1.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(MimeTypePanel.class, "MimeTypePanel.jLabel1.text")); // NOI18N
@ -105,12 +116,12 @@ public class MimeTypePanel extends javax.swing.JPanel {
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jCheckBox1) .addComponent(mimeTypeCheckBox)
.addGap(0, 0, Short.MAX_VALUE)) .addGap(0, 0, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 298, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))) .addGap(0, 0, Short.MAX_VALUE)))
@ -119,20 +130,24 @@ public class MimeTypePanel extends javax.swing.JPanel {
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jCheckBox1) .addComponent(mimeTypeCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1) .addComponent(jLabel1)
.addGap(0, 0, 0)) .addContainerGap())
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void mimeTypeCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeTypeCheckBoxActionPerformed
setComponentsEnabled();
}//GEN-LAST:event_mimeTypeCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox jCheckBox1;
private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel1;
private javax.swing.JList<String> jList1;
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JCheckBox mimeTypeCheckBox;
private javax.swing.JList<String> mimeTypeList;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -94,6 +94,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.nameCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.nameCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nameCheckBoxActionPerformed"/>
</Events>
</Component> </Component>
<Component class="javax.swing.JTextField" name="searchTextField"> <Component class="javax.swing.JTextField" name="searchTextField">
<Properties> <Properties>

View File

@ -24,7 +24,6 @@
*/ */
package org.sleuthkit.autopsy.filesearch; package org.sleuthkit.autopsy.filesearch;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
@ -43,6 +42,7 @@ class NameSearchPanel extends javax.swing.JPanel {
NameSearchPanel() { NameSearchPanel() {
initComponents(); initComponents();
customizeComponents(); customizeComponents();
setComponentsEnabled();
} }
private void customizeComponents() { private void customizeComponents() {
@ -78,6 +78,12 @@ class NameSearchPanel extends javax.swing.JPanel {
return searchTextField; return searchTextField;
} }
void setComponentsEnabled() {
boolean enabled = nameCheckBox.isSelected();
this.searchTextField.setEnabled(enabled);
this.noteNameLabel.setEnabled(enabled);
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -110,6 +116,11 @@ class NameSearchPanel extends javax.swing.JPanel {
nameCheckBox.setFont(nameCheckBox.getFont().deriveFont(nameCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); nameCheckBox.setFont(nameCheckBox.getFont().deriveFont(nameCheckBox.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
nameCheckBox.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.nameCheckBox.text")); // NOI18N nameCheckBox.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.nameCheckBox.text")); // NOI18N
nameCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nameCheckBoxActionPerformed(evt);
}
});
searchTextField.setFont(searchTextField.getFont().deriveFont(searchTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); searchTextField.setFont(searchTextField.getFont().deriveFont(searchTextField.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
searchTextField.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.searchTextField.text")); // NOI18N searchTextField.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.searchTextField.text")); // NOI18N
@ -154,6 +165,11 @@ class NameSearchPanel extends javax.swing.JPanel {
private void searchTextFieldMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_searchTextFieldMouseClicked private void searchTextFieldMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_searchTextFieldMouseClicked
this.nameCheckBox.setSelected(true); }//GEN-LAST:event_searchTextFieldMouseClicked this.nameCheckBox.setSelected(true); }//GEN-LAST:event_searchTextFieldMouseClicked
private void nameCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameCheckBoxActionPerformed
setComponentsEnabled();
}//GEN-LAST:event_nameCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JMenuItem copyMenuItem; private javax.swing.JMenuItem copyMenuItem;
private javax.swing.JMenuItem cutMenuItem; private javax.swing.JMenuItem cutMenuItem;

View File

@ -116,6 +116,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="SizeSearchPanel.sizeCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="SizeSearchPanel.sizeCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="sizeCheckBoxActionPerformed"/>
</Events>
</Component> </Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -18,8 +18,6 @@
*/ */
package org.sleuthkit.autopsy.filesearch; package org.sleuthkit.autopsy.filesearch;
import org.openide.util.NbBundle;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.text.NumberFormat; import java.text.NumberFormat;
@ -40,6 +38,7 @@ class SizeSearchPanel extends javax.swing.JPanel {
SizeSearchPanel() { SizeSearchPanel() {
initComponents(); initComponents();
customizeComponents(); customizeComponents();
setComponentsEnabled();
} }
private void customizeComponents() { private void customizeComponents() {
@ -83,6 +82,13 @@ class SizeSearchPanel extends javax.swing.JPanel {
return sizeUnitComboBox; return sizeUnitComboBox;
} }
void setComponentsEnabled() {
boolean enabled = this.sizeCheckBox.isSelected();
this.sizeCompareComboBox.setEnabled(enabled);
this.sizeUnitComboBox.setEnabled(enabled);
this.sizeTextField.setEnabled(enabled);
}
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -97,9 +103,9 @@ class SizeSearchPanel extends javax.swing.JPanel {
copyMenuItem = new javax.swing.JMenuItem(); copyMenuItem = new javax.swing.JMenuItem();
pasteMenuItem = new javax.swing.JMenuItem(); pasteMenuItem = new javax.swing.JMenuItem();
selectAllMenuItem = new javax.swing.JMenuItem(); selectAllMenuItem = new javax.swing.JMenuItem();
sizeUnitComboBox = new javax.swing.JComboBox<String>(); sizeUnitComboBox = new javax.swing.JComboBox<>();
sizeTextField = new JFormattedTextField(NumberFormat.getIntegerInstance()); sizeTextField = new JFormattedTextField(NumberFormat.getIntegerInstance());
sizeCompareComboBox = new javax.swing.JComboBox<String>(); sizeCompareComboBox = new javax.swing.JComboBox<>();
sizeCheckBox = new javax.swing.JCheckBox(); sizeCheckBox = new javax.swing.JCheckBox();
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.cutMenuItem.text")); // NOI18N cutMenuItem.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.cutMenuItem.text")); // NOI18N
@ -114,7 +120,7 @@ class SizeSearchPanel extends javax.swing.JPanel {
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.selectAllMenuItem.text")); // NOI18N selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.selectAllMenuItem.text")); // NOI18N
rightClickMenu.add(selectAllMenuItem); rightClickMenu.add(selectAllMenuItem);
sizeUnitComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { "Byte(s)", "KB", "MB", "GB", "TB" })); //NON-NLS sizeUnitComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { "Byte(s)", "KB", "MB", "GB", "TB" }));
sizeTextField.setValue(0); sizeTextField.setValue(0);
sizeTextField.addMouseListener(new java.awt.event.MouseAdapter() { sizeTextField.addMouseListener(new java.awt.event.MouseAdapter() {
@ -123,12 +129,14 @@ class SizeSearchPanel extends javax.swing.JPanel {
} }
}); });
sizeCompareComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { sizeCompareComboBox.setModel(new javax.swing.DefaultComboBoxModel<String>(new String[] { "equal to", "greater than", "less than" }));
NbBundle.getMessage(this.getClass(), "SizeSearchPanel.sizeCompareComboBox.equalTo"),
NbBundle.getMessage(this.getClass(), "SizeSearchPanel.sizeCompareComboBox.greaterThan"),
NbBundle.getMessage(this.getClass(), "SizeSearchPanel.sizeCompareComboBox.lessThan") }));
sizeCheckBox.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.sizeCheckBox.text")); // NOI18N sizeCheckBox.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.sizeCheckBox.text")); // NOI18N
sizeCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
sizeCheckBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
@ -157,6 +165,11 @@ class SizeSearchPanel extends javax.swing.JPanel {
this.sizeCheckBox.setSelected(true); this.sizeCheckBox.setSelected(true);
this.sizeTextField.selectAll(); // select all so user can change it easily this.sizeTextField.selectAll(); // select all so user can change it easily
}//GEN-LAST:event_sizeTextFieldMouseClicked }//GEN-LAST:event_sizeTextFieldMouseClicked
private void sizeCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sizeCheckBoxActionPerformed
setComponentsEnabled();
}//GEN-LAST:event_sizeCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JMenuItem copyMenuItem; private javax.swing.JMenuItem copyMenuItem;
private javax.swing.JMenuItem cutMenuItem; private javax.swing.JMenuItem cutMenuItem;

View File

@ -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");
@ -23,7 +23,9 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
* An implementation of a keyword search service.
* *
* TODO (AUT-2158: This interface should not extend Closeable.
*/ */
public interface KeywordSearchService extends Closeable { public interface KeywordSearchService extends Closeable {
@ -49,4 +51,4 @@ public interface KeywordSearchService extends Closeable {
*/ */
public void tryConnect(String host, int port) throws KeywordSearchServiceException; public void tryConnect(String host, int port) throws KeywordSearchServiceException;
} }

View File

@ -543,7 +543,9 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
this.mimeCheck.setSelected(false); this.mimeCheck.setSelected(false);
} else { } else {
this.extensionRadioButton.setEnabled(true); if (this.nameCheck.isSelected()) {
this.extensionRadioButton.setEnabled(true);
}
this.fileSizeCheck.setEnabled(true); this.fileSizeCheck.setEnabled(true);
this.mimeCheck.setEnabled(true); this.mimeCheck.setEnabled(true);
} }
@ -814,7 +816,9 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
} else { } else {
this.nameTextField.setEnabled(true); this.nameTextField.setEnabled(true);
this.fullNameRadioButton.setEnabled(true); this.fullNameRadioButton.setEnabled(true);
this.extensionRadioButton.setEnabled(true); if (this.filesRadioButton.isSelected()) {
this.extensionRadioButton.setEnabled(true);
}
this.nameRegexCheckbox.setEnabled(true); this.nameRegexCheckbox.setEnabled(true);
} }
this.setOkButton(); this.setOkButton();

View File

@ -44,7 +44,7 @@ public final class OpenHelpAction implements ActionListener {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
Desktop.getDesktop().browse(URI.create("http://sleuthkit.org/autopsy/docs/user-docs/4.0/image_gallery_page.html")); //NON-NLS Desktop.getDesktop().browse(URI.create("http://sleuthkit.org/autopsy/docs/user-docs/4.1/image_gallery_page.html")); //NON-NLS
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(OpenHelpAction.class.getName()).log(Level.SEVERE, "failed to open help page", ex); //NON-NLS Logger.getLogger(OpenHelpAction.class.getName()).log(Level.SEVERE, "failed to open help page", ex); //NON-NLS
} }

View File

@ -59,7 +59,6 @@ AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody=Keyword list is empt
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />Try again later. Index is updated every {0} minutes.</html> AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />Try again later. Index is updated every {0} minutes.</html>
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module enabled. </html> AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module enabled. </html>
ExtractedContentPanel.setMarkup.panelTxt=<span style\='font-style\:italic'>Loading text... Please wait</span> ExtractedContentPanel.setMarkup.panelTxt=<span style\='font-style\:italic'>Loading text... Please wait</span>
ExtractedContentViewer.toString=Extracted Text
ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer. ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer.
ExtractedContentViewer.getTitle=Indexed Text ExtractedContentViewer.getTitle=Indexed Text
ExtractedContentViewer.getSolrContent.knownFileMsg=<p style\=''font-style\:italic''>{0} is a known file (based on MD5 hash) and does not have text in the index.</p> ExtractedContentViewer.getSolrContent.knownFileMsg=<p style\=''font-style\:italic''>{0} is a known file (based on MD5 hash) and does not have text in the index.</p>

View File

@ -47,7 +47,6 @@ AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody=\u30ad\u30fc\u30ef\u
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u307e\u3060\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002<br />\u3057\u3070\u3089\u304f\u3057\u3066\u304b\u3089\u518d\u5ea6\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f{0}\u5206\u3054\u3068\u306b\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002</html> AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u307e\u3060\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002<br />\u3057\u3070\u3089\u304f\u3057\u3066\u304b\u3089\u518d\u5ea6\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306f{0}\u5206\u3054\u3068\u306b\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002</html>
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002<br />\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u6709\u52b9\u5316\u3057\u3066\u30a4\u30e1\u30fc\u30b8\u3092\u518d\u5ea6\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3002</html> AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002<br />\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u6709\u52b9\u5316\u3057\u3066\u30a4\u30e1\u30fc\u30b8\u3092\u518d\u5ea6\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3002</html>
ExtractedContentPanel.setMarkup.panelTxt=<span style\='font-style\:italic'>\u30c6\u30ad\u30b9\u30c8\u30ed\u30fc\u30c9\u4e2d...\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002</span> ExtractedContentPanel.setMarkup.panelTxt=<span style\='font-style\:italic'>\u30c6\u30ad\u30b9\u30c8\u30ed\u30fc\u30c9\u4e2d...\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002</span>
ExtractedContentViewer.toString=\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8
ExtractedContentViewer.toolTip=\u30d5\u30a1\u30a4\u30eb\u3084\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u7d50\u679c\u304b\u3089\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a\u3002\u3053\u306e\u30d3\u30e5\u30fc\u30a2\u3092\u6709\u52b9\u5316\u3059\u308b\u306b\u306f\u3001\u30d5\u30a1\u30a4\u30eb\u306b\u5bfe\u3057\u3066\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 ExtractedContentViewer.toolTip=\u30d5\u30a1\u30a4\u30eb\u3084\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u7d50\u679c\u304b\u3089\u62bd\u51fa\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a\u3002\u3053\u306e\u30d3\u30e5\u30fc\u30a2\u3092\u6709\u52b9\u5316\u3059\u308b\u306b\u306f\u3001\u30d5\u30a1\u30a4\u30eb\u306b\u5bfe\u3057\u3066\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
ExtractedContentViewer.getTitle=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8 ExtractedContentViewer.getTitle=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u5316\u3055\u308c\u305f\u30c6\u30ad\u30b9\u30c8
ExtractedContentViewer.getSolrContent.knownFileMsg=<p style\=''font-style\:italic''>{0}\u306f\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\u3067\u3059\uff08MDS\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u3068\uff09\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002</p> ExtractedContentViewer.getSolrContent.knownFileMsg=<p style\=''font-style\:italic''>{0}\u306f\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\u3067\u3059\uff08MDS\u30cf\u30c3\u30b7\u30e5\u306b\u57fa\u3065\u304f\u3068\uff09\u3002\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306b\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002</p>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-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");
@ -26,11 +26,11 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
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.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -40,8 +40,8 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
/** /**
* Displays the indexed text associated with a file or a blackboard artifact, * A content viewer that displays the indexed text associated with a file or an
* possibly marked up with HTML to highlight keyword hits. * artifact, possibly marked up with HTML to highlight keyword hits.
*/ */
@ServiceProvider(service = DataContentViewer.class, position = 4) @ServiceProvider(service = DataContentViewer.class, position = 4)
public class ExtractedContentViewer implements DataContentViewer { public class ExtractedContentViewer implements DataContentViewer {
@ -51,17 +51,26 @@ public class ExtractedContentViewer implements DataContentViewer {
private ExtractedContentPanel panel; private ExtractedContentPanel panel;
private volatile Node currentNode = null; private volatile Node currentNode = null;
private IndexedText currentSource = null; private IndexedText currentSource = null;
private final IsDirVisitor isDirVisitor = new IsDirVisitor();
/**
* Constructs a content viewer that displays the indexed text associated
* with a file or an artifact, possibly marked up with HTML to highlight
* keyword hits.
*/
public ExtractedContentViewer() { public ExtractedContentViewer() {
} }
/**
* Sets the node displayed by the content viewer.
*
* @param node The node to display
*/
@Override @Override
public void setNode(final Node selectedNode) { public void setNode(final Node node) {
/* /*
* Clear the viewer. * Clear the viewer.
*/ */
if (selectedNode == null) { if (node == null) {
currentNode = null; currentNode = null;
resetComponent(); resetComponent();
return; return;
@ -71,50 +80,88 @@ public class ExtractedContentViewer implements DataContentViewer {
* This deals with the known bug with an unknown cause where setNode is * This deals with the known bug with an unknown cause where setNode is
* sometimes called twice for the same node. * sometimes called twice for the same node.
*/ */
if (selectedNode == currentNode) { if (node == currentNode) {
return; return;
} else { } else {
currentNode = selectedNode; currentNode = node;
} }
/* /*
* Assemble a collection of all of the "sources" of extracted and * Assemble a collection of all of the indexed text "sources" associated
* indexed text to present in a paged display. First look for the text * with the node.
* marked up with HTML to highlight keyword hits that will be present if
* the node is a keyword hit blakcboard artifact.
*/ */
final List<IndexedText> sources = new ArrayList<>(); IndexedText highlightedHitText = null;
sources.addAll(selectedNode.getLookup().lookupAll(IndexedText.class)); IndexedText rawContentText = null;
IndexedText rawArtifactText = null;
List<IndexedText> sources = new ArrayList<>();
/* /*
* Now look for the "raw" extracted text if this is a node for another * First add the text marked up with HTML to highlight keyword hits that
* type of artifact or for content. * will be present in the selected node's lookup if the node is for a
* keyword hit artifact.
*/ */
long documentID = getDocumentId(currentNode); sources.addAll(node.getLookup().lookupAll(IndexedText.class));
if (INVALID_DOCUMENT_ID == documentID) { if (!sources.isEmpty()) {
setPanel(sources); highlightedHitText = sources.get(0);
return;
} }
IndexedText rawSource;
if (documentID > INVALID_DOCUMENT_ID) { /*
// Add a content item * Next, add the "raw" (not highlighted) text, if any, for any content
Content content = currentNode.getLookup().lookup(Content.class); * associated with the node.
rawSource = new RawText(content, content.getId()); */
Content content = currentNode.getLookup().lookup(Content.class);
if (null != content && solrHasContent(content.getId())) {
rawContentText = new RawText(content, content.getId());
sources.add(rawContentText);
}
/*
* Finally, add the "raw" (not highlighted) text, if any, for any
* artifact associated with the node.
*/
BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
if (null != artifact) {
/*
* For keyword hit artifacts, add the text of the artifact that hit,
* not the hit artifact; otherwise add the text for the artifact.
*/
if (artifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
rawArtifactText = new RawText(artifact, artifact.getArtifactID());
sources.add(rawArtifactText);
} else {
try {
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
if (attribute != null) {
long artifactId = attribute.getValueLong();
BlackboardArtifact associatedArtifact = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifact(artifactId);
rawArtifactText = new RawText(associatedArtifact, associatedArtifact.getArtifactID());
sources.add(rawArtifactText);
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting associated artifact attributes", ex); //NON-NLS
}
}
}
/*
* Now set the default source to be displayed.
*/
if (null != highlightedHitText) {
currentSource = highlightedHitText;
} else if (null != rawContentText) {
currentSource = rawContentText;
} else { } else {
// Add an artifact item currentSource = rawArtifactText;
BlackboardArtifact blackboardArtifact = currentNode.getLookup().lookup(BlackboardArtifact.class);
rawSource = new RawText(blackboardArtifact, documentID);
} }
currentSource = rawSource;
sources.add(rawSource);
/* /*
* Initialize the pages for the sources. The first source in the list * Push the text sources into the panel.
* of sources will be displayed.
*/ */
int currentPage = currentSource.getCurrentPage(); for (IndexedText source : sources) {
if (currentPage == 0 && currentSource.hasNextPage()) { int currentPage = source.getCurrentPage();
currentSource.nextPage(); if (currentPage == 0 && source.hasNextPage()) {
source.nextPage();
}
} }
updatePageControls(); updatePageControls();
setPanel(sources); setPanel(sources);
@ -288,8 +335,8 @@ public class ExtractedContentViewer implements DataContentViewer {
/* /*
* For keyword search hit artifact nodes and all other nodes, the * For keyword search hit artifact nodes and all other nodes, the
* document ID for the extracted text is the ID of the associated * document ID for the extracted text is the ID of the associated
* content, if any, unless there is an associated artifact, which * content, if any, unless there is an associated artifact, which is
* is handled above. * handled above.
*/ */
Content content = node.getLookup().lookup(Content.class); Content content = node.getLookup().lookup(Content.class);
if (content != null) { if (content != null) {

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-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");
@ -30,8 +30,8 @@ import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
/** /**
* Display content with just raw text * A "source" for the extracted content viewer that displays "raw" (not
* * highlighted) indexed text for a file or an artifact.
*/ */
class RawText implements IndexedText { class RawText implements IndexedText {
@ -151,17 +151,24 @@ class RawText implements IndexedText {
if (this.content != null) { if (this.content != null) {
return getContentText(currentPage, hasChunks); return getContentText(currentPage, hasChunks);
} else if (this.blackboardArtifact != null) { } else if (this.blackboardArtifact != null) {
return KeywordSearch.getServer().getSolrContent(this.objectId, 1); return getArtifactText();
} }
} catch (SolrServerException | NoOpenCoreException ex) { } catch (SolrServerException ex) {
logger.log(Level.WARNING, "Couldn't get extracted content.", ex); //NON-NLS logger.log(Level.SEVERE, "Couldn't get extracted content", ex); //NON-NLS
} }
return NbBundle.getMessage(this.getClass(), "RawText.getText.error.msg"); return NbBundle.getMessage(this.getClass(), "RawText.getText.error.msg");
} }
@NbBundle.Messages({
"RawText.FileText=File Text",
"RawText.ResultText=Result Text"})
@Override @Override
public String toString() { public String toString() {
return NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.toString"); if (null != content) {
return Bundle.RawText_FileText();
} else {
return Bundle.RawText_ResultText();
}
} }
@Override @Override
@ -267,9 +274,23 @@ class RawText implements IndexedText {
cachedString = sb.toString(); cachedString = sb.toString();
cachedChunk = chunkId; cachedChunk = chunkId;
} catch (NoOpenCoreException ex) { } catch (NoOpenCoreException ex) {
logger.log(Level.WARNING, "Couldn't get text content.", ex); //NON-NLS logger.log(Level.SEVERE, "No open core", ex); //NON-NLS
return ""; return "";
} }
return cachedString; return cachedString;
} }
private String getArtifactText() throws SolrServerException{
try {
String indexedText = KeywordSearch.getServer().getSolrContent(this.objectId, 1);
indexedText = EscapeUtil.escapeHtml(indexedText).trim();
StringBuilder sb = new StringBuilder(indexedText.length() + 20);
sb.append("<pre>").append(indexedText).append("</pre>"); //NON-NLS
return sb.toString();
} catch (NoOpenCoreException ex) {
logger.log(Level.SEVERE, "No open core", ex); //NON-NLS
return "";
}
}
} }