mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Reformatted code.
This commit is contained in:
parent
c9d0ace569
commit
d6e0366c73
@ -20,6 +20,7 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException;
|
||||
|
||||
/**
|
||||
@ -51,7 +52,8 @@ class AbstractFileChunk {
|
||||
return Server.getChunkIdString(this.parent.getSourceFile().getId(), this.chunkID);
|
||||
}
|
||||
|
||||
public boolean index(Ingester ingester, byte[] content, long contentSize, Charset indexCharset) throws IngesterException {
|
||||
public boolean index(Ingester ingester, byte[] content, long contentSize, Charset indexCharset)
|
||||
throws IngesterException {
|
||||
boolean success = true;
|
||||
ByteContentStream bcs = new ByteContentStream(content, contentSize, parent.getSourceFile(), indexCharset);
|
||||
try {
|
||||
@ -59,9 +61,11 @@ class AbstractFileChunk {
|
||||
//logger.log(Level.INFO, "Ingesting string chunk: " + this.getName() + ": " + chunkID);
|
||||
} catch (Exception ingEx) {
|
||||
success = false;
|
||||
throw new IngesterException("Problem ingesting file string chunk: " + parent.getSourceFile().getId() + ", chunk: " + chunkID, ingEx);
|
||||
throw new IngesterException("Problem ingesting file string chunk: "
|
||||
+ parent.getSourceFile().getId()
|
||||
+ ", chunk: " + chunkID, ingEx);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
@ -37,44 +38,46 @@ interface AbstractFileExtract {
|
||||
|
||||
EXTRACT_UTF16, ///< extract UTF16 text, possible values Boolean.TRUE.toString(), Boolean.FALSE.toString()
|
||||
EXTRACT_UTF8, ///< extract UTF8 text, possible values Boolean.TRUE.toString(), Boolean.FALSE.toString()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
//generally text extractors should ignore archives
|
||||
//and let unpacking modules take case of them
|
||||
static final List<String> ARCHIVE_MIME_TYPES =
|
||||
Arrays.asList(
|
||||
//ignore unstructured binary and compressed data, for which string extraction or unzipper works better
|
||||
"application/x-7z-compressed",
|
||||
"application/x-ace-compressed",
|
||||
"application/x-alz-compressed",
|
||||
"application/x-arj",
|
||||
"application/vnd.ms-cab-compressed",
|
||||
"application/x-cfs-compressed",
|
||||
"application/x-dgc-compressed",
|
||||
"application/x-apple-diskimage",
|
||||
"application/x-gca-compressed",
|
||||
"application/x-dar",
|
||||
"application/x-lzx",
|
||||
"application/x-lzh",
|
||||
"application/x-rar-compressed",
|
||||
"application/x-stuffit",
|
||||
"application/x-stuffitx",
|
||||
"application/x-gtar",
|
||||
"application/x-archive",
|
||||
"application/x-executable",
|
||||
"application/x-gzip",
|
||||
"application/zip",
|
||||
"application/x-zoo",
|
||||
"application/x-cpio",
|
||||
"application/x-shar",
|
||||
"application/x-tar",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-lzip",
|
||||
"application/x-lzma",
|
||||
"application/x-lzop",
|
||||
"application/x-z",
|
||||
"application/x-compress");
|
||||
//ignore unstructured binary and compressed data, for which string extraction or unzipper works better
|
||||
"application/x-7z-compressed",
|
||||
"application/x-ace-compressed",
|
||||
"application/x-alz-compressed",
|
||||
"application/x-arj",
|
||||
"application/vnd.ms-cab-compressed",
|
||||
"application/x-cfs-compressed",
|
||||
"application/x-dgc-compressed",
|
||||
"application/x-apple-diskimage",
|
||||
"application/x-gca-compressed",
|
||||
"application/x-dar",
|
||||
"application/x-lzx",
|
||||
"application/x-lzh",
|
||||
"application/x-rar-compressed",
|
||||
"application/x-stuffit",
|
||||
"application/x-stuffitx",
|
||||
"application/x-gtar",
|
||||
"application/x-archive",
|
||||
"application/x-executable",
|
||||
"application/x-gzip",
|
||||
"application/zip",
|
||||
"application/x-zoo",
|
||||
"application/x-cpio",
|
||||
"application/x-shar",
|
||||
"application/x-tar",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-lzip",
|
||||
"application/x-lzma",
|
||||
"application/x-lzop",
|
||||
"application/x-z",
|
||||
"application/x-compress");
|
||||
|
||||
/**
|
||||
* Get number of chunks resulted from extracting this AbstractFile
|
||||
@ -143,9 +146,9 @@ interface AbstractFileExtract {
|
||||
* Determines if the file content is supported by the extractor if
|
||||
* isContentTypeSpecific() returns true.
|
||||
*
|
||||
* @param file to test if its content should be supported
|
||||
* @param file to test if its content should be supported
|
||||
* @param detectedFormat mime-type with detected format (such as text/plain)
|
||||
* or null if not detected
|
||||
* or null if not detected
|
||||
* @return true if the file content is supported, false otherwise
|
||||
*/
|
||||
boolean isSupported(AbstractFile file, String detectedFormat);
|
||||
|
@ -26,6 +26,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
||||
import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException;
|
||||
@ -37,7 +38,7 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
* divided into chunks and indexed with Solr. If HTML extraction succeeds,
|
||||
* chunks are indexed with Solr.
|
||||
*/
|
||||
class AbstractFileHtmlExtract implements AbstractFileExtract {
|
||||
class AbstractFileHtmlExtract implements AbstractFileExtract {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AbstractFileHtmlExtract.class.getName());
|
||||
static final Charset outCharset = Server.DEFAULT_INDEXED_TEXT_CHARSET;
|
||||
@ -58,7 +59,7 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
"text/html",
|
||||
"text/javascript" //"application/xml",
|
||||
//"application/xml-dtd",
|
||||
);
|
||||
);
|
||||
private final TikaLanguageIdentifier tikaLanguageIdentifier;
|
||||
|
||||
AbstractFileHtmlExtract() {
|
||||
@ -189,10 +190,12 @@ import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
module.checkRunCommitSearch();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Unable to read content stream from " + sourceFile.getId() + ": " + sourceFile.getName(), ex);
|
||||
logger.log(Level.WARNING, "Unable to read content stream from "
|
||||
+ sourceFile.getId() + ": " + sourceFile.getName(), ex);
|
||||
success = false;
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Unexpected error, can't read content stream from " + sourceFile.getId() + ": " + sourceFile.getName(), ex);
|
||||
logger.log(Level.WARNING, "Unexpected error, can't read content stream from "
|
||||
+ sourceFile.getId() + ": " + sourceFile.getName(), ex);
|
||||
success = false;
|
||||
} finally {
|
||||
try {
|
||||
|
@ -23,6 +23,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.apache.solr.common.util.ContentStream;
|
||||
import org.sleuthkit.datamodel.AbstractContent;
|
||||
@ -31,7 +32,7 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
/**
|
||||
* Wrapper over InputStream that implements ContentStream to feed to Solr.
|
||||
*/
|
||||
class AbstractFileStringContentStream implements ContentStream {
|
||||
class AbstractFileStringContentStream implements ContentStream {
|
||||
//input
|
||||
|
||||
private AbstractFile content;
|
||||
@ -69,7 +70,8 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
@Override
|
||||
public Long getSize() {
|
||||
//return convertedLength;
|
||||
throw new UnsupportedOperationException("Cannot tell how many chars in converted string, until entire string is converted");
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot tell how many chars in converted string, until entire string is converted");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,7 +87,7 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
|
||||
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
||||
import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException;
|
||||
@ -51,7 +52,7 @@ class AbstractFileStringExtract implements AbstractFileExtract {
|
||||
private static final SCRIPT DEFAULT_SCRIPT = SCRIPT.LATIN_2;
|
||||
private final List<SCRIPT> extractScripts = new ArrayList<SCRIPT>();
|
||||
private Map<String, String> extractOptions = new HashMap<String, String>();
|
||||
|
||||
|
||||
|
||||
//disabled prepending of BOM
|
||||
//static {
|
||||
@ -132,7 +133,8 @@ class AbstractFileStringExtract implements AbstractFileExtract {
|
||||
//break input stream into chunks
|
||||
|
||||
long readSize = 0;
|
||||
while ((readSize = stringStream.read(STRING_CHUNK_BUF, BOM_LEN, (int) MAX_STRING_CHUNK_SIZE - BOM_LEN)) != -1) {
|
||||
while ((readSize = stringStream.read(STRING_CHUNK_BUF, BOM_LEN, (int) MAX_STRING_CHUNK_SIZE - BOM_LEN))
|
||||
!= -1) {
|
||||
//FileOutputStream debug = new FileOutputStream("c:\\temp\\" + sourceFile.getName() + Integer.toString(this.numChunks+1));
|
||||
//debug.write(STRING_CHUNK_BUF, 0, (int)readSize);
|
||||
|
||||
@ -143,7 +145,9 @@ class AbstractFileStringExtract implements AbstractFileExtract {
|
||||
++this.numChunks;
|
||||
} catch (IngesterException ingEx) {
|
||||
success = false;
|
||||
logger.log(Level.WARNING, "Ingester had a problem with extracted strings from file '" + sourceFile.getName() + "' (id: " + sourceFile.getId() + ").", ingEx);
|
||||
logger.log(Level.WARNING,
|
||||
"Ingester had a problem with extracted strings from file '" + sourceFile.getName()
|
||||
+ "' (id: " + sourceFile.getId() + ").", ingEx);
|
||||
throw ingEx; //need to rethrow/return to signal error and move on
|
||||
}
|
||||
|
||||
@ -159,7 +163,8 @@ class AbstractFileStringExtract implements AbstractFileExtract {
|
||||
ingester.ingest(this);
|
||||
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Unable to read input stream to divide and send to Solr, file: " + sourceFile.getName(), ex);
|
||||
logger.log(Level.WARNING,
|
||||
"Unable to read input stream to divide and send to Solr, file: " + sourceFile.getName(), ex);
|
||||
success = false;
|
||||
} finally {
|
||||
try {
|
||||
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractResult;
|
||||
@ -33,16 +34,17 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* Wrapper over StringExtract to provide streaming API Given AbstractFile
|
||||
* object, extract international strings from the file and read output as a
|
||||
* stream of UTF-8 strings as encoded bytes.
|
||||
*
|
||||
* <p/>
|
||||
* Currently not-thread safe (reusing static buffers for efficiency)
|
||||
*/
|
||||
class AbstractFileStringIntStream extends InputStream {
|
||||
class AbstractFileStringIntStream extends InputStream {
|
||||
|
||||
private AbstractFile content;
|
||||
private final byte[] oneCharBuf = new byte[1];
|
||||
private final StringExtract stringExtractor;
|
||||
private static final int FILE_BUF_SIZE = 1024 * 1024;
|
||||
private static final byte[] fileReadBuff = new byte[FILE_BUF_SIZE]; //NOTE: need to run all stream extraction in same thread
|
||||
private static final byte[] fileReadBuff = new byte[FILE_BUF_SIZE];
|
||||
//NOTE: need to run all stream extraction in same thread
|
||||
private long fileReadOffset = 0L;
|
||||
private byte[] convertBuff; //stores extracted string encoded as bytes, before returned to user
|
||||
private int convertBuffOffset = 0; //offset to start returning data to user on next read()
|
||||
@ -59,14 +61,14 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* strings, then to byte stream, for specified script, auto-detected encoding
|
||||
* (UTF8, UTF16LE, UTF16BE), and specified output byte stream encoding
|
||||
*
|
||||
* @param content input content to process and turn into a stream to convert into strings
|
||||
* @param scripts a list of scripts to consider
|
||||
* @param extractUTF8 whether to extract utf8 encoding
|
||||
* @param content input content to process and turn into a stream to convert into strings
|
||||
* @param scripts a list of scripts to consider
|
||||
* @param extractUTF8 whether to extract utf8 encoding
|
||||
* @param extractUTF16 whether to extract utf16 encoding
|
||||
* @param outCharset encoding to use in the output byte stream
|
||||
* @param outCharset encoding to use in the output byte stream
|
||||
*/
|
||||
public AbstractFileStringIntStream(AbstractFile content, List<SCRIPT> scripts, boolean extractUTF8,
|
||||
boolean extractUTF16, Charset outCharset) {
|
||||
public AbstractFileStringIntStream(AbstractFile content, List<SCRIPT> scripts, boolean extractUTF8,
|
||||
boolean extractUTF16, Charset outCharset) {
|
||||
this.content = content;
|
||||
this.stringExtractor = new StringExtract();
|
||||
this.stringExtractor.setEnabledScripts(scripts);
|
||||
@ -100,7 +102,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (extractUTF8 == false && extractUTF16 == false) {
|
||||
return -1;
|
||||
}
|
||||
@ -124,22 +126,22 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
//convert more strings, store in buffer
|
||||
long toRead = 0;
|
||||
//int shiftSize = 0;
|
||||
|
||||
|
||||
//if (lastExtractResult != null && lastExtractResult.getTextLength() != 0
|
||||
// && (shiftSize = FILE_BUF_SIZE - lastExtractResult.getFirstUnprocessedOff()) > 0) {
|
||||
////a string previously extracted
|
||||
////shift the fileReadBuff past last bytes extracted
|
||||
////read only what's needed to fill the buffer
|
||||
////to avoid loosing chars and breaking or corrupting potential strings - preserve byte stream continuity
|
||||
//byte[] temp = new byte[shiftSize];
|
||||
//System.arraycopy(fileReadBuff, lastExtractResult.getFirstUnprocessedOff(),
|
||||
// temp, 0, shiftSize);
|
||||
//System.arraycopy(temp, 0, fileReadBuff, 0, shiftSize);
|
||||
//toRead = Math.min(lastExtractResult.getFirstUnprocessedOff(), fileSize - fileReadOffset);
|
||||
//lastExtractResult = null;
|
||||
// && (shiftSize = FILE_BUF_SIZE - lastExtractResult.getFirstUnprocessedOff()) > 0) {
|
||||
////a string previously extracted
|
||||
////shift the fileReadBuff past last bytes extracted
|
||||
////read only what's needed to fill the buffer
|
||||
////to avoid loosing chars and breaking or corrupting potential strings - preserve byte stream continuity
|
||||
//byte[] temp = new byte[shiftSize];
|
||||
//System.arraycopy(fileReadBuff, lastExtractResult.getFirstUnprocessedOff(),
|
||||
// temp, 0, shiftSize);
|
||||
//System.arraycopy(temp, 0, fileReadBuff, 0, shiftSize);
|
||||
//toRead = Math.min(lastExtractResult.getFirstUnprocessedOff(), fileSize - fileReadOffset);
|
||||
//lastExtractResult = null;
|
||||
//} else {
|
||||
//fill up entire fileReadBuff fresh
|
||||
toRead = Math.min(FILE_BUF_SIZE, fileSize - fileReadOffset);
|
||||
//fill up entire fileReadBuff fresh
|
||||
toRead = Math.min(FILE_BUF_SIZE, fileSize - fileReadOffset);
|
||||
//}
|
||||
int read = content.read(fileReadBuff, fileReadOffset, toRead);
|
||||
if (read == -1 || read == 0) {
|
||||
@ -173,7 +175,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
//return part or all of convert buff to user
|
||||
final int toCopy = Math.min(convertBuffRemain, len - offsetUser);
|
||||
System.arraycopy(convertBuff, convertBuffOffset, b, offsetUser, toCopy);
|
||||
|
||||
|
||||
//DEBUG
|
||||
/*
|
||||
if (toCopy > 0) {
|
||||
@ -182,12 +184,12 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
debug.close();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
convertBuffOffset += toCopy;
|
||||
offsetUser += toCopy;
|
||||
|
||||
bytesToUser += toCopy;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//if more string data in convertBuff, will be consumed on next read()
|
||||
|
@ -21,22 +21,23 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
* AbstractFile input string stream reader/converter - given AbstractFile,
|
||||
* AbstractFile input string stream reader/converter - given AbstractFile,
|
||||
* extract strings from it and return encoded bytes via read()
|
||||
*
|
||||
* <p/>
|
||||
* Note: the utility supports extraction of only LATIN script and UTF8, UTF16LE, UTF16BE encodings
|
||||
* and uses a brute force encoding detection - it's fast but could apply multiple encodings on the same string.
|
||||
*
|
||||
* <p/>
|
||||
* For other script/languages support and better encoding detection use AbstractFileStringIntStream streaming class,
|
||||
* which wraps around StringExtract extractor.
|
||||
*/
|
||||
class AbstractFileStringStream extends InputStream {
|
||||
class AbstractFileStringStream extends InputStream {
|
||||
|
||||
//args
|
||||
private AbstractFile content;
|
||||
@ -53,7 +54,8 @@ import org.sleuthkit.datamodel.TskException;
|
||||
private int tempStringLen = 0;
|
||||
private boolean isEOF = false;
|
||||
private boolean stringAtTempBoundary = false; //if temp has part of string that didn't make it in previous read()
|
||||
private boolean stringAtBufBoundary = false; //if read buffer has string being processed, continue as string from prev read() in next read()
|
||||
private boolean stringAtBufBoundary = false;
|
||||
//if read buffer has string being processed, continue as string from prev read() in next read()
|
||||
private boolean inString = false; //if current temp has min chars required
|
||||
private static final byte[] oneCharBuf = new byte[1];
|
||||
private final int MIN_PRINTABLE_CHARS = 4; //num. of chars needed to qualify as a char string
|
||||
@ -63,12 +65,12 @@ import org.sleuthkit.datamodel.TskException;
|
||||
/**
|
||||
* Construct new string stream from FsContent
|
||||
*
|
||||
* @param content to extract strings from
|
||||
* @param outputCharset target encoding to index as
|
||||
* @param content to extract strings from
|
||||
* @param outputCharset target encoding to index as
|
||||
* @param preserveOnBuffBoundary whether to preserve or split string on a
|
||||
* buffer boundary. If false, will pack into read buffer up to max.
|
||||
* possible, potentially splitting a string. If false, the string will be
|
||||
* preserved for next read.
|
||||
* buffer boundary. If false, will pack into read buffer up to max.
|
||||
* possible, potentially splitting a string. If false, the string will be
|
||||
* preserved for next read.
|
||||
*/
|
||||
public AbstractFileStringStream(AbstractFile content, Charset outputCharset, boolean preserveOnBuffBoundary) {
|
||||
this.content = content;
|
||||
@ -81,7 +83,7 @@ import org.sleuthkit.datamodel.TskException;
|
||||
* Construct new string stream from FsContent Do not attempt to fill entire
|
||||
* read buffer if that would break a string
|
||||
*
|
||||
* @param content to extract strings from
|
||||
* @param content to extract strings from
|
||||
* @param outCharset target charset to encode into bytes and index as, e.g. UTF-8
|
||||
*/
|
||||
public AbstractFileStringStream(AbstractFile content, Charset outCharset) {
|
||||
|
@ -34,6 +34,7 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
@ -55,10 +56,9 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* divided into chunks and indexed with Solr. Protects against Tika parser hangs
|
||||
* (for unexpected/corrupt content) using a timeout mechanism. If Tika
|
||||
* extraction succeeds, chunks are indexed with Solr.
|
||||
*
|
||||
* <p/>
|
||||
* This Tika extraction/chunking utility is useful for large files of Tika
|
||||
* parsers-supported content type.
|
||||
*
|
||||
*/
|
||||
class AbstractFileTikaTextExtract implements AbstractFileExtract {
|
||||
|
||||
@ -139,13 +139,15 @@ class AbstractFileTikaTextExtract implements AbstractFileExtract {
|
||||
future.get(Ingester.getTimeout(sourceFile.getSize()), TimeUnit.SECONDS);
|
||||
} catch (TimeoutException te) {
|
||||
tika = null;
|
||||
final String msg = "Exception: Tika parse timeout for content: " + sourceFile.getId() + ", " + sourceFile.getName();
|
||||
final String msg = "Exception: Tika parse timeout for content: " + sourceFile.getId() + ", "
|
||||
+ sourceFile.getName();
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING, msg, te);
|
||||
logger.log(Level.WARNING, msg);
|
||||
throw new IngesterException(msg);
|
||||
} catch (Exception ex) {
|
||||
tika = null;
|
||||
final String msg = "Exception: Unexpected exception from Tika parse task execution for file: " + sourceFile.getId() + ", " + sourceFile.getName();
|
||||
final String msg = "Exception: Unexpected exception from Tika parse task execution for file: "
|
||||
+ sourceFile.getId() + ", " + sourceFile.getName();
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING, msg, ex);
|
||||
logger.log(Level.WARNING, msg);
|
||||
throw new IngesterException(msg);
|
||||
@ -242,12 +244,14 @@ class AbstractFileTikaTextExtract implements AbstractFileExtract {
|
||||
module.checkRunCommitSearch();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
final String msg = "Exception: Unable to read Tika content stream from " + sourceFile.getId() + ": " + sourceFile.getName();
|
||||
final String msg = "Exception: Unable to read Tika content stream from " + sourceFile.getId() + ": "
|
||||
+ sourceFile.getName();
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING, msg, ex);
|
||||
logger.log(Level.WARNING, msg);
|
||||
success = false;
|
||||
} catch (Exception ex) {
|
||||
final String msg = "Exception: Unexpected error, can't read Tika content stream from " + sourceFile.getId() + ": " + sourceFile.getName();
|
||||
final String msg = "Exception: Unexpected error, can't read Tika content stream from " + sourceFile.getId()
|
||||
+ ": " + sourceFile.getName();
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING, msg, ex);
|
||||
logger.log(Level.WARNING, msg);
|
||||
success = false;
|
||||
@ -327,11 +331,15 @@ class AbstractFileTikaTextExtract implements AbstractFileExtract {
|
||||
try {
|
||||
reader = tika.parse(stream, meta);
|
||||
} catch (IOException ex) {
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING, "Exception: Unable to Tika parse the content" + sourceFile.getId() + ": " + sourceFile.getName(), ex);
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING,
|
||||
"Exception: Unable to Tika parse the content" + sourceFile.getId()
|
||||
+ ": " + sourceFile.getName(), ex);
|
||||
tika = null;
|
||||
reader = null;
|
||||
} catch (Exception ex) {
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING, "Exception: Unable to Tika parse the content" + sourceFile.getId() + ": " + sourceFile.getName(), ex);
|
||||
KeywordSearch.getTikaLogger().log(Level.WARNING,
|
||||
"Exception: Unable to Tika parse the content" + sourceFile.getId()
|
||||
+ ": " + sourceFile.getName(), ex);
|
||||
tika = null;
|
||||
reader = null;
|
||||
}
|
||||
|
@ -33,7 +33,8 @@ import org.openide.util.NbBundle;
|
||||
*/
|
||||
abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel implements KeywordSearchPerformerInterface {
|
||||
|
||||
private final String keywordSearchErrorDialogHeader = org.openide.util.NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.dialogErrorHeader");
|
||||
private final String keywordSearchErrorDialogHeader = org.openide.util.NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.dialogErrorHeader");
|
||||
protected int filesIndexed;
|
||||
|
||||
AbstractKeywordSearchPerformer() {
|
||||
@ -86,19 +87,26 @@ abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel impleme
|
||||
if (filesIndexed == 0) {
|
||||
if (isRunning) {
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.noFilesInIdxMsg",
|
||||
KeywordSearchSettings.getUpdateFrequency().getTime()), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
"AbstractKeywordSearchPerformer.search.noFilesInIdxMsg",
|
||||
KeywordSearchSettings
|
||||
.getUpdateFrequency()
|
||||
.getTime()),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
} else {
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.noFilesIdxdMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
"AbstractKeywordSearchPerformer.search.noFilesIdxdMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//check if keyword search module ingest is running (indexing, etc)
|
||||
if (isRunning) {
|
||||
if (KeywordSearchUtil.displayConfirmDialog(org.openide.util.NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "AbstractKeywordSearchPerformer.search.ingestInProgressBody"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN) == false) {
|
||||
if (KeywordSearchUtil.displayConfirmDialog(org.openide.util.NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.searchIngestInProgressTitle"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.ingestInProgressBody"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN) == false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -108,8 +116,8 @@ abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel impleme
|
||||
final List<Keyword> keywords = getQueryList();
|
||||
if (keywords.isEmpty()) {
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
"AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
return;
|
||||
}
|
||||
man = new KeywordSearchQueryManager(keywords, Presentation.FLAT);
|
||||
@ -123,7 +131,8 @@ abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel impleme
|
||||
final String queryText = getQueryText();
|
||||
if (queryText == null || queryText.trim().equals("")) {
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.pleaseEnterKeywordBody"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
"AbstractKeywordSearchPerformer.search.pleaseEnterKeywordBody"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
return;
|
||||
}
|
||||
man = new KeywordSearchQueryManager(getQueryText(), queryType, Presentation.FLAT);
|
||||
@ -133,7 +142,8 @@ abstract class AbstractKeywordSearchPerformer extends javax.swing.JPanel impleme
|
||||
man.execute();
|
||||
} else {
|
||||
KeywordSearchUtil.displayDialog(keywordSearchErrorDialogHeader, NbBundle.getMessage(this.getClass(),
|
||||
"AbstractKeywordSearchPerformer.search.invalidSyntaxHeader"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
"AbstractKeywordSearchPerformer.search.invalidSyntaxHeader"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.apache.solr.common.util.ContentStream;
|
||||
import org.sleuthkit.datamodel.AbstractContent;
|
||||
@ -32,30 +33,30 @@ import org.sleuthkit.datamodel.AbstractContent;
|
||||
* Stream of bytes representing string with specified encoding
|
||||
* to feed into Solr as ContentStream
|
||||
*/
|
||||
class ByteContentStream implements ContentStream {
|
||||
|
||||
|
||||
class ByteContentStream implements ContentStream {
|
||||
|
||||
|
||||
//input
|
||||
private byte[] content; //extracted subcontent
|
||||
private long contentSize;
|
||||
private AbstractContent aContent; //origin
|
||||
private Charset charset; //output byte stream charset of encoded strings
|
||||
|
||||
|
||||
private InputStream stream;
|
||||
|
||||
private static Logger logger = Logger.getLogger(ByteContentStream.class.getName());
|
||||
|
||||
public ByteContentStream(byte [] content, long contentSize, AbstractContent aContent, Charset charset) {
|
||||
public ByteContentStream(byte[] content, long contentSize, AbstractContent aContent, Charset charset) {
|
||||
this.content = content;
|
||||
this.aContent = aContent;
|
||||
this.charset = charset;
|
||||
stream = new ByteArrayInputStream(content, 0, (int)contentSize);
|
||||
stream = new ByteArrayInputStream(content, 0, (int) contentSize);
|
||||
}
|
||||
|
||||
public byte[] getByteContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
public AbstractContent getSourceContent() {
|
||||
return aContent;
|
||||
}
|
||||
@ -95,10 +96,9 @@ class ByteContentStream implements ContentStream {
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
|
||||
|
||||
stream.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
@ -85,8 +86,9 @@ class ContentHit {
|
||||
|
||||
/**
|
||||
* Identify the list of files with the first chunk that has a hit
|
||||
*
|
||||
* @param hits
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
static Map<AbstractFile, Integer> flattenResults(List<ContentHit> hits) {
|
||||
Map<AbstractFile, Integer> ret = new LinkedHashMap<AbstractFile, Integer>();
|
||||
@ -99,7 +101,7 @@ class ContentHit {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//flatten results to get unique AbstractFile per hit, with first chunk id encountered
|
||||
static LinkedHashMap<AbstractFile, Integer> flattenResults(Map<String, List<ContentHit>> results) {
|
||||
LinkedHashMap<AbstractFile, Integer> flattened = new LinkedHashMap<AbstractFile, Integer>();
|
||||
|
@ -29,6 +29,7 @@ import java.util.List;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.SizeRequirements;
|
||||
@ -41,6 +42,7 @@ import javax.swing.text.html.ParagraphView;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import javax.swing.text.html.HTMLEditorKit.HTMLFactory;
|
||||
import javax.swing.text.html.StyleSheet;
|
||||
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
@ -64,7 +66,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
|
||||
|
||||
HTMLEditorKit editorKit = new HTMLEditorKit() {
|
||||
@Override
|
||||
public ViewFactory getViewFactory() {
|
||||
@ -92,7 +94,8 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
};
|
||||
} else if (v instanceof ParagraphView) {
|
||||
return new ParagraphView(e) {
|
||||
protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
|
||||
protected SizeRequirements calculateMinorAxisRequirements(int axis,
|
||||
SizeRequirements r) {
|
||||
if (r == null) {
|
||||
r = new SizeRequirements();
|
||||
}
|
||||
@ -112,12 +115,12 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// set font size manually in an effort to get fonts in this panel to look
|
||||
// similar to what is in the 'String View' content viewer.
|
||||
StyleSheet ss = editorKit.getStyleSheet();
|
||||
ss.addRule("body {font-size: 8.5px;}");
|
||||
|
||||
|
||||
extractedTextPane.setEditorKit(editorKit);
|
||||
|
||||
sourceComboBox.addItemListener(new ItemListener() {
|
||||
@ -162,176 +165,239 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
copyMenuItem = new javax.swing.JMenuItem();
|
||||
selectAllMenuItem = new javax.swing.JMenuItem();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
extractedTextPane = new JTextPane(){
|
||||
extractedTextPane = new JTextPane() {
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
return (getSize().width < 400);
|
||||
}};
|
||||
sourceComboBox = new javax.swing.JComboBox();
|
||||
hitLabel = new javax.swing.JLabel();
|
||||
hitCountLabel = new javax.swing.JLabel();
|
||||
hitOfLabel = new javax.swing.JLabel();
|
||||
hitTotalLabel = new javax.swing.JLabel();
|
||||
hitButtonsLabel = new javax.swing.JLabel();
|
||||
hitPreviousButton = new javax.swing.JButton();
|
||||
hitNextButton = new javax.swing.JButton();
|
||||
pageButtonsLabel = new javax.swing.JLabel();
|
||||
pagePreviousButton = new javax.swing.JButton();
|
||||
pageNextButton = new javax.swing.JButton();
|
||||
pagesLabel = new javax.swing.JLabel();
|
||||
pageCurLabel = new javax.swing.JLabel();
|
||||
pageOfLabel = new javax.swing.JLabel();
|
||||
pageTotalLabel = new javax.swing.JLabel();
|
||||
}
|
||||
};
|
||||
sourceComboBox = new javax.swing.JComboBox();
|
||||
hitLabel = new javax.swing.JLabel();
|
||||
hitCountLabel = new javax.swing.JLabel();
|
||||
hitOfLabel = new javax.swing.JLabel();
|
||||
hitTotalLabel = new javax.swing.JLabel();
|
||||
hitButtonsLabel = new javax.swing.JLabel();
|
||||
hitPreviousButton = new javax.swing.JButton();
|
||||
hitNextButton = new javax.swing.JButton();
|
||||
pageButtonsLabel = new javax.swing.JLabel();
|
||||
pagePreviousButton = new javax.swing.JButton();
|
||||
pageNextButton = new javax.swing.JButton();
|
||||
pagesLabel = new javax.swing.JLabel();
|
||||
pageCurLabel = new javax.swing.JLabel();
|
||||
pageOfLabel = new javax.swing.JLabel();
|
||||
pageTotalLabel = new javax.swing.JLabel();
|
||||
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.copyMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(copyMenuItem);
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.copyMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(copyMenuItem);
|
||||
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.selectAllMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(selectAllMenuItem);
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.selectAllMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(selectAllMenuItem);
|
||||
|
||||
setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
|
||||
jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
|
||||
jScrollPane1.setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
|
||||
jScrollPane1.setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
|
||||
extractedTextPane.setEditable(false);
|
||||
extractedTextPane.setAutoscrolls(false);
|
||||
extractedTextPane.setMaximumSize(new java.awt.Dimension(2000, 2000));
|
||||
extractedTextPane.setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
jScrollPane1.setViewportView(extractedTextPane);
|
||||
extractedTextPane.setEditable(false);
|
||||
extractedTextPane.setAutoscrolls(false);
|
||||
extractedTextPane.setMaximumSize(new java.awt.Dimension(2000, 2000));
|
||||
extractedTextPane.setPreferredSize(new java.awt.Dimension(700, 400));
|
||||
jScrollPane1.setViewportView(extractedTextPane);
|
||||
|
||||
sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
sourceComboBox
|
||||
.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"}));
|
||||
|
||||
hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N
|
||||
hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N
|
||||
hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitLabel.text")); // NOI18N
|
||||
hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N
|
||||
|
||||
hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
hitCountLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitCountLabel.text")); // NOI18N
|
||||
hitCountLabel.setMaximumSize(new java.awt.Dimension(18, 14));
|
||||
hitCountLabel.setMinimumSize(new java.awt.Dimension(18, 14));
|
||||
hitCountLabel.setPreferredSize(new java.awt.Dimension(18, 14));
|
||||
hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
hitCountLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitCountLabel.text")); // NOI18N
|
||||
hitCountLabel.setMaximumSize(new java.awt.Dimension(18, 14));
|
||||
hitCountLabel.setMinimumSize(new java.awt.Dimension(18, 14));
|
||||
hitCountLabel.setPreferredSize(new java.awt.Dimension(18, 14));
|
||||
|
||||
hitOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitOfLabel.text")); // NOI18N
|
||||
hitOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitOfLabel.text")); // NOI18N
|
||||
|
||||
hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
hitTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitTotalLabel.text")); // NOI18N
|
||||
hitTotalLabel.setMaximumSize(new java.awt.Dimension(18, 14));
|
||||
hitTotalLabel.setMinimumSize(new java.awt.Dimension(18, 14));
|
||||
hitTotalLabel.setPreferredSize(new java.awt.Dimension(18, 14));
|
||||
hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
hitTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitTotalLabel.text")); // NOI18N
|
||||
hitTotalLabel.setMaximumSize(new java.awt.Dimension(18, 14));
|
||||
hitTotalLabel.setMinimumSize(new java.awt.Dimension(18, 14));
|
||||
hitTotalLabel.setPreferredSize(new java.awt.Dimension(18, 14));
|
||||
|
||||
hitButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitButtonsLabel.text")); // NOI18N
|
||||
hitButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitButtonsLabel.text")); // NOI18N
|
||||
|
||||
hitPreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
|
||||
hitPreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitPreviousButton.text")); // NOI18N
|
||||
hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
hitPreviousButton.setBorderPainted(false);
|
||||
hitPreviousButton.setContentAreaFilled(false);
|
||||
hitPreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
|
||||
hitPreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
hitPreviousButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
hitPreviousButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); // NOI18N
|
||||
hitPreviousButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
|
||||
hitPreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitPreviousButton.text")); // NOI18N
|
||||
hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
hitPreviousButton.setBorderPainted(false);
|
||||
hitPreviousButton.setContentAreaFilled(false);
|
||||
hitPreviousButton.setDisabledIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
|
||||
hitPreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
hitPreviousButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
hitPreviousButton.setRolloverIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); // NOI18N
|
||||
|
||||
hitNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
|
||||
hitNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitNextButton.text")); // NOI18N
|
||||
hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
hitNextButton.setBorderPainted(false);
|
||||
hitNextButton.setContentAreaFilled(false);
|
||||
hitNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
|
||||
hitNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
hitNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
hitNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); // NOI18N
|
||||
hitNextButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
|
||||
hitNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.hitNextButton.text")); // NOI18N
|
||||
hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
hitNextButton.setBorderPainted(false);
|
||||
hitNextButton.setContentAreaFilled(false);
|
||||
hitNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource(
|
||||
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
|
||||
hitNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
hitNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
hitNextButton.setRolloverIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); // NOI18N
|
||||
|
||||
pageButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageButtonsLabel.text")); // NOI18N
|
||||
pageButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pageButtonsLabel.text")); // NOI18N
|
||||
|
||||
pagePreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
|
||||
pagePreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.text")); // NOI18N
|
||||
pagePreviousButton.setActionCommand(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.actionCommand")); // NOI18N
|
||||
pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
pagePreviousButton.setBorderPainted(false);
|
||||
pagePreviousButton.setContentAreaFilled(false);
|
||||
pagePreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
|
||||
pagePreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
pagePreviousButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N
|
||||
pagePreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pagePreviousButton.text")); // NOI18N
|
||||
pagePreviousButton.setActionCommand(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pagePreviousButton.actionCommand")); // NOI18N
|
||||
pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
pagePreviousButton.setBorderPainted(false);
|
||||
pagePreviousButton.setContentAreaFilled(false);
|
||||
pagePreviousButton.setDisabledIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N
|
||||
pagePreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
|
||||
pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
|
||||
pageNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageNextButton.text")); // NOI18N
|
||||
pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
pageNextButton.setBorderPainted(false);
|
||||
pageNextButton.setContentAreaFilled(false);
|
||||
pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
|
||||
pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
pageNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
pageNextButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N
|
||||
pageNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pageNextButton.text")); // NOI18N
|
||||
pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
pageNextButton.setBorderPainted(false);
|
||||
pageNextButton.setContentAreaFilled(false);
|
||||
pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource(
|
||||
"/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N
|
||||
pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
|
||||
pageNextButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
|
||||
pagesLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagesLabel.text")); // NOI18N
|
||||
pagesLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pagesLabel.text")); // NOI18N
|
||||
|
||||
pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageCurLabel.text")); // NOI18N
|
||||
pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pageCurLabel.text")); // NOI18N
|
||||
|
||||
pageOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageOfLabel.text")); // NOI18N
|
||||
pageOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pageOfLabel.text")); // NOI18N
|
||||
|
||||
pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
pageTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageTotalLabel.text")); // NOI18N
|
||||
pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
pageTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class,
|
||||
"ExtractedContentPanel.pageTotalLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(hitLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitOfLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitButtonsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pagesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pageCurLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pageOfLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pageTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(pageButtonsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pagePreviousButton)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 71, Short.MAX_VALUE)
|
||||
.addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(hitLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitOfLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(hitButtonsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pagesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pageCurLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pageOfLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pageTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(pageButtonsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pagePreviousButton)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 71,
|
||||
Short.MAX_VALUE)
|
||||
.addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitOfLabel)
|
||||
.addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitLabel)
|
||||
.addComponent(hitButtonsLabel))
|
||||
.addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(pageButtonsLabel)
|
||||
.addComponent(pageTotalLabel)
|
||||
.addComponent(pagesLabel)
|
||||
.addComponent(pageCurLabel)
|
||||
.addComponent(pageOfLabel))
|
||||
.addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(pagePreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(sourceComboBox,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(
|
||||
javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(hitCountLabel,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitOfLabel)
|
||||
.addComponent(hitTotalLabel,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitLabel)
|
||||
.addComponent(hitButtonsLabel))
|
||||
.addComponent(hitPreviousButton,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE, 23,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(hitNextButton,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE, 23,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGroup(layout.createParallelGroup(
|
||||
javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(pageButtonsLabel)
|
||||
.addComponent(pageTotalLabel)
|
||||
.addComponent(pagesLabel)
|
||||
.addComponent(pageCurLabel)
|
||||
.addComponent(pageOfLabel))
|
||||
.addComponent(pageNextButton,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(pagePreviousButton,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE, 23,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 293,
|
||||
Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JMenuItem copyMenuItem;
|
||||
private javax.swing.JTextPane extractedTextPane;
|
||||
@ -380,9 +446,9 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the types of mark up sources that this viewer knows about.
|
||||
* Different sources will markup the text in different ways.
|
||||
*
|
||||
* Return the types of mark up sources that this viewer knows about.
|
||||
* Different sources will markup the text in different ways.
|
||||
*
|
||||
* @return currently available sources on the panel
|
||||
*/
|
||||
public List<MarkupSource> getSources() {
|
||||
@ -395,6 +461,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Get the source selected in the combo box
|
||||
*
|
||||
* @return currently selected Source
|
||||
*/
|
||||
public MarkupSource getSelectedSource() {
|
||||
@ -438,7 +505,6 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param current, current hit to update the display with
|
||||
*/
|
||||
void updateCurrentMatchDisplay(int current) {
|
||||
@ -450,7 +516,6 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param total total number of hits to update the display with
|
||||
*/
|
||||
void updateTotaMatcheslDisplay(int total) {
|
||||
@ -462,7 +527,6 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param current, current page to update the display with
|
||||
*/
|
||||
void updateCurrentPageDisplay(int current) {
|
||||
@ -470,7 +534,6 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param total total number of pages to update the display with
|
||||
*/
|
||||
void updateTotalPageslDisplay(int total) {
|
||||
|
@ -78,8 +78,7 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
//for now, do not update second time
|
||||
if (selectedNode == currentNode) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
currentNode = selectedNode;
|
||||
}
|
||||
|
||||
@ -93,13 +92,13 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
//add additional registered sources for this node
|
||||
sources.addAll(selectedNode.getLookup().lookupAll(MarkupSource.class));
|
||||
|
||||
|
||||
|
||||
// if it doesn't have any SOLR content, then we won't add more sources
|
||||
if (solrHasContent(selectedNode) == false) {
|
||||
setPanel(sources);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Content content = selectedNode.getLookup().lookup(Content.class);
|
||||
if (content == null) {
|
||||
return;
|
||||
@ -238,10 +237,10 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
|
||||
//initialize the source
|
||||
newSource.getNumberPages();
|
||||
|
||||
|
||||
currentSource = newSource;
|
||||
sources.add(newSource);
|
||||
|
||||
|
||||
|
||||
//init pages
|
||||
int currentPage = currentSource.getCurrentPage();
|
||||
@ -399,11 +398,11 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
/**
|
||||
* Get extracted content for a node from Solr
|
||||
*
|
||||
* @param node a node that has extracted content in Solr (check with
|
||||
* solrHasContent(ContentNode))
|
||||
* @param node a node that has extracted content in Solr (check with
|
||||
* solrHasContent(ContentNode))
|
||||
* @param currentPage currently used page
|
||||
* @param hasChunks true if the content behind the node has multiple chunks.
|
||||
* This means we need to address the content pages specially.
|
||||
* @param hasChunks true if the content behind the node has multiple chunks.
|
||||
* This means we need to address the content pages specially.
|
||||
* @return the extracted content
|
||||
* @throws SolrServerException if something goes wrong
|
||||
*/
|
||||
@ -415,24 +414,25 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
int chunkId = 0;
|
||||
if (hasChunks) {
|
||||
chunkId = currentPage;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//if no chunks, it is safe to assume there is no text content
|
||||
//because we are storing extracted text in chunks only
|
||||
//and the non-chunk stores meta-data only
|
||||
String name = contentObj.getName();
|
||||
String msg = null;
|
||||
if (contentObj instanceof AbstractFile) {
|
||||
if (contentObj instanceof AbstractFile) {
|
||||
//we know it's AbstractFile, but do quick check to make sure if we index other objects in future
|
||||
boolean isKnown = FileKnown.KNOWN.equals(((AbstractFile)contentObj).getKnown());
|
||||
boolean isKnown = FileKnown.KNOWN.equals(((AbstractFile) contentObj).getKnown());
|
||||
if (isKnown && KeywordSearchSettings.getSkipKnown()) {
|
||||
msg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.knownFileMsg", name);
|
||||
msg = NbBundle
|
||||
.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.knownFileMsg", name);
|
||||
}
|
||||
}
|
||||
if (msg == null) {
|
||||
msg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.noTxtYetMsg", name);
|
||||
msg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.noTxtYetMsg", name);
|
||||
}
|
||||
String htmlMsg = NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.txtBodyItal", msg);
|
||||
String htmlMsg = NbBundle
|
||||
.getMessage(this.getClass(), "ExtractedContentViewer.getSolrContent.txtBodyItal", msg);
|
||||
return htmlMsg;
|
||||
}
|
||||
|
||||
@ -567,7 +567,7 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
panel.updateControls(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (currentSource.hasNextPage()) {
|
||||
currentSource.nextPage();
|
||||
|
||||
@ -600,7 +600,7 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
panel.updateControls(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (currentSource.hasPreviousPage()) {
|
||||
currentSource.previousPage();
|
||||
|
||||
|
@ -94,7 +94,8 @@ class HighlightedMatchesSource implements MarkupSource, HighlightLookup {
|
||||
this.hits = hits;
|
||||
}
|
||||
|
||||
HighlightedMatchesSource(Content content, String solrQuery, boolean isRegex, boolean group, Map<String, List<ContentHit>> hits) {
|
||||
HighlightedMatchesSource(Content content, String solrQuery, boolean isRegex, boolean group,
|
||||
Map<String, List<ContentHit>> hits) {
|
||||
this(content, solrQuery, isRegex, hits);
|
||||
this.group = group;
|
||||
}
|
||||
@ -345,11 +346,13 @@ class HighlightedMatchesSource implements MarkupSource, HighlightLookup {
|
||||
|
||||
final String filterQuery = Server.Schema.ID.toString() + ":" + contentIdStr;
|
||||
q.addFilterQuery(filterQuery);
|
||||
q.addHighlightField(highLightField); //for exact highlighting, try content_ws field (with stored="true" in Solr schema)
|
||||
q.addHighlightField(
|
||||
highLightField); //for exact highlighting, try content_ws field (with stored="true" in Solr schema)
|
||||
|
||||
//q.setHighlightSimplePre(HIGHLIGHT_PRE); //original highlighter only
|
||||
//q.setHighlightSimplePost(HIGHLIGHT_POST); //original highlighter only
|
||||
q.setHighlightFragsize(0); // don't fragment the highlight, works with original highlighter, or needs "single" list builder with FVH
|
||||
q.setHighlightFragsize(
|
||||
0); // don't fragment the highlight, works with original highlighter, or needs "single" list builder with FVH
|
||||
|
||||
//tune the highlighter
|
||||
q.setParam("hl.useFastVectorHighlighter", "on"); //fast highlighter scales better than standard one
|
||||
@ -439,6 +442,7 @@ class HighlightedMatchesSource implements MarkupSource, HighlightLookup {
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
//dummy instance for Lookup only
|
||||
private static HighlightLookup instance = null;
|
||||
|
||||
|
@ -32,6 +32,7 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrRequest.METHOD;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
|
||||
@ -70,10 +71,10 @@ class Ingester {
|
||||
private final Server solrServer = KeywordSearch.getServer();
|
||||
private final GetContentFieldsV getContentFieldsV = new GetContentFieldsV();
|
||||
private static Ingester instance;
|
||||
|
||||
|
||||
//for ingesting chunk as SolrInputDocument (non-content-streaming, by-pass tika)
|
||||
//TODO use a streaming way to add content to /update handler
|
||||
private final static int MAX_DOC_CHUNK_SIZE = 1024*1024;
|
||||
private final static int MAX_DOC_CHUNK_SIZE = 1024 * 1024;
|
||||
private final byte[] docChunkContentBuf = new byte[MAX_DOC_CHUNK_SIZE];
|
||||
private static final String docContentEncoding = "UTF-8";
|
||||
|
||||
@ -105,7 +106,7 @@ class Ingester {
|
||||
*
|
||||
* @param afscs File AbstractFileStringContentStream to ingest
|
||||
* @throws IngesterException if there was an error processing a specific
|
||||
* file, but the Solr server is probably fine.
|
||||
* file, but the Solr server is probably fine.
|
||||
*/
|
||||
void ingest(AbstractFileStringContentStream afscs) throws IngesterException {
|
||||
Map<String, String> params = getContentFields(afscs.getSourceContent());
|
||||
@ -121,7 +122,7 @@ class Ingester {
|
||||
*
|
||||
* @param fe AbstractFileExtract to ingest
|
||||
* @throws IngesterException if there was an error processing a specific
|
||||
* file, but the Solr server is probably fine.
|
||||
* file, but the Solr server is probably fine.
|
||||
*/
|
||||
void ingest(AbstractFileExtract fe) throws IngesterException {
|
||||
Map<String, String> params = getContentFields(fe.getSourceFile());
|
||||
@ -136,11 +137,11 @@ class Ingester {
|
||||
* added to the index. commit() should be called once you're done ingesting
|
||||
* files. AbstractFileChunk represents a file chunk and its chunk content.
|
||||
*
|
||||
* @param fec AbstractFileChunk to ingest
|
||||
* @param fec AbstractFileChunk to ingest
|
||||
* @param size approx. size of the stream in bytes, used for timeout
|
||||
* estimation
|
||||
* estimation
|
||||
* @throws IngesterException if there was an error processing a specific
|
||||
* file, but the Solr server is probably fine.
|
||||
* file, but the Solr server is probably fine.
|
||||
*/
|
||||
void ingest(AbstractFileChunk fec, ByteContentStream bcs, int size) throws IngesterException {
|
||||
AbstractContent sourceContent = bcs.getSourceContent();
|
||||
@ -148,7 +149,7 @@ class Ingester {
|
||||
|
||||
//overwrite id with the chunk id
|
||||
params.put(Server.Schema.ID.toString(),
|
||||
Server.getChunkIdString(sourceContent.getId(), fec.getChunkId()));
|
||||
Server.getChunkIdString(sourceContent.getId(), fec.getChunkId()));
|
||||
|
||||
ingest(bcs, params, size);
|
||||
}
|
||||
@ -159,11 +160,11 @@ class Ingester {
|
||||
* file is a directory or ingestContent is set to false, the file name is
|
||||
* indexed only.
|
||||
*
|
||||
* @param file File to ingest
|
||||
* @param file File to ingest
|
||||
* @param ingestContent if true, index the file and the content, otherwise
|
||||
* indesx metadata only
|
||||
* indesx metadata only
|
||||
* @throws IngesterException if there was an error processing a specific
|
||||
* file, but the Solr server is probably fine.
|
||||
* file, but the Solr server is probably fine.
|
||||
*/
|
||||
void ingest(AbstractFile file, boolean ingestContent) throws IngesterException {
|
||||
if (ingestContent == false || file.isDir()) {
|
||||
@ -189,11 +190,11 @@ class Ingester {
|
||||
private class GetContentFieldsV extends ContentVisitor.Default<Map<String, String>> {
|
||||
|
||||
private SleuthkitCase curCase = null;
|
||||
|
||||
|
||||
GetContentFieldsV() {
|
||||
curCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Map<String, String> defaultVisit(Content cntnt) {
|
||||
return new HashMap<String, String>();
|
||||
@ -205,7 +206,7 @@ class Ingester {
|
||||
getCommonFileContentFields(params, f);
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, String> visit(DerivedFile df) {
|
||||
Map<String, String> params = getCommonFields(df);
|
||||
@ -225,7 +226,7 @@ class Ingester {
|
||||
// layout files do not have times
|
||||
return getCommonFields(lf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, String> visit(LocalFile lf) {
|
||||
Map<String, String> params = getCommonFields(lf);
|
||||
@ -240,7 +241,7 @@ class Ingester {
|
||||
params.put(Server.Schema.CRTIME.toString(), ContentUtils.getStringTimeISO8601(file.getCrtime(), file));
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Map<String, String> getCommonFields(AbstractFile af) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
@ -259,31 +260,31 @@ class Ingester {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Indexing method that bypasses Tika, assumes pure text
|
||||
* It reads and converts the entire content stream to string, assuming UTF8
|
||||
* since we can't use streaming approach for Solr /update handler.
|
||||
* This should be safe, since all content is now in max 1MB chunks.
|
||||
*
|
||||
* <p/>
|
||||
* TODO see if can use a byte or string streaming way to add content to /update handler
|
||||
* e.g. with XMLUpdateRequestHandler (deprecated in SOlr 4.0.0), see if possible
|
||||
* e.g. with XMLUpdateRequestHandler (deprecated in SOlr 4.0.0), see if possible
|
||||
* to stream with UpdateRequestHandler
|
||||
*
|
||||
*
|
||||
* @param cs
|
||||
* @param fields
|
||||
* @param size
|
||||
* @throws org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException
|
||||
* @throws org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException
|
||||
*/
|
||||
private void ingest(ContentStream cs, Map<String, String> fields, final long size) throws IngesterException {
|
||||
|
||||
|
||||
if (fields.get(Server.Schema.IMAGE_ID.toString()) == null) {
|
||||
//skip the file, image id unknown
|
||||
String msg = "Skipping indexing the file, unknown image id, for file: " + cs.getName();
|
||||
logger.log(Level.SEVERE, msg);
|
||||
throw new IngesterException(msg);
|
||||
}
|
||||
|
||||
|
||||
SolrInputDocument updateDoc = new SolrInputDocument();
|
||||
|
||||
for (String key : fields.keySet()) {
|
||||
@ -292,9 +293,9 @@ class Ingester {
|
||||
|
||||
//using size here, but we are no longer ingesting entire files
|
||||
//size is normally a chunk size, up to 1MB
|
||||
|
||||
|
||||
if (size > 0) {
|
||||
|
||||
|
||||
InputStream is = null;
|
||||
int read = 0;
|
||||
try {
|
||||
@ -306,7 +307,8 @@ class Ingester {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Could not close input stream after reading content, " + cs.getName(), ex);
|
||||
logger.log(Level.WARNING, "Could not close input stream after reading content, " + cs.getName(),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,12 +323,11 @@ class Ingester {
|
||||
} else {
|
||||
updateDoc.addField(Server.Schema.CONTENT.toString(), "");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//no content, such as case when 0th chunk indexed
|
||||
updateDoc.addField(Server.Schema.CONTENT.toString(), "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
try {
|
||||
//TODO consider timeout thread, or vary socket timeout based on size of indexed content
|
||||
@ -343,13 +344,12 @@ class Ingester {
|
||||
* Delegate method actually performing the indexing work for objects
|
||||
* implementing ContentStream
|
||||
*
|
||||
* @param cs ContentStream to ingest
|
||||
* @param cs ContentStream to ingest
|
||||
* @param fields content specific fields
|
||||
* @param size size of the content - used to determine the Solr timeout, not
|
||||
* used to populate meta-data
|
||||
*
|
||||
* @param size size of the content - used to determine the Solr timeout, not
|
||||
* used to populate meta-data
|
||||
* @throws IngesterException if there was an error processing a specific
|
||||
* content, but the Solr server is probably fine.
|
||||
* content, but the Solr server is probably fine.
|
||||
*/
|
||||
private void ingestExtract(ContentStream cs, Map<String, String> fields, final long size) throws IngesterException {
|
||||
final ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update/extract");
|
||||
@ -373,9 +373,12 @@ class Ingester {
|
||||
logger.log(Level.WARNING, "Solr timeout encountered, trying to restart Solr");
|
||||
//restart may be needed to recover from some error conditions
|
||||
hardSolrRestart();
|
||||
throw new IngesterException("Solr index request time out for id: " + fields.get("id") + ", name: " + fields.get("file_name"));
|
||||
throw new IngesterException(
|
||||
"Solr index request time out for id: " + fields.get("id") + ", name: " + fields.get("file_name"));
|
||||
} catch (Exception e) {
|
||||
throw new IngesterException("Problem posting content to Solr, id: " + fields.get("id") + ", name: " + fields.get("file_name"), e);
|
||||
throw new IngesterException(
|
||||
"Problem posting content to Solr, id: " + fields.get("id") + ", name: " + fields.get("file_name"),
|
||||
e);
|
||||
}
|
||||
uncommitedIngests = true;
|
||||
}
|
||||
@ -458,7 +461,8 @@ class Ingester {
|
||||
// When Tika has problems with a document, it throws a server error
|
||||
// but it's okay to continue with other documents
|
||||
if (ec.equals(ErrorCode.SERVER_ERROR)) {
|
||||
throw new RuntimeException("Problem posting file contents to Solr. SolrException error code: " + ec, ex);
|
||||
throw new RuntimeException("Problem posting file contents to Solr. SolrException error code: " + ec,
|
||||
ex);
|
||||
} else {
|
||||
// shouldn't get any other error codes
|
||||
throw ex;
|
||||
@ -486,7 +490,7 @@ class Ingester {
|
||||
/**
|
||||
* Helper to set document fields
|
||||
*
|
||||
* @param up request with document
|
||||
* @param up request with document
|
||||
* @param fields map of field-names->values
|
||||
*/
|
||||
private static void setFields(ContentStreamUpdateRequest up, Map<String, String> fields) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.openide.modules.ModuleInstall;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.windows.WindowManager;
|
||||
@ -31,7 +32,7 @@ import org.sleuthkit.autopsy.coreutils.Version;
|
||||
/**
|
||||
* Starts up the Solr server when the module is loaded, and stops it when the
|
||||
* application is closed.
|
||||
*
|
||||
* <p/>
|
||||
* In addition, the default KeywordSearch config files (NSRL, Options, Scripts)
|
||||
* are generated here, if they config files do not already exist.
|
||||
*/
|
||||
@ -202,7 +203,9 @@ class Installer extends ModuleInstall {
|
||||
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportPortError", curFailPort, Version.getName(), Server.PROPERTIES_CURRENT_SERVER_PORT, Server.PROPERTIES_FILE);
|
||||
final String msg = NbBundle
|
||||
.getMessage(this.getClass(), "Installer.reportPortError", curFailPort, Version.getName(),
|
||||
Server.PROPERTIES_CURRENT_SERVER_PORT, Server.PROPERTIES_FILE);
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
|
||||
}
|
||||
});
|
||||
@ -212,7 +215,8 @@ class Installer extends ModuleInstall {
|
||||
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportStopPortError", curFailPort, Server.PROPERTIES_CURRENT_STOP_PORT, Server.PROPERTIES_FILE);
|
||||
final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportStopPortError", curFailPort,
|
||||
Server.PROPERTIES_CURRENT_STOP_PORT, Server.PROPERTIES_FILE);
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
|
||||
}
|
||||
});
|
||||
@ -222,7 +226,10 @@ class Installer extends ModuleInstall {
|
||||
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportInitError", KeywordSearch.getServer().getCurrentSolrServerPort(), Version.getName(), Server.PROPERTIES_CURRENT_SERVER_PORT, Server.PROPERTIES_FILE);
|
||||
final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportInitError",
|
||||
KeywordSearch.getServer().getCurrentSolrServerPort(),
|
||||
Version.getName(), Server.PROPERTIES_CURRENT_SERVER_PORT,
|
||||
Server.PROPERTIES_FILE);
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
|
||||
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
|
||||
|
@ -24,6 +24,7 @@ import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import net.htmlparser.jericho.Attributes;
|
||||
import net.htmlparser.jericho.Renderer;
|
||||
@ -38,34 +39,35 @@ import net.htmlparser.jericho.StartTagType;
|
||||
*/
|
||||
class JerichoParserWrapper {
|
||||
private static final Logger logger = Logger.getLogger(JerichoParserWrapper.class.getName());
|
||||
private InputStream in;
|
||||
private InputStream in;
|
||||
private StringBuilder out;
|
||||
private Reader reader;
|
||||
|
||||
|
||||
JerichoParserWrapper(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the reader, initialized in parse(), which will be
|
||||
* null if parse() is not called or if parse() throws an error.
|
||||
*
|
||||
* @return Reader
|
||||
*/
|
||||
public Reader getReader() {
|
||||
return reader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the reader by parsing the InputStream, adding it to StringBuilder,
|
||||
* and creating a StringReader from it.
|
||||
*/
|
||||
public void parse() {
|
||||
out = new StringBuilder();
|
||||
|
||||
|
||||
try {
|
||||
Source source = new Source(in);
|
||||
source.fullSequentialParse();
|
||||
|
||||
|
||||
String text;
|
||||
StringBuilder scripts = new StringBuilder();
|
||||
StringBuilder links = new StringBuilder();
|
||||
@ -77,37 +79,37 @@ class JerichoParserWrapper {
|
||||
int numImages = 1;
|
||||
int numComments = 1;
|
||||
int numOthers = 1;
|
||||
|
||||
|
||||
text = renderHTMLAsPlainText(source);
|
||||
|
||||
// Get all the tags in the source
|
||||
List<StartTag> tags = source.getAllStartTags();
|
||||
for(StartTag tag : tags) {
|
||||
if(tag.getName().equals("script")) {
|
||||
for (StartTag tag : tags) {
|
||||
if (tag.getName().equals("script")) {
|
||||
// If the <script> tag has attributes
|
||||
scripts.append(numScripts).append(") ");
|
||||
if(tag.getTagContent().length()>0) {
|
||||
if (tag.getTagContent().length() > 0) {
|
||||
scripts.append(tag.getTagContent()).append(" ");
|
||||
}
|
||||
// Get whats between the <script> .. </script> tags
|
||||
scripts.append(tag.getElement().getContent()).append("\n");
|
||||
numScripts++;
|
||||
} else if(tag.getName().equals("a")) {
|
||||
} else if (tag.getName().equals("a")) {
|
||||
links.append(numLinks).append(") ");
|
||||
links.append(tag.getTagContent()).append("\n");
|
||||
numLinks++;
|
||||
} else if(tag.getName().equals("img")) {
|
||||
} else if (tag.getName().equals("img")) {
|
||||
images.append(numImages).append(") ");
|
||||
images.append(tag.getTagContent()).append("\n");
|
||||
numImages++;
|
||||
} else if(tag.getTagType().equals(StartTagType.COMMENT)) {
|
||||
} else if (tag.getTagType().equals(StartTagType.COMMENT)) {
|
||||
comments.append(numComments).append(") ");
|
||||
comments.append(tag.getTagContent()).append("\n");
|
||||
numComments++;
|
||||
} else {
|
||||
// Make sure it has an attribute
|
||||
Attributes atts = tag.getAttributes();
|
||||
if (atts!=null && atts.length()>0) {
|
||||
if (atts != null && atts.length() > 0) {
|
||||
others.append(numOthers).append(") ");
|
||||
others.append(tag.getName()).append(":");
|
||||
others.append(tag.getTagContent()).append("\n");
|
||||
@ -119,19 +121,23 @@ class JerichoParserWrapper {
|
||||
out.append(text).append("\n\n");
|
||||
|
||||
out.append("----------NONVISIBLE TEXT----------\n\n");
|
||||
if(numScripts>1) {
|
||||
if (numScripts > 1) {
|
||||
out.append("---Scripts---\n");
|
||||
out.append(scripts.toString()).append("\n");
|
||||
} if(numLinks>1) {
|
||||
}
|
||||
if (numLinks > 1) {
|
||||
out.append("---Links---\n");
|
||||
out.append(links.toString()).append("\n");
|
||||
} if(numImages>1) {
|
||||
}
|
||||
if (numImages > 1) {
|
||||
out.append("---Images---\n");
|
||||
out.append(images.toString()).append("\n");
|
||||
} if(numComments>1) {
|
||||
}
|
||||
if (numComments > 1) {
|
||||
out.append("---Comments---\n");
|
||||
out.append(comments.toString()).append("\n");
|
||||
} if(numOthers>1) {
|
||||
}
|
||||
if (numOthers > 1) {
|
||||
out.append("---Others---\n");
|
||||
out.append(others.toString()).append("\n");
|
||||
}
|
||||
@ -141,7 +147,7 @@ class JerichoParserWrapper {
|
||||
logger.log(Level.WARNING, "Unable to parse the HTML file", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Extract text from the source, nicely formatted with whitespace and
|
||||
// newlines where appropriate.
|
||||
private String renderHTMLAsPlainText(Source source) {
|
||||
|
@ -30,36 +30,33 @@ class Keyword {
|
||||
private BlackboardAttribute.ATTRIBUTE_TYPE keywordType = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param query Keyword to search for
|
||||
* @param query Keyword to search for
|
||||
* @param isLiteral false if reg exp
|
||||
*/
|
||||
Keyword(String query, boolean isLiteral) {
|
||||
this.keywordString = query;
|
||||
this.isLiteral = isLiteral;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param query Keyword to search for
|
||||
* @param isLiteral false if reg exp
|
||||
* @param keywordType
|
||||
* @param query Keyword to search for
|
||||
* @param isLiteral false if reg exp
|
||||
* @param keywordType
|
||||
*/
|
||||
Keyword(String query, boolean isLiteral, BlackboardAttribute.ATTRIBUTE_TYPE keywordType) {
|
||||
this(query, isLiteral);
|
||||
this.keywordType = keywordType;
|
||||
}
|
||||
|
||||
|
||||
void setType(BlackboardAttribute.ATTRIBUTE_TYPE keywordType) {
|
||||
this.keywordType = keywordType;
|
||||
}
|
||||
|
||||
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE getType() {
|
||||
return this.keywordType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Keyword to search for
|
||||
*/
|
||||
String getQuery() {
|
||||
@ -72,10 +69,10 @@ class Keyword {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Keyword{" + "query=" + keywordString + ", isLiteral=" + isLiteral + ", keywordType=" + keywordType + '}';
|
||||
return "Keyword{" + "query=" + keywordString + ", isLiteral=" + isLiteral + ", keywordType=" + keywordType
|
||||
+ '}';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@ -86,7 +83,8 @@ class Keyword {
|
||||
return false;
|
||||
}
|
||||
final Keyword other = (Keyword) obj;
|
||||
if ((this.keywordString == null) ? (other.keywordString != null) : !this.keywordString.equals(other.keywordString)) {
|
||||
if ((this.keywordString == null) ? (other.keywordString != null)
|
||||
: !this.keywordString.equals(other.keywordString)) {
|
||||
return false;
|
||||
}
|
||||
if (this.isLiteral != other.isLiteral) {
|
||||
|
@ -23,7 +23,6 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* Filter to restrict query only specific files, chunks, images
|
||||
* Single filter supports multiple ids per file/chunk/image, that act as OR filter
|
||||
*/
|
||||
@ -33,7 +32,7 @@ class KeywordQueryFilter {
|
||||
|
||||
FILE, CHUNK, DATA_SOURCE
|
||||
};
|
||||
private Set<Long>idFilters;
|
||||
private Set<Long> idFilters;
|
||||
private FilterType filterType;
|
||||
|
||||
public KeywordQueryFilter(FilterType filterType, long id) {
|
||||
@ -42,7 +41,7 @@ class KeywordQueryFilter {
|
||||
this.idFilters.add(id);
|
||||
}
|
||||
|
||||
public KeywordQueryFilter(FilterType filterType, Set<Long>ids) {
|
||||
public KeywordQueryFilter(FilterType filterType, Set<Long> ids) {
|
||||
this.filterType = filterType;
|
||||
this.idFilters = ids;
|
||||
}
|
||||
@ -59,8 +58,8 @@ class KeywordQueryFilter {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String id = null;
|
||||
|
||||
Iterator<Long>it = idFilters.iterator();
|
||||
|
||||
Iterator<Long> it = idFilters.iterator();
|
||||
for (int i = 0; it.hasNext(); ++i) {
|
||||
if (i > 0) {
|
||||
sb.append(" "); //OR
|
||||
|
@ -27,6 +27,7 @@ import java.util.logging.FileHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.SimpleFormatter;
|
||||
|
||||
import org.openide.util.Exceptions;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
@ -66,7 +67,8 @@ class KeywordSearch {
|
||||
static {
|
||||
try {
|
||||
final int MAX_TIKA_LOG_FILES = 3;
|
||||
FileHandler tikaLogHandler = new FileHandler(PlatformUtil.getUserDirectory().getAbsolutePath() + "/var/log/tika.log",
|
||||
FileHandler tikaLogHandler = new FileHandler(
|
||||
PlatformUtil.getUserDirectory().getAbsolutePath() + "/var/log/tika.log",
|
||||
0, MAX_TIKA_LOG_FILES);
|
||||
tikaLogHandler.setFormatter(new SimpleFormatter());
|
||||
tikaLogHandler.setEncoding(PlatformUtil.getLogFileEncoding());
|
||||
@ -88,16 +90,16 @@ class KeywordSearch {
|
||||
static Logger getTikaLogger() {
|
||||
return TIKA_LOGGER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void addNumIndexedFilesChangeListener(PropertyChangeListener l) {
|
||||
changeSupport.addPropertyChangeListener(NUM_FILES_CHANGE_EVT, l);
|
||||
}
|
||||
|
||||
|
||||
public static void removeNumIndexedFilesChangeListener(PropertyChangeListener l) {
|
||||
changeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
|
||||
static void fireNumIndexedFilesChange(Integer oldNum, Integer newNum) {
|
||||
changeSupport.firePropertyChange(NUM_FILES_CHANGE_EVT, oldNum, newNum);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.AbstractAction;
|
||||
|
||||
import org.openide.util.actions.Presenter;
|
||||
|
||||
final class KeywordSearchAction extends AbstractAction implements Presenter.Toolbar {
|
||||
|
@ -23,6 +23,7 @@ import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
|
||||
@ -30,9 +31,10 @@ import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
|
||||
/**
|
||||
* System action to open the KeywordSearch Options panel.
|
||||
*/
|
||||
class KeywordSearchConfigurationAction extends CallableSystemAction{
|
||||
|
||||
private static final String ACTION_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleConfig");
|
||||
class KeywordSearchConfigurationAction extends CallableSystemAction {
|
||||
|
||||
private static final String ACTION_NAME = org.openide.util.NbBundle
|
||||
.getMessage(KeywordSearchPanel.class, "ListBundleConfig");
|
||||
private KeywordSearchConfigurationPanel panel;
|
||||
|
||||
@Override
|
||||
@ -59,9 +61,9 @@ class KeywordSearchConfigurationAction extends CallableSystemAction{
|
||||
dialog.addWindowListener(exitListener);
|
||||
dialog.display(panel);
|
||||
}
|
||||
|
||||
|
||||
private KeywordSearchConfigurationPanel getPanel() {
|
||||
if(panel==null) {
|
||||
if (panel == null) {
|
||||
panel = new KeywordSearchConfigurationPanel();
|
||||
}
|
||||
return panel;
|
||||
@ -76,7 +78,7 @@ class KeywordSearchConfigurationAction extends CallableSystemAction{
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean asynchronous() {
|
||||
return false;
|
||||
|
@ -35,18 +35,30 @@ final class KeywordSearchConfigurationPanel extends javax.swing.JPanel implement
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
|
||||
private void customizeComponents() {
|
||||
setName(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.title"));
|
||||
listsPanel = new KeywordSearchConfigurationPanel1();
|
||||
languagesPanel = new KeywordSearchConfigurationPanel3();
|
||||
generalPanel = new KeywordSearchConfigurationPanel2();
|
||||
tabbedPane.insertTab(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.listTabTitle"), null,
|
||||
listsPanel, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.listLabToolTip"), 0);
|
||||
tabbedPane.insertTab(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.stringExtTitle"), null,
|
||||
languagesPanel, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.stringExtToolTip"), 1);
|
||||
tabbedPane.insertTab(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.genTabTitle"), null,
|
||||
generalPanel, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.genTabToolTip"), 2);
|
||||
tabbedPane.insertTab(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel.customizeComponents.listTabTitle"),
|
||||
null,
|
||||
listsPanel, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel.customizeComponents.listLabToolTip"),
|
||||
0);
|
||||
tabbedPane.insertTab(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel.customizeComponents.stringExtTitle"),
|
||||
null,
|
||||
languagesPanel, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel.customizeComponents.stringExtToolTip"),
|
||||
1);
|
||||
tabbedPane.insertTab(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel.customizeComponents.genTabTitle"),
|
||||
null,
|
||||
generalPanel, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel.customizeComponents.genTabToolTip"),
|
||||
2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,12 +74,14 @@ final class KeywordSearchConfigurationPanel extends javax.swing.JPanel implement
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 675, Short.MAX_VALUE)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE, 675, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.TRAILING,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -95,14 +109,14 @@ final class KeywordSearchConfigurationPanel extends javax.swing.JPanel implement
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
KeywordSearchListsXML.getCurrent().reload();
|
||||
KeywordSearchListsXML.getCurrent().reload();
|
||||
}
|
||||
|
||||
|
||||
boolean valid() {
|
||||
// TODO check whether form is consistent and complete
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTabbedPane tabbedPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
@ -41,11 +41,14 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
KeywordSearchListsManagementPanel listsManagementPanel;
|
||||
KeywordSearchEditListPanel editListPanel;
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchConfigurationPanel1.class.getName());
|
||||
private static final String KEYWORD_CONFIG_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleConfig");
|
||||
|
||||
/** Creates new form KeywordSearchConfigurationPanel1 */
|
||||
private static final String KEYWORD_CONFIG_NAME = org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"ListBundleConfig");
|
||||
|
||||
/**
|
||||
* Creates new form KeywordSearchConfigurationPanel1
|
||||
*/
|
||||
KeywordSearchConfigurationPanel1() {
|
||||
|
||||
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
setName(KEYWORD_CONFIG_NAME);
|
||||
@ -57,12 +60,14 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
|
||||
listsManagementPanel.addListSelectionListener(editListPanel);
|
||||
editListPanel.addDeleteButtonActionPerformed(new ActionListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.title")
|
||||
, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.body" )
|
||||
, KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN) ) {
|
||||
if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel1.customizeComponents.title")
|
||||
, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel1.customizeComponents.body")
|
||||
, KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) {
|
||||
|
||||
KeywordSearchListsXML deleter = KeywordSearchListsXML.getCurrent();
|
||||
String toDelete = editListPanel.getCurrentKeywordList().getName();
|
||||
@ -73,9 +78,9 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
editListPanel.addSaveButtonActionPerformed(new ActionListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final String FEATURE_NAME = "Save Keyword List";
|
||||
@ -84,8 +89,9 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
|
||||
List<Keyword> keywords = currentKeywordList.getKeywords();
|
||||
if (keywords.isEmpty()) {
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.keywordListEmptyErr"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel1.customizeComponents.keywordListEmptyErr"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -102,13 +108,18 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
}
|
||||
|
||||
if (writer.listExists(listName) && writer.getList(listName).isLocked()) {
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.noOwDefaultMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel1.customizeComponents.noOwDefaultMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
return;
|
||||
}
|
||||
boolean shouldAdd = false;
|
||||
if (writer.listExists(listName)) {
|
||||
boolean replace = KeywordSearchUtil.displayConfirmDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.kwListExistMsg", listName),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
boolean replace = KeywordSearchUtil.displayConfirmDialog(FEATURE_NAME,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel1.customizeComponents.kwListExistMsg",
|
||||
listName),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
if (replace) {
|
||||
shouldAdd = true;
|
||||
}
|
||||
@ -119,34 +130,38 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
|
||||
if (shouldAdd) {
|
||||
writer.addList(listName, keywords);
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(), "KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg", listName), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchConfigurationPanel1.customizeComponents.kwListSavedMsg",
|
||||
listName),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
}
|
||||
|
||||
//currentKeywordList = writer.getList(listName);
|
||||
|
||||
|
||||
listsManagementPanel.resync();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mainSplitPane.setLeftComponent(listsManagementPanel);
|
||||
mainSplitPane.setRightComponent(editListPanel);
|
||||
mainSplitPane.revalidate();
|
||||
mainSplitPane.repaint();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void store() {
|
||||
KeywordSearchListsXML.getCurrent().save(false);
|
||||
//refresh the list viewer/searcher panel
|
||||
KeywordSearchListsViewerPanel.getDefault().resync();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
listsManagementPanel.load();
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
@ -165,12 +180,12 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
javax.swing.GroupLayout leftPanelLayout = new javax.swing.GroupLayout(leftPanel);
|
||||
leftPanel.setLayout(leftPanelLayout);
|
||||
leftPanelLayout.setHorizontalGroup(
|
||||
leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 275, Short.MAX_VALUE)
|
||||
leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 275, Short.MAX_VALUE)
|
||||
);
|
||||
leftPanelLayout.setVerticalGroup(
|
||||
leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 327, Short.MAX_VALUE)
|
||||
leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 327, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
mainSplitPane.setLeftComponent(leftPanel);
|
||||
@ -178,12 +193,12 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
javax.swing.GroupLayout rightPanelLayout = new javax.swing.GroupLayout(rightPanel);
|
||||
rightPanel.setLayout(rightPanelLayout);
|
||||
rightPanelLayout.setHorizontalGroup(
|
||||
rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 318, Short.MAX_VALUE)
|
||||
rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 318, Short.MAX_VALUE)
|
||||
);
|
||||
rightPanelLayout.setVerticalGroup(
|
||||
rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 327, Short.MAX_VALUE)
|
||||
rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 327, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
mainSplitPane.setRightComponent(rightPanel);
|
||||
@ -191,12 +206,12 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(mainSplitPane)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(mainSplitPane)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(mainSplitPane)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(mainSplitPane)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -205,5 +220,5 @@ class KeywordSearchConfigurationPanel1 extends javax.swing.JPanel implements Opt
|
||||
private javax.swing.JSplitPane mainSplitPane;
|
||||
private javax.swing.JPanel rightPanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
@ -97,35 +98,52 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
|
||||
timeRadioButton3 = new javax.swing.JRadioButton();
|
||||
timeRadioButton4 = new javax.swing.JRadioButton();
|
||||
|
||||
skipNSRLCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.skipNSRLCheckBox.text")); // NOI18N
|
||||
skipNSRLCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.skipNSRLCheckBox.toolTipText")); // NOI18N
|
||||
skipNSRLCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.skipNSRLCheckBox.text")); // NOI18N
|
||||
skipNSRLCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.skipNSRLCheckBox.toolTipText")); // NOI18N
|
||||
|
||||
filesIndexedLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.filesIndexedLabel.text")); // NOI18N
|
||||
filesIndexedLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.filesIndexedLabel.text")); // NOI18N
|
||||
|
||||
filesIndexedValue.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.filesIndexedValue.text")); // NOI18N
|
||||
filesIndexedValue.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.filesIndexedValue.text")); // NOI18N
|
||||
filesIndexedValue.setMaximumSize(null);
|
||||
|
||||
chunksLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.chunksLabel.text")); // NOI18N
|
||||
chunksLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.chunksLabel.text")); // NOI18N
|
||||
|
||||
chunksValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.chunksValLabel.text")); // NOI18N
|
||||
chunksValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.chunksValLabel.text")); // NOI18N
|
||||
|
||||
settingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.settingsLabel.text")); // NOI18N
|
||||
settingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.settingsLabel.text")); // NOI18N
|
||||
|
||||
informationLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.informationLabel.text")); // NOI18N
|
||||
informationLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.informationLabel.text")); // NOI18N
|
||||
|
||||
frequencyLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.frequencyLabel.text")); // NOI18N
|
||||
frequencyLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.frequencyLabel.text")); // NOI18N
|
||||
|
||||
timeRadioButton1.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton1.text")); // NOI18N
|
||||
timeRadioButton1.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton1.toolTipText")); // NOI18N
|
||||
timeRadioButton1.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton1.text")); // NOI18N
|
||||
timeRadioButton1.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton1.toolTipText")); // NOI18N
|
||||
|
||||
timeRadioButton2.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton2.text")); // NOI18N
|
||||
timeRadioButton2.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton2.toolTipText")); // NOI18N
|
||||
timeRadioButton2.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton2.text")); // NOI18N
|
||||
timeRadioButton2.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton2.toolTipText")); // NOI18N
|
||||
|
||||
timeRadioButton3.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton3.text")); // NOI18N
|
||||
timeRadioButton3.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton3.toolTipText")); // NOI18N
|
||||
timeRadioButton3.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton3.text")); // NOI18N
|
||||
timeRadioButton3.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton3.toolTipText")); // NOI18N
|
||||
|
||||
timeRadioButton4.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton4.text_1")); // NOI18N
|
||||
timeRadioButton4.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class, "KeywordSearchConfigurationPanel2.timeRadioButton4.toolTipText")); // NOI18N
|
||||
timeRadioButton4.setText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton4.text_1")); // NOI18N
|
||||
timeRadioButton4.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel2.class,
|
||||
"KeywordSearchConfigurationPanel2.timeRadioButton4.toolTipText")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -239,14 +257,11 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
|
||||
private UpdateFrequency getSelectedTimeValue() {
|
||||
if (timeRadioButton1.isSelected()) {
|
||||
return UpdateFrequency.FAST;
|
||||
}
|
||||
else if (timeRadioButton2.isSelected()) {
|
||||
} else if (timeRadioButton2.isSelected()) {
|
||||
return UpdateFrequency.AVG;
|
||||
}
|
||||
else if (timeRadioButton3.isSelected()) {
|
||||
} else if (timeRadioButton3.isSelected()) {
|
||||
return UpdateFrequency.SLOW;
|
||||
}
|
||||
else if (timeRadioButton4.isSelected()) {
|
||||
} else if (timeRadioButton4.isSelected()) {
|
||||
return UpdateFrequency.SLOWEST;
|
||||
}
|
||||
return UpdateFrequency.DEFAULT;
|
||||
@ -282,7 +297,8 @@ class KeywordSearchConfigurationPanel2 extends javax.swing.JPanel implements Opt
|
||||
int newFilesIndexed = ((Integer) newValue).intValue();
|
||||
filesIndexedValue.setText(Integer.toString(newFilesIndexed));
|
||||
try {
|
||||
chunksValLabel.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedChunks()));
|
||||
chunksValLabel
|
||||
.setText(Integer.toString(KeywordSearch.getServer().queryNumIndexedChunks()));
|
||||
} catch (KeywordSearchModuleException ex) {
|
||||
logger.log(Level.WARNING, "Could not get number of indexed chunks");
|
||||
|
||||
|
@ -26,8 +26,11 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
||||
@ -40,7 +43,8 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
|
||||
private static KeywordSearchConfigurationPanel3 instance = null;
|
||||
private final Logger logger = Logger.getLogger(KeywordSearchConfigurationPanel3.class.getName());
|
||||
private final Map<String, StringExtract.StringExtractUnicodeTable.SCRIPT> scripts = new HashMap<String, StringExtract.StringExtractUnicodeTable.SCRIPT>();
|
||||
private final Map<String, StringExtract.StringExtractUnicodeTable.SCRIPT> scripts
|
||||
= new HashMap<String, StringExtract.StringExtractUnicodeTable.SCRIPT>();
|
||||
private ActionListener updateLanguagesAction;
|
||||
private List<SCRIPT> toUpdate;
|
||||
|
||||
@ -97,9 +101,10 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private void initScriptsCheckBoxes() {
|
||||
final List<StringExtract.StringExtractUnicodeTable.SCRIPT> supportedScripts = StringExtract.getSupportedScripts();
|
||||
final List<StringExtract.StringExtractUnicodeTable.SCRIPT> supportedScripts = StringExtract
|
||||
.getSupportedScripts();
|
||||
checkPanel.setLayout(new GridLayout(0, 1));
|
||||
for (StringExtract.StringExtractUnicodeTable.SCRIPT s : supportedScripts) {
|
||||
String text = getLangText(s);
|
||||
@ -112,45 +117,49 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
}
|
||||
|
||||
private void reloadScriptsCheckBoxes() {
|
||||
|
||||
boolean utf16 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString()));
|
||||
|
||||
|
||||
boolean utf16 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(
|
||||
AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString()));
|
||||
|
||||
enableUTF16Checkbox.setSelected(utf16);
|
||||
|
||||
boolean utf8 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString()));
|
||||
|
||||
boolean utf8 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(
|
||||
AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString()));
|
||||
enableUTF8Checkbox.setSelected(utf8);
|
||||
|
||||
|
||||
final List<SCRIPT> serviceScripts = KeywordSearchSettings.getStringExtractScripts();
|
||||
final int components = checkPanel.getComponentCount();
|
||||
|
||||
|
||||
for (int i = 0; i < components; ++i) {
|
||||
JCheckBox ch = (JCheckBox) checkPanel.getComponent(i);
|
||||
|
||||
|
||||
StringExtract.StringExtractUnicodeTable.SCRIPT script = scripts.get(ch.getText());
|
||||
|
||||
|
||||
ch.setSelected(serviceScripts.contains(script));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void activateWidgets() {
|
||||
reloadScriptsCheckBoxes();
|
||||
|
||||
|
||||
boolean utf16 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString()));
|
||||
|
||||
|
||||
|
||||
boolean utf16 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(
|
||||
AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString()));
|
||||
|
||||
enableUTF16Checkbox.setSelected(utf16);
|
||||
|
||||
boolean utf8 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString()));
|
||||
|
||||
boolean utf8 =
|
||||
Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(
|
||||
AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString()));
|
||||
enableUTF8Checkbox.setSelected(utf8);
|
||||
final boolean extractEnabled = utf16 || utf8;
|
||||
|
||||
|
||||
boolean ingestNotRunning = !IngestManager.getDefault().isIngestRunning()
|
||||
&& ! IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault());
|
||||
&& !IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault());
|
||||
//enable / disable checboxes
|
||||
activateScriptsCheckboxes(extractEnabled && ingestNotRunning);
|
||||
enableUTF16Checkbox.setEnabled(ingestNotRunning);
|
||||
@ -173,7 +182,9 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
enableUTF16Checkbox = new javax.swing.JCheckBox();
|
||||
ingestSettingsLabel = new javax.swing.JLabel();
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(languagesLabel, org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel3.class, "KeywordSearchConfigurationPanel3.languagesLabel.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(languagesLabel, org.openide.util.NbBundle.getMessage(
|
||||
KeywordSearchConfigurationPanel3.class,
|
||||
"KeywordSearchConfigurationPanel3.languagesLabel.text")); // NOI18N
|
||||
|
||||
langPanel.setPreferredSize(new java.awt.Dimension(430, 361));
|
||||
|
||||
@ -182,31 +193,37 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
javax.swing.GroupLayout checkPanelLayout = new javax.swing.GroupLayout(checkPanel);
|
||||
checkPanel.setLayout(checkPanelLayout);
|
||||
checkPanelLayout.setHorizontalGroup(
|
||||
checkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 428, Short.MAX_VALUE)
|
||||
checkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 428, Short.MAX_VALUE)
|
||||
);
|
||||
checkPanelLayout.setVerticalGroup(
|
||||
checkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 395, Short.MAX_VALUE)
|
||||
checkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 395, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
langPanel.setViewportView(checkPanel);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(enableUTF8Checkbox, org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel3.class, "KeywordSearchConfigurationPanel3.enableUTF8Checkbox.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(enableUTF8Checkbox, org.openide.util.NbBundle.getMessage(
|
||||
KeywordSearchConfigurationPanel3.class,
|
||||
"KeywordSearchConfigurationPanel3.enableUTF8Checkbox.text")); // NOI18N
|
||||
enableUTF8Checkbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
enableUTF8CheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(enableUTF16Checkbox, org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel3.class, "KeywordSearchConfigurationPanel3.enableUTF16Checkbox.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(enableUTF16Checkbox, org.openide.util.NbBundle.getMessage(
|
||||
KeywordSearchConfigurationPanel3.class,
|
||||
"KeywordSearchConfigurationPanel3.enableUTF16Checkbox.text")); // NOI18N
|
||||
enableUTF16Checkbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
enableUTF16CheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(KeywordSearchConfigurationPanel3.class, "KeywordSearchConfigurationPanel3.ingestSettingsLabel.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(
|
||||
KeywordSearchConfigurationPanel3.class,
|
||||
"KeywordSearchConfigurationPanel3.ingestSettingsLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -243,18 +260,20 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void enableUTF8CheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableUTF8CheckboxActionPerformed
|
||||
|
||||
private void enableUTF8CheckboxActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableUTF8CheckboxActionPerformed
|
||||
|
||||
boolean selected = this.enableUTF8Checkbox.isSelected();
|
||||
|
||||
|
||||
activateScriptsCheckboxes(selected || this.enableUTF16Checkbox.isSelected());
|
||||
|
||||
|
||||
}//GEN-LAST:event_enableUTF8CheckboxActionPerformed
|
||||
|
||||
private void enableUTF16CheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableUTF16CheckboxActionPerformed
|
||||
|
||||
private void enableUTF16CheckboxActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableUTF16CheckboxActionPerformed
|
||||
|
||||
boolean selected = this.enableUTF16Checkbox.isSelected();
|
||||
|
||||
|
||||
activateScriptsCheckboxes(selected || this.enableUTF8Checkbox.isSelected());
|
||||
}//GEN-LAST:event_enableUTF16CheckboxActionPerformed
|
||||
|
||||
@ -270,19 +289,19 @@ class KeywordSearchConfigurationPanel3 extends javax.swing.JPanel implements Opt
|
||||
@Override
|
||||
public void store() {
|
||||
KeywordSearchSettings.setStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString(),
|
||||
Boolean.toString(enableUTF8Checkbox.isSelected()));
|
||||
Boolean.toString(enableUTF8Checkbox.isSelected()));
|
||||
KeywordSearchSettings.setStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString(),
|
||||
Boolean.toString(enableUTF16Checkbox.isSelected()));
|
||||
|
||||
if(toUpdate!=null) {
|
||||
KeywordSearchSettings.setStringExtractScripts(toUpdate);
|
||||
Boolean.toString(enableUTF16Checkbox.isSelected()));
|
||||
|
||||
if (toUpdate != null) {
|
||||
KeywordSearchSettings.setStringExtractScripts(toUpdate);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
activateWidgets();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import java.util.logging.Level;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import javax.swing.DefaultListSelectionModel;
|
||||
@ -47,13 +48,14 @@ import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
|
||||
/**
|
||||
* KeywordSearchEditListPanel widget to manage keywords in lists
|
||||
* KeywordSearchEditListPanel widget to manage keywords in lists
|
||||
*/
|
||||
class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelectionListener, OptionsPanel {
|
||||
|
||||
@ -61,24 +63,32 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
private KeywordTableModel tableModel;
|
||||
private KeywordSearchListsAbstract.KeywordSearchList currentKeywordList;
|
||||
|
||||
|
||||
|
||||
private boolean ingestRunning;
|
||||
|
||||
/** Creates new form KeywordSearchEditListPanel */
|
||||
/**
|
||||
* Creates new form KeywordSearchEditListPanel
|
||||
*/
|
||||
KeywordSearchEditListPanel() {
|
||||
tableModel = new KeywordTableModel();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void customizeComponents() {
|
||||
chRegex.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.kwReToolTip"));
|
||||
addWordButton.setToolTipText((NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.addWordToolTip")));
|
||||
addWordField.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.enterNewWordToolTip"));
|
||||
exportButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.exportToFile"));
|
||||
saveListButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.saveCurrentWIthNewNameToolTip"));
|
||||
deleteWordButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.removeSelectedMsg"));
|
||||
chRegex.setToolTipText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.kwReToolTip"));
|
||||
addWordButton.setToolTipText((NbBundle
|
||||
.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.addWordToolTip")));
|
||||
addWordField.setToolTipText(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.customizeComponents.enterNewWordToolTip"));
|
||||
exportButton.setToolTipText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.customizeComponents.exportToFile"));
|
||||
saveListButton.setToolTipText(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.customizeComponents.saveCurrentWIthNewNameToolTip"));
|
||||
deleteWordButton.setToolTipText(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.customizeComponents.removeSelectedMsg"));
|
||||
|
||||
//keywordTable.setAutoscrolls(true);
|
||||
//keywordTable.setTableHeader(null);
|
||||
@ -105,7 +115,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
|
||||
final ListSelectionModel lsm = keywordTable.getSelectionModel();
|
||||
lsm.addListSelectionListener(new ListSelectionListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (lsm.isSelectionEmpty() || currentKeywordList.isLocked()) {
|
||||
@ -114,7 +124,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
} else {
|
||||
deleteWordButton.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
//show selector if available
|
||||
DefaultListSelectionModel selModel = (DefaultListSelectionModel) e.getSource();
|
||||
if (!selModel.getValueIsAdjusting()) {
|
||||
@ -133,7 +143,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
});
|
||||
|
||||
//loadDefaultKeywords();
|
||||
|
||||
|
||||
|
||||
initButtons();
|
||||
|
||||
@ -160,7 +170,6 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
selectAllMenuItem.addActionListener(actList);
|
||||
|
||||
|
||||
|
||||
if (IngestManager.getDefault().isModuleRunning(KeywordSearchIngestModule.getDefault())) {
|
||||
initIngest(0);
|
||||
} else {
|
||||
@ -173,13 +182,13 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String changed = evt.getPropertyName();
|
||||
Object oldValue = evt.getOldValue();
|
||||
if (changed.equals(IngestModuleEvent.COMPLETED.toString() )
|
||||
if (changed.equals(IngestModuleEvent.COMPLETED.toString())
|
||||
&& ((String) oldValue).equals(KeywordSearchIngestModule.MODULE_NAME)) {
|
||||
initIngest(1);
|
||||
} else if (changed.equals(IngestModuleEvent.STARTED.toString() )
|
||||
} else if (changed.equals(IngestModuleEvent.STARTED.toString())
|
||||
&& ((String) oldValue).equals(KeywordSearchIngestModule.MODULE_NAME)) {
|
||||
initIngest(0);
|
||||
} else if (changed.equals(IngestModuleEvent.STOPPED.toString() )
|
||||
} else if (changed.equals(IngestModuleEvent.STOPPED.toString())
|
||||
&& ((String) oldValue).equals(KeywordSearchIngestModule.MODULE_NAME)) {
|
||||
initIngest(1);
|
||||
}
|
||||
@ -187,11 +196,11 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Initialize this panel depending on whether ingest is running
|
||||
* @param running
|
||||
* case 0: ingest running
|
||||
* case 1: ingest not running
|
||||
*
|
||||
* @param running case 0: ingest running
|
||||
* case 1: ingest not running
|
||||
*/
|
||||
private void initIngest(int running) {
|
||||
switch (running) {
|
||||
@ -253,7 +262,8 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
}
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
@ -286,16 +296,20 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
saveListButton = new javax.swing.JButton();
|
||||
exportButton = new javax.swing.JButton();
|
||||
|
||||
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.cutMenuItem.text")); // NOI18N
|
||||
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.cutMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(cutMenuItem);
|
||||
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.copyMenuItem.text")); // NOI18N
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.copyMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(copyMenuItem);
|
||||
|
||||
pasteMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.pasteMenuItem.text")); // NOI18N
|
||||
pasteMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.pasteMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(pasteMenuItem);
|
||||
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.selectAllMenuItem.text")); // NOI18N
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.selectAllMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(selectAllMenuItem);
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(340, 300));
|
||||
@ -310,35 +324,40 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
keywordTable.getTableHeader().setReorderingAllowed(false);
|
||||
jScrollPane1.setViewportView(keywordTable);
|
||||
|
||||
useForIngestCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.useForIngestCheckbox.text")); // NOI18N
|
||||
useForIngestCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.useForIngestCheckbox.text")); // NOI18N
|
||||
useForIngestCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
useForIngestCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
addWordButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.addWordButton.text")); // NOI18N
|
||||
addWordButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.addWordButton.text")); // NOI18N
|
||||
addWordButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
addWordButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
addWordField.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.addWordField.text")); // NOI18N
|
||||
addWordField.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.addWordField.text")); // NOI18N
|
||||
addWordField.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
addWordFieldActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chRegex.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.chRegex.text")); // NOI18N
|
||||
chRegex.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.chRegex.text")); // NOI18N
|
||||
chRegex.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
chRegexActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
deleteWordButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.deleteWordButton.text")); // NOI18N
|
||||
deleteWordButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.deleteWordButton.text")); // NOI18N
|
||||
deleteWordButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
deleteWordButtonActionPerformed(evt);
|
||||
@ -374,28 +393,39 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
ingestMessagesCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.ingestMessagesCheckbox.text")); // NOI18N
|
||||
ingestMessagesCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText")); // NOI18N
|
||||
ingestMessagesCheckbox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.ingestMessagesCheckbox.text")); // NOI18N
|
||||
ingestMessagesCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText")); // NOI18N
|
||||
ingestMessagesCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
ingestMessagesCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
keywordsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.keywordsLabel.text")); // NOI18N
|
||||
keywordsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.keywordsLabel.text")); // NOI18N
|
||||
|
||||
keywordOptionsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.keywordOptionsLabel.text")); // NOI18N
|
||||
keywordOptionsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.keywordOptionsLabel.text")); // NOI18N
|
||||
|
||||
listOptionsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.listOptionsLabel.text")); // NOI18N
|
||||
listOptionsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.listOptionsLabel.text")); // NOI18N
|
||||
|
||||
deleteListButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/delete16.png"))); // NOI18N
|
||||
deleteListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.deleteListButton.text")); // NOI18N
|
||||
deleteListButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/delete16.png"))); // NOI18N
|
||||
deleteListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.deleteListButton.text")); // NOI18N
|
||||
|
||||
saveListButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/save16.png"))); // NOI18N
|
||||
saveListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.saveListButton.text")); // NOI18N
|
||||
saveListButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/save16.png"))); // NOI18N
|
||||
saveListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.saveListButton.text")); // NOI18N
|
||||
|
||||
exportButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/export16.png"))); // NOI18N
|
||||
exportButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class, "KeywordSearchEditListPanel.exportButton.text")); // NOI18N
|
||||
exportButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/export16.png"))); // NOI18N
|
||||
exportButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchEditListPanel.class,
|
||||
"KeywordSearchEditListPanel.exportButton.text")); // NOI18N
|
||||
exportButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
exportButtonActionPerformed(evt);
|
||||
@ -474,16 +504,19 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void addWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addWordButtonActionPerformed
|
||||
private void addWordButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addWordButtonActionPerformed
|
||||
String newWord = addWordField.getText().trim();
|
||||
boolean isLiteral = !chRegex.isSelected();
|
||||
final Keyword keyword = new Keyword(newWord, isLiteral);
|
||||
@ -491,8 +524,11 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
if (newWord.equals("")) {
|
||||
return;
|
||||
} else if (currentKeywordList.hasKeyword(keyword)) {
|
||||
KeywordSearchUtil.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.addWordButtonAction.kwAlreadyExistsMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
KeywordSearchUtil
|
||||
.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.addWordButtonAction.kwAlreadyExistsMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -507,8 +543,10 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
valid = false;
|
||||
}
|
||||
if (!valid) {
|
||||
KeywordSearchUtil.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.invalidKwMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
KeywordSearchUtil
|
||||
.displayDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.newKwTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.invalidKwMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -521,29 +559,36 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
initButtons();
|
||||
}//GEN-LAST:event_addWordButtonActionPerformed
|
||||
|
||||
private void deleteWordButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteWordButtonActionPerformed
|
||||
if (KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.removeKwMsg")
|
||||
, NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.deleteWordButtonActionPerformed.delConfirmMsg")
|
||||
, KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN) ) {
|
||||
|
||||
tableModel.deleteSelected(keywordTable.getSelectedRows());
|
||||
KeywordSearchListsXML.getCurrent().addList(currentKeywordList);
|
||||
initButtons();
|
||||
private void deleteWordButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteWordButtonActionPerformed
|
||||
if (KeywordSearchUtil
|
||||
.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.removeKwMsg")
|
||||
, NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.deleteWordButtonActionPerformed.delConfirmMsg")
|
||||
, KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN)) {
|
||||
|
||||
tableModel.deleteSelected(keywordTable.getSelectedRows());
|
||||
KeywordSearchListsXML.getCurrent().addList(currentKeywordList);
|
||||
initButtons();
|
||||
}
|
||||
}//GEN-LAST:event_deleteWordButtonActionPerformed
|
||||
|
||||
private void addWordFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addWordFieldActionPerformed
|
||||
private void addWordFieldActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addWordFieldActionPerformed
|
||||
addWordButtonActionPerformed(evt);
|
||||
}//GEN-LAST:event_addWordFieldActionPerformed
|
||||
|
||||
private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
|
||||
private void exportButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
|
||||
|
||||
final String FEATURE_NAME = "Keyword List Export";
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
final String EXTENSION = "xml";
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.exportButtonActionPerformed.fileFilterLabel"), EXTENSION);
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.exportButtonActionPerformed.fileFilterLabel"),
|
||||
EXTENSION);
|
||||
chooser.setFileFilter(filter);
|
||||
chooser.setSelectedFile(new File(currentKeywordList.getName()));
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
@ -565,8 +610,10 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
boolean shouldWrite = true;
|
||||
if (selFile.exists()) {
|
||||
shouldWrite = KeywordSearchUtil.displayConfirmDialog(FEATURE_NAME,
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.exportButtonActionPerformed.fileExistPrompt",
|
||||
selFile.getName()), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.exportButtonActionPerformed.fileExistPrompt",
|
||||
selFile.getName()),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
}
|
||||
if (!shouldWrite) {
|
||||
return;
|
||||
@ -575,14 +622,16 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
|
||||
KeywordSearchListsXML reader = KeywordSearchListsXML.getCurrent();
|
||||
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> toWrite = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> toWrite
|
||||
= new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
toWrite.add(reader.getList(currentKeywordList.getName()));
|
||||
final KeywordSearchListsXML exporter = new KeywordSearchListsXML(fileAbs);
|
||||
boolean written = exporter.saveLists(toWrite);
|
||||
if (written) {
|
||||
KeywordSearchUtil.displayDialog(FEATURE_NAME,
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.exportButtonActionPerformed.kwListExportedMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.exportButtonActionPerformed.kwListExportedMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_exportButtonActionPerformed
|
||||
@ -590,14 +639,16 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
|
||||
private void chRegexActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chRegexActionPerformed
|
||||
}//GEN-LAST:event_chRegexActionPerformed
|
||||
|
||||
private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useForIngestCheckboxActionPerformed
|
||||
ingestMessagesCheckbox.setEnabled(useForIngestCheckbox.isSelected());
|
||||
currentKeywordList.setUseForIngest(useForIngestCheckbox.isSelected());
|
||||
KeywordSearchListsXML updater = KeywordSearchListsXML.getCurrent();
|
||||
updater.addList(currentKeywordList);
|
||||
}//GEN-LAST:event_useForIngestCheckboxActionPerformed
|
||||
private void useForIngestCheckboxActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useForIngestCheckboxActionPerformed
|
||||
ingestMessagesCheckbox.setEnabled(useForIngestCheckbox.isSelected());
|
||||
currentKeywordList.setUseForIngest(useForIngestCheckbox.isSelected());
|
||||
KeywordSearchListsXML updater = KeywordSearchListsXML.getCurrent();
|
||||
updater.addList(currentKeywordList);
|
||||
}//GEN-LAST:event_useForIngestCheckboxActionPerformed
|
||||
|
||||
private void ingestMessagesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ingestMessagesCheckboxActionPerformed
|
||||
private void ingestMessagesCheckboxActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ingestMessagesCheckboxActionPerformed
|
||||
currentKeywordList.setIngestMessages(ingestMessagesCheckbox.isSelected());
|
||||
KeywordSearchListsXML updater = KeywordSearchListsXML.getCurrent();
|
||||
updater.addList(currentKeywordList);
|
||||
@ -658,19 +709,19 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt)
|
||||
public void load() {
|
||||
// Implemented by parent panel
|
||||
}
|
||||
|
||||
|
||||
KeywordSearchListsAbstract.KeywordSearchList getCurrentKeywordList() {
|
||||
return currentKeywordList;
|
||||
}
|
||||
|
||||
|
||||
void setCurrentKeywordList(KeywordSearchListsAbstract.KeywordSearchList list) {
|
||||
currentKeywordList = list;
|
||||
}
|
||||
|
||||
|
||||
void addDeleteButtonActionPerformed(ActionListener l) {
|
||||
deleteListButton.addActionListener(l);
|
||||
}
|
||||
|
||||
|
||||
void addSaveButtonActionPerformed(ActionListener l) {
|
||||
saveListButton.addActionListener(l);
|
||||
}
|
||||
@ -698,7 +749,8 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt)
|
||||
colName = NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.kwColName");
|
||||
break;
|
||||
case 1:
|
||||
colName = NbBundle.getMessage(this.getClass(), "KeywordSearchEditListPanel.exportButtonActionPerformed.regExColName");
|
||||
colName = NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchEditListPanel.exportButtonActionPerformed.regExColName");
|
||||
break;
|
||||
default:
|
||||
;
|
||||
@ -710,7 +762,7 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt)
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
Object ret = null;
|
||||
if(currentKeywordList == null) {
|
||||
if (currentKeywordList == null) {
|
||||
return "";
|
||||
}
|
||||
Keyword word = currentKeywordList.getKeywords().get(rowIndex);
|
||||
@ -743,7 +795,7 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt)
|
||||
}
|
||||
|
||||
void addKeyword(Keyword keyword) {
|
||||
if(!currentKeywordList.hasKeyword(keyword)) {
|
||||
if (!currentKeywordList.hasKeyword(keyword)) {
|
||||
currentKeywordList.getKeywords().add(keyword);
|
||||
}
|
||||
fireTableDataChanged();
|
||||
@ -757,7 +809,7 @@ private void useForIngestCheckboxActionPerformed(java.awt.event.ActionEvent evt)
|
||||
void deleteSelected(int[] selected) {
|
||||
List<Keyword> words = currentKeywordList.getKeywords();
|
||||
Arrays.sort(selected);
|
||||
for(int arrayi = selected.length-1; arrayi >= 0; arrayi--) {
|
||||
for (int arrayi = selected.length - 1; arrayi >= 0; arrayi--) {
|
||||
words.remove(selected[arrayi]);
|
||||
}
|
||||
resync();
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.Action;
|
||||
|
||||
import org.openide.nodes.FilterNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Node.Property;
|
||||
@ -120,23 +121,29 @@ class KeywordSearchFilterNode extends FilterNode {
|
||||
public List<Action> visit(File f) {
|
||||
return getFileActions();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Action> visit(DerivedFile f) {
|
||||
return getFileActions();
|
||||
}
|
||||
|
||||
|
||||
private List<Action> getFileActions() {
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl"), KeywordSearchFilterNode.this));
|
||||
actions.add(new ExternalViewerAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.openExternViewActLbl"), getOriginal()));
|
||||
actions.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl"),
|
||||
KeywordSearchFilterNode.this));
|
||||
actions.add(new ExternalViewerAction(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.openExternViewActLbl"),
|
||||
getOriginal()));
|
||||
actions.add(null);
|
||||
actions.add(ExtractAction.getInstance());
|
||||
actions.add(new HashSearchAction(NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.searchSameMd5"), getOriginal()));
|
||||
actions.add(new HashSearchAction(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchFilterNode.getFileActions.searchSameMd5"),
|
||||
getOriginal()));
|
||||
actions.add(null); // creates a menu separator
|
||||
actions.add(AddContentTagAction.getInstance());
|
||||
actions.addAll(ContextMenuExtensionPoint.getActions());
|
||||
return actions;
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,9 +36,11 @@ import java.util.logging.Level;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import org.apache.tika.Tika;
|
||||
import org.netbeans.api.progress.aggregate.AggregateProgressFactory;
|
||||
import org.netbeans.api.progress.aggregate.AggregateProgressHandle;
|
||||
@ -75,7 +77,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown;
|
||||
* ingest update interval) Runs a periodic keyword / regular expression search
|
||||
* on currently configured lists for ingest and writes results to blackboard
|
||||
* Reports interesting events to Inbox and to viewers
|
||||
*
|
||||
* <p/>
|
||||
* Registered as a module in layer.xml
|
||||
*/
|
||||
public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
@ -96,10 +98,13 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
int getTime() {
|
||||
return time;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchIngestModule.class.getName());
|
||||
public static final String MODULE_NAME = "Keyword Search";
|
||||
public static final String MODULE_DESCRIPTION = "Performs file indexing and periodic search using keywords and regular expressions in lists.";
|
||||
public static final String MODULE_DESCRIPTION
|
||||
= "Performs file indexing and periodic search using keywords and regular expressions in lists.";
|
||||
final public static String MODULE_VERSION = Version.getVersion();
|
||||
private static KeywordSearchIngestModule instance = null;
|
||||
private IngestServices services;
|
||||
@ -132,7 +137,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
private KeywordSearchIngestSimplePanel simpleConfigPanel;
|
||||
private KeywordSearchConfigurationPanel advancedConfigPanel;
|
||||
private Tika tikaFormatDetector;
|
||||
|
||||
|
||||
|
||||
private enum IngestStatus {
|
||||
TEXT_INGESTED, /// Text was extracted by knowing file type and text_ingested
|
||||
@ -141,7 +146,9 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
SKIPPED_ERROR_INDEXING, ///< File was skipped because index engine had problems
|
||||
SKIPPED_ERROR_TEXTEXTRACT, ///< File was skipped because of text extraction issues
|
||||
SKIPPED_ERROR_IO ///< File was skipped because of IO issues reading it
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
private Map<Long, IngestStatus> ingestStatus;
|
||||
|
||||
//private constructor to ensure singleton instance
|
||||
@ -175,9 +182,10 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
curDataSourceIds.add(fileSourceId);
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting image id of file processed by keyword search: " + abstractFile.getName(), ex);
|
||||
logger.log(Level.SEVERE,
|
||||
"Error getting image id of file processed by keyword search: " + abstractFile.getName(), ex);
|
||||
}
|
||||
|
||||
|
||||
if (abstractFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR)) {
|
||||
//skip indexing of virtual dirs (no content, no real name) - will index children files
|
||||
return ProcessResult.OK;
|
||||
@ -189,14 +197,13 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
//notify depending module that keyword search (would) encountered error for this file
|
||||
ingestStatus.put(abstractFile.getId(), IngestStatus.SKIPPED_ERROR_IO);
|
||||
return ProcessResult.ERROR;
|
||||
}
|
||||
else if (KeywordSearchSettings.getSkipKnown() && abstractFile.getKnown().equals(FileKnown.KNOWN)) {
|
||||
} else if (KeywordSearchSettings.getSkipKnown() && abstractFile.getKnown().equals(FileKnown.KNOWN)) {
|
||||
//index meta-data only
|
||||
indexer.indexFile(abstractFile, false);
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
processedFiles = true;
|
||||
processedFiles = true;
|
||||
|
||||
//check if it's time to commit after previous processing
|
||||
checkRunCommitSearch();
|
||||
@ -337,7 +344,6 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
/**
|
||||
* Initializes the module for new ingest run Sets up threads, timers,
|
||||
* retrieves settings, keyword lists to run on
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void init(IngestModuleInit initContext) {
|
||||
@ -356,7 +362,8 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
if (!server.isRunning()) {
|
||||
String msg = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.badInitMsg");
|
||||
logger.log(Level.SEVERE, msg);
|
||||
String details = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.tryStopSolrMsg", msg);
|
||||
String details = NbBundle
|
||||
.getMessage(this.getClass(), "KeywordSearchIngestModule.init.tryStopSolrMsg", msg);
|
||||
services.postMessage(IngestMessage.createErrorMessage(++messageID, instance, msg, details));
|
||||
return;
|
||||
|
||||
@ -399,8 +406,11 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
initKeywords();
|
||||
|
||||
if (keywords.isEmpty() || keywordLists.isEmpty()) {
|
||||
services.postMessage(IngestMessage.createWarningMessage(++messageID, instance, NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.noKwInLstMsg"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.init.onlyIdxKwSkipMsg")));
|
||||
services.postMessage(IngestMessage.createWarningMessage(++messageID, instance,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.init.noKwInLstMsg"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.init.onlyIdxKwSkipMsg")));
|
||||
}
|
||||
|
||||
processedFiles = false;
|
||||
@ -439,14 +449,13 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
@Override
|
||||
public javax.swing.JPanel getSimpleConfiguration(String context) {
|
||||
KeywordSearchListsXML.getCurrent().reload();
|
||||
|
||||
|
||||
if (null == simpleConfigPanel) {
|
||||
simpleConfigPanel = new KeywordSearchIngestSimplePanel();
|
||||
}
|
||||
else {
|
||||
simpleConfigPanel = new KeywordSearchIngestSimplePanel();
|
||||
} else {
|
||||
simpleConfigPanel.load();
|
||||
}
|
||||
|
||||
|
||||
return simpleConfigPanel;
|
||||
}
|
||||
|
||||
@ -455,7 +464,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
if (advancedConfigPanel == null) {
|
||||
advancedConfigPanel = new KeywordSearchConfigurationPanel();
|
||||
}
|
||||
|
||||
|
||||
advancedConfigPanel.load();
|
||||
return advancedConfigPanel;
|
||||
}
|
||||
@ -465,7 +474,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
if (advancedConfigPanel != null) {
|
||||
advancedConfigPanel.store();
|
||||
}
|
||||
|
||||
|
||||
if (simpleConfigPanel != null) {
|
||||
simpleConfigPanel.load();
|
||||
}
|
||||
@ -543,23 +552,42 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("<table border=0><tr><td>").append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.knowFileHeaderLbl")).append("</td><td>").append(text_ingested).append("</td></tr>");
|
||||
msg.append("<tr><td>").append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.fileGenStringsHead")).append("</td><td>").append(strings_ingested).append("</td></tr>");
|
||||
msg.append("<tr><td>").append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.mdOnlyLbl")).append("</td><td>").append(metadata_ingested).append("</td></tr>");
|
||||
msg.append("<tr><td>").append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.idxErrLbl")).append("</td><td>").append(error_index).append("</td></tr>");
|
||||
msg.append("<tr><td>").append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.errTxtLbl")).append("</td><td>").append(error_text).append("</td></tr>");
|
||||
msg.append("<tr><td>").append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.errIoLbl")).append("</td><td>").append(error_io).append("</td></tr>");
|
||||
msg.append("<table border=0><tr><td>")
|
||||
.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.knowFileHeaderLbl"))
|
||||
.append("</td><td>").append(text_ingested).append("</td></tr>");
|
||||
msg.append("<tr><td>").append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.postIndexSummary.fileGenStringsHead"))
|
||||
.append("</td><td>").append(strings_ingested).append("</td></tr>");
|
||||
msg.append("<tr><td>")
|
||||
.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.mdOnlyLbl"))
|
||||
.append("</td><td>").append(metadata_ingested).append("</td></tr>");
|
||||
msg.append("<tr><td>")
|
||||
.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.idxErrLbl"))
|
||||
.append("</td><td>").append(error_index).append("</td></tr>");
|
||||
msg.append("<tr><td>")
|
||||
.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.errTxtLbl"))
|
||||
.append("</td><td>").append(error_text).append("</td></tr>");
|
||||
msg.append("<tr><td>")
|
||||
.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.errIoLbl"))
|
||||
.append("</td><td>").append(error_io).append("</td></tr>");
|
||||
msg.append("</table>");
|
||||
String indexStats = msg.toString();
|
||||
logger.log(Level.INFO, "Keyword Indexing Completed: " + indexStats);
|
||||
services.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, this, NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.kwIdxResultsLbl"), indexStats));
|
||||
services.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, this,
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.postIndexSummary.kwIdxResultsLbl"),
|
||||
indexStats));
|
||||
if (error_index > 0) {
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.kwIdxErrsTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.kwIdxErrMsgFiles", error_index));
|
||||
}
|
||||
else if (error_io + error_text > 0) {
|
||||
MessageNotifyUtil.Notify.warn(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.kwIdxWarnMsgTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.postIndexSummary.idxErrReadFilesMsg"));
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.postIndexSummary.kwIdxErrsTitle"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.postIndexSummary.kwIdxErrMsgFiles",
|
||||
error_index));
|
||||
} else if (error_io + error_text > 0) {
|
||||
MessageNotifyUtil.Notify.warn(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.postIndexSummary.kwIdxWarnMsgTitle"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.postIndexSummary.idxErrReadFilesMsg"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,8 +723,8 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
* streaming) from the file Divide the file into chunks and index the
|
||||
* chunks
|
||||
*
|
||||
* @param aFile file to extract strings from, divide into chunks and
|
||||
* index
|
||||
* @param aFile file to extract strings from, divide into chunks and
|
||||
* index
|
||||
* @param detectedFormat mime-type detected, or null if none detected
|
||||
* @return true if the file was text_ingested, false otherwise
|
||||
* @throws IngesterException exception thrown if indexing failed
|
||||
@ -728,7 +756,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
* Extract strings using heuristics from the file and add to index.
|
||||
*
|
||||
* @param aFile file to extract strings from, divide into chunks and
|
||||
* index
|
||||
* index
|
||||
* @return true if the file was text_ingested, false otherwise
|
||||
*/
|
||||
private boolean extractStringsAndIndex(AbstractFile aFile) {
|
||||
@ -737,12 +765,16 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.STRINGS_INGESTED);
|
||||
return true;
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Failed to extract strings and ingest, file '" + aFile.getName() + "' (id: " + aFile.getId() + ").");
|
||||
logger.log(Level.WARNING,
|
||||
"Failed to extract strings and ingest, file '" + aFile.getName() + "' (id: " + aFile
|
||||
.getId() + ").");
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
return false;
|
||||
}
|
||||
} catch (IngesterException ex) {
|
||||
logger.log(Level.WARNING, "Failed to extract strings and ingest, file '" + aFile.getName() + "' (id: " + aFile.getId() + ").", ex);
|
||||
logger.log(Level.WARNING,
|
||||
"Failed to extract strings and ingest, file '" + aFile.getName() + "' (id: " + aFile.getId()
|
||||
+ ").", ex);
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
return false;
|
||||
}
|
||||
@ -752,9 +784,9 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
* Check with every extractor if it supports the file with the detected
|
||||
* format
|
||||
*
|
||||
* @param aFile file to check for
|
||||
* @param aFile file to check for
|
||||
* @param detectedFormat mime-type with detected format (such as
|
||||
* text/plain) or null if not detected
|
||||
* text/plain) or null if not detected
|
||||
* @return true if text extraction is supported
|
||||
*/
|
||||
private boolean isTextExtractSupported(AbstractFile aFile, String detectedFormat) {
|
||||
@ -770,17 +802,18 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
/**
|
||||
* Adds the file to the index. Detects file type, calls extractors, etc.
|
||||
*
|
||||
* @param aFile File to analyze
|
||||
* @param aFile File to analyze
|
||||
* @param indexContent False if only metadata should be text_ingested. True if
|
||||
* content and metadata should be index.
|
||||
* content and metadata should be index.
|
||||
*/
|
||||
private void indexFile(AbstractFile aFile, boolean indexContent) {
|
||||
//logger.log(Level.INFO, "Processing AbstractFile: " + abstractFile.getName());
|
||||
|
||||
TskData.TSK_DB_FILES_TYPE_ENUM aType = aFile.getType();
|
||||
|
||||
TskData.TSK_DB_FILES_TYPE_ENUM aType = aFile.getType();
|
||||
|
||||
// unallocated and unused blocks can only have strings extracted from them.
|
||||
if ((aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))) {
|
||||
if ((aType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) || aType
|
||||
.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))) {
|
||||
extractStringsAndIndex(aFile);
|
||||
}
|
||||
|
||||
@ -790,8 +823,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
try {
|
||||
ingester.ingest(aFile, false); //meta-data only
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.METADATA_INGESTED);
|
||||
}
|
||||
catch (IngesterException ex) {
|
||||
} catch (IngesterException ex) {
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
logger.log(Level.WARNING, "Unable to index meta-data for file: " + aFile.getId(), ex);
|
||||
}
|
||||
@ -804,11 +836,9 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
try {
|
||||
is = new ReadContentInputStream(aFile);
|
||||
detectedFormat = tikaFormatDetector.detect(is, aFile.getName());
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Could not detect format using tika for file: " + aFile, e);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
@ -818,9 +848,9 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @@@ Add file type signature to blackboard here
|
||||
|
||||
|
||||
//logger.log(Level.INFO, "Detected format: " + aFile.getName() + " " + detectedFormat);
|
||||
|
||||
// we skip archive formats that are opened by the archive module.
|
||||
@ -829,8 +859,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
try {
|
||||
ingester.ingest(aFile, false); //meta-data only
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.METADATA_INGESTED);
|
||||
}
|
||||
catch (IngesterException ex) {
|
||||
} catch (IngesterException ex) {
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.SKIPPED_ERROR_INDEXING);
|
||||
logger.log(Level.WARNING, "Unable to index meta-data for file: " + aFile.getId(), ex);
|
||||
}
|
||||
@ -843,7 +872,9 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
try {
|
||||
//logger.log(Level.INFO, "indexing: " + aFile.getName());
|
||||
if (!extractTextAndIndex(aFile, detectedFormat)) {
|
||||
logger.log(Level.WARNING, "Failed to extract text and ingest, file '" + aFile.getName() + "' (id: " + aFile.getId() + ").");
|
||||
logger.log(Level.WARNING,
|
||||
"Failed to extract text and ingest, file '" + aFile.getName() + "' (id: " + aFile
|
||||
.getId() + ").");
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.SKIPPED_ERROR_TEXTEXTRACT);
|
||||
} else {
|
||||
ingestStatus.put(aFile.getId(), IngestStatus.TEXT_INGESTED);
|
||||
@ -906,15 +937,21 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
logger.log(Level.INFO, "Pending start of new searcher");
|
||||
}
|
||||
|
||||
final String displayName = NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.displayName") +
|
||||
(finalRun ? (" - "+ NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.finalizeMsg")) : "");
|
||||
progressGroup = AggregateProgressFactory.createSystemHandle(displayName + (" ("+
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.pendingMsg") +")"), null, new Cancellable() {
|
||||
final String displayName =
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.displayName") +
|
||||
(finalRun ? (" - " + NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.doInBackGround.finalizeMsg"))
|
||||
: "");
|
||||
progressGroup = AggregateProgressFactory.createSystemHandle(displayName + (" (" +
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.pendingMsg") + ")"),
|
||||
null, new Cancellable() {
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
logger.log(Level.INFO, "Cancelling the searcher by user.");
|
||||
if (progressGroup != null) {
|
||||
progressGroup.setDisplayName(displayName + " ("+ NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.cancelMsg") +"...)");
|
||||
progressGroup.setDisplayName(displayName + " (" + NbBundle
|
||||
.getMessage(this.getClass(), "KeywordSearchIngestModule.doInBackGround.cancelMsg")
|
||||
+ "...)");
|
||||
}
|
||||
return Searcher.this.cancel(true);
|
||||
}
|
||||
@ -954,7 +991,8 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
|
||||
for (Keyword keywordQuery : keywords) {
|
||||
if (this.isCancelled()) {
|
||||
logger.log(Level.INFO, "Cancel detected, bailing before new keyword processed: " + keywordQuery.getQuery());
|
||||
logger.log(Level.INFO,
|
||||
"Cancel detected, bailing before new keyword processed: " + keywordQuery.getQuery());
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -974,15 +1012,15 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
boolean isRegex = !keywordQuery.isLiteral();
|
||||
if (isRegex) {
|
||||
del = new TermComponentQuery(keywordQuery);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
del = new LuceneQuery(keywordQuery);
|
||||
del.escape();
|
||||
del.escape();
|
||||
}
|
||||
|
||||
//limit search to currently ingested data sources
|
||||
//set up a filter with 1 or more image ids OR'ed
|
||||
final KeywordQueryFilter dataSourceFilter = new KeywordQueryFilter(KeywordQueryFilter.FilterType.DATA_SOURCE, curDataSourceIds);
|
||||
final KeywordQueryFilter dataSourceFilter = new KeywordQueryFilter(
|
||||
KeywordQueryFilter.FilterType.DATA_SOURCE, curDataSourceIds);
|
||||
del.addFilter(dataSourceFilter);
|
||||
|
||||
Map<String, List<ContentHit>> queryResult = null;
|
||||
@ -996,7 +1034,8 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
//likely case has closed and threads are being interrupted
|
||||
return null;
|
||||
} catch (CancellationException e) {
|
||||
logger.log(Level.INFO, "Cancel detected, bailing during keyword query: " + keywordQuery.getQuery());
|
||||
logger.log(Level.INFO,
|
||||
"Cancel detected, bailing during keyword query: " + keywordQuery.getQuery());
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Error performing query: " + keywordQuery.getQuery(), e);
|
||||
@ -1029,10 +1068,11 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
for (final Keyword hitTerm : newResults.keySet()) {
|
||||
//checking for cancellation between results
|
||||
if (this.isCancelled()) {
|
||||
logger.log(Level.INFO, "Cancel detected, bailing before new hit processed for query: " + keywordQuery.getQuery());
|
||||
logger.log(Level.INFO, "Cancel detected, bailing before new hit processed for query: "
|
||||
+ keywordQuery.getQuery());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// update progress display
|
||||
String hitDisplayStr = hitTerm.getQuery();
|
||||
if (hitDisplayStr.length() > 50) {
|
||||
@ -1042,15 +1082,17 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
//subProgresses[keywordsSearched].progress(unitProgress);
|
||||
|
||||
// this returns the unique files in the set with the first chunk that has a hit
|
||||
Map<AbstractFile, Integer> contentHitsFlattened = ContentHit.flattenResults(newResults.get(hitTerm));
|
||||
Map<AbstractFile, Integer> contentHitsFlattened = ContentHit
|
||||
.flattenResults(newResults.get(hitTerm));
|
||||
for (final AbstractFile hitFile : contentHitsFlattened.keySet()) {
|
||||
|
||||
|
||||
// get the snippet for the first hit in the file
|
||||
String snippet = null;
|
||||
final String snippetQuery = KeywordSearchUtil.escapeLuceneQuery(hitTerm.getQuery());
|
||||
int chunkId = contentHitsFlattened.get(hitFile);
|
||||
try {
|
||||
snippet = LuceneQuery.querySnippet(snippetQuery, hitFile.getId(), chunkId, isRegex, true);
|
||||
snippet = LuceneQuery
|
||||
.querySnippet(snippetQuery, hitFile.getId(), chunkId, isRegex, true);
|
||||
} catch (NoOpenCoreException e) {
|
||||
logger.log(Level.WARNING, "Error querying snippet: " + snippetQuery, e);
|
||||
//no reason to continue
|
||||
@ -1061,9 +1103,12 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
}
|
||||
|
||||
// write the blackboard artifact for this keyword in this file
|
||||
KeywordWriteResult written = del.writeToBlackBoard(hitTerm.getQuery(), hitFile, snippet, listName);
|
||||
KeywordWriteResult written = del
|
||||
.writeToBlackBoard(hitTerm.getQuery(), hitFile, snippet, listName);
|
||||
if (written == null) {
|
||||
logger.log(Level.WARNING, "BB artifact for keyword hit not written, file: " + hitFile + ", hit: " + hitTerm.toString());
|
||||
logger.log(Level.WARNING,
|
||||
"BB artifact for keyword hit not written, file: " + hitFile + ", hit: "
|
||||
+ hitTerm.toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1076,13 +1121,16 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
//final int hitFiles = newResults.size();
|
||||
|
||||
if (!keywordQuery.isLiteral()) {
|
||||
subjectSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.regExpHitLbl"));
|
||||
subjectSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.regExpHitLbl"));
|
||||
} else {
|
||||
subjectSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.kwHitLbl"));
|
||||
subjectSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.kwHitLbl"));
|
||||
}
|
||||
//subjectSb.append("<");
|
||||
String uniqueKey = null;
|
||||
BlackboardAttribute attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID());
|
||||
BlackboardAttribute attr = written
|
||||
.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID());
|
||||
if (attr != null) {
|
||||
final String keyword = attr.getValueString();
|
||||
subjectSb.append(keyword);
|
||||
@ -1096,49 +1144,64 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
detailsSb.append("<table border='0' cellpadding='4' width='280'>");
|
||||
//hit
|
||||
detailsSb.append("<tr>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.kwHitLThLbl"));
|
||||
detailsSb.append("<td>").append(EscapeUtil.escapeHtml(attr.getValueString())).append("</td>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.kwHitLThLbl"));
|
||||
detailsSb.append("<td>").append(EscapeUtil.escapeHtml(attr.getValueString()))
|
||||
.append("</td>");
|
||||
detailsSb.append("</tr>");
|
||||
|
||||
//preview
|
||||
attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID());
|
||||
attr = written.getAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID());
|
||||
if (attr != null) {
|
||||
detailsSb.append("<tr>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.previewThLbl"));
|
||||
detailsSb.append("<td>").append(EscapeUtil.escapeHtml(attr.getValueString())).append("</td>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.previewThLbl"));
|
||||
detailsSb.append("<td>").append(EscapeUtil.escapeHtml(attr.getValueString()))
|
||||
.append("</td>");
|
||||
detailsSb.append("</tr>");
|
||||
|
||||
}
|
||||
|
||||
//file
|
||||
detailsSb.append("<tr>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.fileThLbl"));
|
||||
detailsSb.append("<td>").append(hitFile.getParentPath()).append(hitFile.getName()).append("</td>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.fileThLbl"));
|
||||
detailsSb.append("<td>").append(hitFile.getParentPath()).append(hitFile.getName())
|
||||
.append("</td>");
|
||||
|
||||
detailsSb.append("</tr>");
|
||||
|
||||
|
||||
//list
|
||||
attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||
attr = written
|
||||
.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID());
|
||||
detailsSb.append("<tr>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.listThLbl"));
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.listThLbl"));
|
||||
detailsSb.append("<td>").append(attr.getValueString()).append("</td>");
|
||||
detailsSb.append("</tr>");
|
||||
|
||||
//regex
|
||||
if (!keywordQuery.isLiteral()) {
|
||||
attr = written.getAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID());
|
||||
attr = written.getAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID());
|
||||
if (attr != null) {
|
||||
detailsSb.append("<tr>");
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(), "KeywordSearchIngestModule.regExThLbl"));
|
||||
detailsSb.append(NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearchIngestModule.regExThLbl"));
|
||||
detailsSb.append("<td>").append(attr.getValueString()).append("</td>");
|
||||
detailsSb.append("</tr>");
|
||||
|
||||
}
|
||||
}
|
||||
detailsSb.append("</table>");
|
||||
|
||||
services.postMessage(IngestMessage.createDataMessage(++messageID, instance, subjectSb.toString(), detailsSb.toString(), uniqueKey, written.getArtifact()));
|
||||
|
||||
services.postMessage(IngestMessage.createDataMessage(++messageID, instance,
|
||||
subjectSb.toString(),
|
||||
detailsSb.toString(),
|
||||
uniqueKey,
|
||||
written.getArtifact()));
|
||||
}
|
||||
} //for each file hit
|
||||
|
||||
@ -1148,7 +1211,8 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
|
||||
//update artifact browser
|
||||
if (!newArtifacts.isEmpty()) {
|
||||
services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_KEYWORD_HIT, newArtifacts));
|
||||
services.fireModuleDataEvent(
|
||||
new ModuleDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_KEYWORD_HIT, newArtifacts));
|
||||
}
|
||||
} //if has results
|
||||
|
||||
@ -1198,6 +1262,7 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
//perform all essential cleanup that needs to be done right AFTER doInBackground() returns
|
||||
//without relying on done() method that is not guaranteed to run after background thread completes
|
||||
//NEED to call this method always right before doInBackground() returns
|
||||
|
||||
/**
|
||||
* Performs the cleanup that needs to be done right AFTER
|
||||
* doInBackground() returns without relying on done() method that is not
|
||||
@ -1235,7 +1300,8 @@ public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||
|
||||
//calculate new results but substracting results already obtained in this ingest
|
||||
//update currentResults map with the new results
|
||||
private Map<Keyword, List<ContentHit>> filterResults(Map<String, List<ContentHit>> queryResult, boolean isRegex) {
|
||||
private Map<Keyword, List<ContentHit>> filterResults(Map<String, List<ContentHit>> queryResult,
|
||||
boolean isRegex) {
|
||||
Map<Keyword, List<ContentHit>> newResults = new HashMap<Keyword, List<ContentHit>>();
|
||||
|
||||
for (String termResult : queryResult.keySet()) {
|
||||
|
@ -23,23 +23,28 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JTable;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
|
||||
|
||||
/**
|
||||
* Simple ingest config panel
|
||||
*/
|
||||
public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
|
||||
|
||||
private final static Logger logger = Logger.getLogger(KeywordSearchIngestSimplePanel.class.getName());
|
||||
public static final String PROP_OPTIONS = "Keyword Search_Options";
|
||||
private KeywordTableModel tableModel;
|
||||
private List<KeywordSearchListsAbstract.KeywordSearchList> lists;
|
||||
|
||||
/** Creates new form KeywordSearchIngestSimplePanel */
|
||||
/**
|
||||
* Creates new form KeywordSearchIngestSimplePanel
|
||||
*/
|
||||
public KeywordSearchIngestSimplePanel() {
|
||||
tableModel = new KeywordTableModel();
|
||||
lists = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
@ -47,10 +52,10 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
|
||||
private void customizeComponents() {
|
||||
listsTable.setModel(tableModel);
|
||||
|
||||
|
||||
listsTable.setTableHeader(null);
|
||||
listsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
//customize column witdhs
|
||||
@ -65,13 +70,13 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
column.setPreferredWidth(((int) (width * 0.92)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reloadLangs();
|
||||
reloadEncodings();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
KeywordSearchListsXML.getCurrent().reload();
|
||||
public void load() {
|
||||
KeywordSearchListsXML.getCurrent().reload();
|
||||
reloadLists();
|
||||
reloadLangs();
|
||||
reloadEncodings();
|
||||
@ -81,8 +86,9 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
public void store() {
|
||||
KeywordSearchListsXML.getCurrent().save();
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
@ -106,28 +112,35 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
|
||||
listsTable.setBackground(new java.awt.Color(240, 240, 240));
|
||||
listsTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
new Object[][]{
|
||||
|
||||
},
|
||||
new String [] {
|
||||
},
|
||||
new String[]{
|
||||
|
||||
}
|
||||
}
|
||||
));
|
||||
listsTable.setShowHorizontalLines(false);
|
||||
listsTable.setShowVerticalLines(false);
|
||||
listsScrollPane.setViewportView(listsTable);
|
||||
|
||||
titleLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.titleLabel.text")); // NOI18N
|
||||
titleLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.titleLabel.text")); // NOI18N
|
||||
|
||||
languagesLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.languagesLabel.text")); // NOI18N
|
||||
languagesLabel.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.languagesLabel.toolTipText")); // NOI18N
|
||||
languagesLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.languagesLabel.text")); // NOI18N
|
||||
languagesLabel.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.languagesLabel.toolTipText")); // NOI18N
|
||||
|
||||
languagesValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.languagesValLabel.text")); // NOI18N
|
||||
languagesValLabel.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.languagesValLabel.toolTipText")); // NOI18N
|
||||
languagesValLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.languagesValLabel.text")); // NOI18N
|
||||
languagesValLabel.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.languagesValLabel.toolTipText")); // NOI18N
|
||||
|
||||
encodingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.encodingsLabel.text")); // NOI18N
|
||||
encodingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.encodingsLabel.text")); // NOI18N
|
||||
|
||||
keywordSearchEncodings.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class, "KeywordSearchIngestSimplePanel.keywordSearchEncodings.text")); // NOI18N
|
||||
keywordSearchEncodings.setText(org.openide.util.NbBundle.getMessage(KeywordSearchIngestSimplePanel.class,
|
||||
"KeywordSearchIngestSimplePanel.keywordSearchEncodings.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -187,9 +200,9 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
List<SCRIPT> scripts = KeywordSearchSettings.getStringExtractScripts();
|
||||
StringBuilder langs = new StringBuilder();
|
||||
langs.append("<html>");
|
||||
for(int i=0; i<scripts.size(); i++) {
|
||||
for (int i = 0; i < scripts.size(); i++) {
|
||||
langs.append(scripts.get(i).toString());
|
||||
if(i+1 < scripts.size()) {
|
||||
if (i + 1 < scripts.size()) {
|
||||
langs.append(", ");
|
||||
}
|
||||
}
|
||||
@ -198,22 +211,24 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
this.languagesValLabel.setText(langsS);
|
||||
this.languagesValLabel.setToolTipText(langsS);
|
||||
}
|
||||
|
||||
|
||||
private void reloadEncodings() {
|
||||
String utf8 = KeywordSearchSettings.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString());
|
||||
String utf16 = KeywordSearchSettings.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString());
|
||||
String utf8 = KeywordSearchSettings
|
||||
.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString());
|
||||
String utf16 = KeywordSearchSettings
|
||||
.getStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString());
|
||||
ArrayList<String> encodingsList = new ArrayList<String>();
|
||||
if(utf8==null || Boolean.parseBoolean(utf8)) {
|
||||
if (utf8 == null || Boolean.parseBoolean(utf8)) {
|
||||
encodingsList.add("UTF8");
|
||||
}
|
||||
if(utf16==null || Boolean.parseBoolean(utf16)) {
|
||||
if (utf16 == null || Boolean.parseBoolean(utf16)) {
|
||||
encodingsList.add("UTF16");
|
||||
}
|
||||
String encodings = encodingsList.toString();
|
||||
encodings = encodings.substring(1, encodings.length()-1);
|
||||
encodings = encodings.substring(1, encodings.length() - 1);
|
||||
keywordSearchEncodings.setText(encodings);
|
||||
}
|
||||
|
||||
|
||||
private void reloadLists() {
|
||||
lists.clear();
|
||||
lists.addAll(KeywordSearchListsXML.getCurrent().getListsL());
|
||||
@ -234,13 +249,13 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchIngestSimplePanel.this.lists.get(rowIndex);
|
||||
if(columnIndex == 0) {
|
||||
if (columnIndex == 0) {
|
||||
return list.getUseForIngest();
|
||||
} else {
|
||||
return list.getName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return columnIndex == 0;
|
||||
@ -248,19 +263,19 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
|
||||
|
||||
KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchIngestSimplePanel.this.lists.get(rowIndex);
|
||||
if(columnIndex == 0){
|
||||
if (columnIndex == 0) {
|
||||
KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
|
||||
loader.addList(list.getName(), list.getKeywords(), (Boolean) aValue, false);
|
||||
reloadLists();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int c) {
|
||||
return getValueAt(0, c).getClass();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
@ -53,13 +54,15 @@ public abstract class KeywordSearchListsAbstract {
|
||||
|
||||
/**
|
||||
* Property change event support
|
||||
* In events: For all of these enums, the old value should be null, and
|
||||
* the new value should be the keyword list name string.
|
||||
* In events: For all of these enums, the old value should be null, and
|
||||
* the new value should be the keyword list name string.
|
||||
*/
|
||||
public enum ListsEvt {
|
||||
|
||||
LIST_ADDED, LIST_DELETED, LIST_UPDATED
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* get instance for managing the current keyword list of the application
|
||||
@ -77,41 +80,47 @@ public abstract class KeywordSearchListsAbstract {
|
||||
}
|
||||
|
||||
private void prepopulateLists() {
|
||||
if (! theLists.isEmpty()) {
|
||||
if (!theLists.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
//phone number
|
||||
List<Keyword> phones = new ArrayList<Keyword>();
|
||||
phones.add(new Keyword("[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
|
||||
phones.add(new Keyword("[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d", false,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
|
||||
//phones.add(new Keyword("\\d{8,10}", false));
|
||||
//IP address
|
||||
List<Keyword> ips = new ArrayList<Keyword>();
|
||||
ips.add(new Keyword("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS));
|
||||
ips.add(new Keyword(
|
||||
"(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])",
|
||||
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS));
|
||||
//email
|
||||
List<Keyword> emails = new ArrayList<Keyword>();
|
||||
emails.add(new Keyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
|
||||
emails.add(new Keyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}", false,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
|
||||
//URL
|
||||
List<Keyword> urls = new ArrayList<Keyword>();
|
||||
//urls.add(new Keyword("http://|https://|^www\\.", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
|
||||
urls.add(new Keyword("((((ht|f)tp(s?))\\://)|www\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&%\\$#\\=~_\\-]+))*", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
|
||||
urls.add(new Keyword(
|
||||
"((((ht|f)tp(s?))\\://)|www\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&%\\$#\\=~_\\-]+))*",
|
||||
false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
|
||||
|
||||
//urls.add(new Keyword("ssh://", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
|
||||
|
||||
//disable messages for harcoded/locked lists
|
||||
String name;
|
||||
|
||||
|
||||
name = "Phone Numbers";
|
||||
lockedLists.add(name);
|
||||
addList(name, phones, false, false, true);
|
||||
|
||||
|
||||
name = "IP Addresses";
|
||||
lockedLists.add(name);
|
||||
addList(name, ips, false, false, true);
|
||||
|
||||
|
||||
name = "Email Addresses";
|
||||
lockedLists.add(name);
|
||||
addList(name, emails, true, false, true);
|
||||
|
||||
|
||||
name = "URLs";
|
||||
lockedLists.add(name);
|
||||
addList(name, urls, false, false, true);
|
||||
@ -126,7 +135,7 @@ public abstract class KeywordSearchListsAbstract {
|
||||
//theLists.clear();
|
||||
//populate only the first time
|
||||
prepopulateLists();
|
||||
|
||||
|
||||
//reset all the lists other than locked lists (we don't save them to XML)
|
||||
//we want to preserve state of locked lists
|
||||
List<String> toClear = new ArrayList<String>();
|
||||
@ -137,8 +146,8 @@ public abstract class KeywordSearchListsAbstract {
|
||||
}
|
||||
for (String clearList : toClear) {
|
||||
theLists.remove(clearList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!this.listFileExists()) {
|
||||
//create new if it doesn't exist
|
||||
save();
|
||||
@ -283,8 +292,8 @@ public abstract class KeywordSearchListsAbstract {
|
||||
* adds the new word list using name id replacing old one if exists with the
|
||||
* same name
|
||||
*
|
||||
* @param name the name of the new list or list to replace
|
||||
* @param newList list of keywords
|
||||
* @param name the name of the new list or list to replace
|
||||
* @param newList list of keywords
|
||||
* @param useForIngest should this list be used for ingest
|
||||
* @return true if old list was replaced
|
||||
*/
|
||||
@ -300,14 +309,15 @@ public abstract class KeywordSearchListsAbstract {
|
||||
// }
|
||||
changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
|
||||
} else {
|
||||
theLists.put(name, new KeywordSearchList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
|
||||
theLists.put(name, new KeywordSearchList(name, curList.getDateCreated(), now, useForIngest, ingestMessages,
|
||||
newList, locked));
|
||||
// if (!locked) {
|
||||
// save();
|
||||
// }
|
||||
replaced = true;
|
||||
changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
|
||||
}
|
||||
|
||||
|
||||
return replaced;
|
||||
}
|
||||
|
||||
@ -323,7 +333,8 @@ public abstract class KeywordSearchListsAbstract {
|
||||
}
|
||||
|
||||
boolean addList(KeywordSearchList list) {
|
||||
return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked());
|
||||
return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(),
|
||||
list.isLocked());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -380,7 +391,7 @@ public abstract class KeywordSearchListsAbstract {
|
||||
//boolean saved = save();
|
||||
|
||||
for (KeywordSearchList list : newLists) {
|
||||
changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
|
||||
changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
|
||||
}
|
||||
for (KeywordSearchList over : overwritten) {
|
||||
changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
|
||||
@ -403,7 +414,7 @@ public abstract class KeywordSearchListsAbstract {
|
||||
//deleted = save();
|
||||
}
|
||||
changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
@ -412,11 +423,12 @@ public abstract class KeywordSearchListsAbstract {
|
||||
* writes out current list replacing the last lists file
|
||||
*/
|
||||
public abstract boolean save();
|
||||
|
||||
|
||||
/**
|
||||
* writes out current list replacing the last lists file
|
||||
*
|
||||
* @param isExport true is this save operation is an export and not a 'Save
|
||||
* As'
|
||||
* As'
|
||||
*/
|
||||
public abstract boolean save(boolean isExport);
|
||||
|
||||
@ -429,11 +441,11 @@ public abstract class KeywordSearchListsAbstract {
|
||||
File f = new File(filePath);
|
||||
return f.exists() && f.canRead() && f.canWrite();
|
||||
}
|
||||
|
||||
public void setUseForIngest(String key, boolean flag)
|
||||
{
|
||||
|
||||
public void setUseForIngest(String key, boolean flag) {
|
||||
theLists.get(key).setUseForIngest(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* a representation of a single keyword list created or loaded
|
||||
*/
|
||||
@ -447,7 +459,8 @@ public abstract class KeywordSearchListsAbstract {
|
||||
private List<Keyword> keywords;
|
||||
private Boolean locked;
|
||||
|
||||
KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords, boolean locked) {
|
||||
KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages,
|
||||
List<Keyword> keywords, boolean locked) {
|
||||
this.name = name;
|
||||
this.created = created;
|
||||
this.modified = modified;
|
||||
@ -457,7 +470,8 @@ public abstract class KeywordSearchListsAbstract {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords) {
|
||||
KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages,
|
||||
List<Keyword> keywords) {
|
||||
this(name, created, modified, useForIngest, ingestMessages, keywords, false);
|
||||
}
|
||||
|
||||
|
@ -30,46 +30,46 @@ import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* @author dfickling
|
||||
* KeywordSearchListsEncase adds support for Encase tab-delimited
|
||||
* keyword list exports to Autopsy.
|
||||
*
|
||||
* load() does the I/O operation, converting lines from the text file to
|
||||
* an unsorted list of EncaseFileEntrys
|
||||
* The next step is to recreate the original folder hierarchy,
|
||||
* and finally the EncaseFileEntries are converted to KeywordSearchLists
|
||||
*
|
||||
* KeywordSearchListsEncase adds support for Encase tab-delimited
|
||||
* keyword list exports to Autopsy.
|
||||
* <p/>
|
||||
* load() does the I/O operation, converting lines from the text file to
|
||||
* an unsorted list of EncaseFileEntrys
|
||||
* The next step is to recreate the original folder hierarchy,
|
||||
* and finally the EncaseFileEntries are converted to KeywordSearchLists
|
||||
*/
|
||||
class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
|
||||
class KeywordSearchListsEncase extends KeywordSearchListsAbstract {
|
||||
|
||||
ArrayList<EncaseFileEntry> entriesUnsorted;
|
||||
EncaseFileEntry rootEntry;
|
||||
|
||||
|
||||
public KeywordSearchListsEncase(String encasePath) {
|
||||
super(encasePath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Follow the EncaseFileEntry hierarchy starting with given entry
|
||||
* Create list for each Folder entry, add keyword for each Expression
|
||||
*
|
||||
* @param entry
|
||||
* @param parentPath
|
||||
* @param parentPath
|
||||
*/
|
||||
private void doCreateListsFromEntries(EncaseFileEntry entry, String parentPath) {
|
||||
String name;
|
||||
if(parentPath.isEmpty()) {
|
||||
if (parentPath.isEmpty()) {
|
||||
name = entry.name;
|
||||
} else {
|
||||
name = parentPath + "/" + entry.name;
|
||||
}
|
||||
|
||||
|
||||
List<Keyword> children = new ArrayList<Keyword>();
|
||||
for(EncaseFileEntry child : entry.children) {
|
||||
switch(child.type) {
|
||||
for (EncaseFileEntry child : entry.children) {
|
||||
switch (child.type) {
|
||||
case Folder:
|
||||
doCreateListsFromEntries(child, name);
|
||||
break;
|
||||
case Expression:
|
||||
if(child.flags.contains(EncaseFlag.pg)) { // Skip GREP keywords
|
||||
if (child.flags.contains(EncaseFlag.pg)) { // Skip GREP keywords
|
||||
break;
|
||||
}
|
||||
children.add(new Keyword(child.value, true));
|
||||
@ -77,22 +77,22 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
}
|
||||
}
|
||||
// Give each list a unique name
|
||||
if(theLists.containsKey(name)) {
|
||||
if (theLists.containsKey(name)) {
|
||||
int i = 2;
|
||||
while(theLists.containsKey(name + "(" + i + ")")) {
|
||||
i+=1;
|
||||
while (theLists.containsKey(name + "(" + i + ")")) {
|
||||
i += 1;
|
||||
}
|
||||
name = name + "(" + i + ")";
|
||||
}
|
||||
// Don't create lists if there are no keywords
|
||||
if (!children.isEmpty()) {
|
||||
KeywordSearchList newList = new KeywordSearchList(name, new Date(), new Date(),
|
||||
true, true, children);
|
||||
true, true, children);
|
||||
theLists.put(name, newList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Convert entriesUnsorted (a list of childless and parentless EncaseFileEntries) into an EncaseFileEntry structure
|
||||
*/
|
||||
private void doCreateEntryStructure(EncaseFileEntry parent) {
|
||||
@ -101,7 +101,7 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
child.hasParent = true;
|
||||
child.parent = parent;
|
||||
parent.addChild(child);
|
||||
if(!child.isFull()) {
|
||||
if (!child.isFull()) {
|
||||
doCreateEntryStructure(child);
|
||||
}
|
||||
if (!parent.isFull()) {
|
||||
@ -117,7 +117,7 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
public boolean save() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean save(boolean isExport) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
@ -126,11 +126,12 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
@Override
|
||||
public boolean load() {
|
||||
try {
|
||||
BufferedReader readBuffer = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "utf-16"));
|
||||
BufferedReader readBuffer = new BufferedReader(
|
||||
new InputStreamReader(new FileInputStream(filePath), "utf-16"));
|
||||
String structLine;
|
||||
String metaLine;
|
||||
entriesUnsorted = new ArrayList<EncaseFileEntry>();
|
||||
for(int line = 1; line < 6; line++) {
|
||||
for (int line = 1; line < 6; line++) {
|
||||
readBuffer.readLine();
|
||||
}
|
||||
while ((structLine = readBuffer.readLine()) != null && (metaLine = readBuffer.readLine()) != null) {
|
||||
@ -141,21 +142,22 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
String name = metaArr[1];
|
||||
String value = metaArr[2];
|
||||
ArrayList<EncaseFlag> flags = new ArrayList<EncaseFlag>();
|
||||
for(int i = 0; i < 17; i++) {
|
||||
if(metaArr.length < i+4) {
|
||||
for (int i = 0; i < 17; i++) {
|
||||
if (metaArr.length < i + 4) {
|
||||
continue;
|
||||
}
|
||||
if(!metaArr[i+3].equals("")) {
|
||||
if (!metaArr[i + 3].equals("")) {
|
||||
flags.add(EncaseFlag.getFlag(i));
|
||||
}
|
||||
}
|
||||
entriesUnsorted.add(new EncaseFileEntry(name, value, Integer.parseInt(childCount), false, null, type, flags));
|
||||
entriesUnsorted
|
||||
.add(new EncaseFileEntry(name, value, Integer.parseInt(childCount), false, null, type, flags));
|
||||
}
|
||||
this.rootEntry = entriesUnsorted.remove(0);
|
||||
doCreateEntryStructure(this.rootEntry);
|
||||
doCreateListsFromEntries(this.rootEntry, "");
|
||||
return true;
|
||||
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
logger.log(Level.INFO, "File at " + filePath + " does not exist!", ex);
|
||||
} catch (IOException ex) {
|
||||
@ -163,21 +165,21 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private enum EncaseMetaType {
|
||||
Expression, Folder;
|
||||
|
||||
|
||||
static EncaseMetaType getType(String type) {
|
||||
if(type.equals("5")) {
|
||||
if (type.equals("5")) {
|
||||
return Folder;
|
||||
} else if(type.equals("")) {
|
||||
} else if (type.equals("")) {
|
||||
return Expression;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported EncaseMetaType: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flags for EncaseFileEntries.
|
||||
* p8 = UTF-8
|
||||
@ -186,12 +188,12 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
*/
|
||||
private enum EncaseFlag {
|
||||
pc, pu, pb, p8, p7, pg, an, ph, or, di, um, st, ww, pr, lo, ta, cp;
|
||||
|
||||
|
||||
static EncaseFlag getFlag(int i) {
|
||||
return EncaseFlag.values()[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An entry in the Encase keyword list file.
|
||||
*/
|
||||
@ -204,7 +206,9 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
EncaseMetaType type;
|
||||
boolean hasParent;
|
||||
ArrayList<EncaseFlag> flags;
|
||||
EncaseFileEntry(String name, String value, int childCount, boolean hasParent, EncaseFileEntry parent, EncaseMetaType type, ArrayList<EncaseFlag> flags) {
|
||||
|
||||
EncaseFileEntry(String name, String value, int childCount, boolean hasParent, EncaseFileEntry parent,
|
||||
EncaseMetaType type, ArrayList<EncaseFlag> flags) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.childCount = childCount;
|
||||
@ -214,12 +218,14 @@ class KeywordSearchListsEncase extends KeywordSearchListsAbstract{
|
||||
this.type = type;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
boolean isFull() {
|
||||
return children.size() == childCount;
|
||||
}
|
||||
|
||||
void addChild(EncaseFileEntry child) {
|
||||
children.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -31,11 +31,13 @@ import java.util.List;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||
|
||||
/**
|
||||
@ -45,14 +47,16 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
|
||||
private Logger logger = Logger.getLogger(KeywordSearchListsManagementPanel.class.getName());
|
||||
private KeywordListTableModel tableModel;
|
||||
|
||||
/** Creates new form KeywordSearchListImportExportForm */
|
||||
|
||||
/**
|
||||
* Creates new form KeywordSearchListImportExportForm
|
||||
*/
|
||||
KeywordSearchListsManagementPanel() {
|
||||
tableModel = new KeywordListTableModel();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
|
||||
private void customizeComponents() {
|
||||
|
||||
|
||||
@ -92,7 +96,8 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
@ -123,76 +128,110 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
});
|
||||
jScrollPane1.setViewportView(listsTable);
|
||||
|
||||
newListButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/new16.png"))); // NOI18N
|
||||
newListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class, "KeywordSearchListsManagementPanel.newListButton.text")); // NOI18N
|
||||
newListButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/new16.png"))); // NOI18N
|
||||
newListButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class,
|
||||
"KeywordSearchListsManagementPanel.newListButton.text")); // NOI18N
|
||||
newListButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
newListButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
importButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/import16.png"))); // NOI18N
|
||||
importButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class, "KeywordSearchListsManagementPanel.importButton.text")); // NOI18N
|
||||
importButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/import16.png"))); // NOI18N
|
||||
importButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class,
|
||||
"KeywordSearchListsManagementPanel.importButton.text")); // NOI18N
|
||||
importButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
importButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
keywordListsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class, "KeywordSearchListsManagementPanel.keywordListsLabel.text")); // NOI18N
|
||||
keywordListsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsManagementPanel.class,
|
||||
"KeywordSearchListsManagementPanel.keywordListsLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(keywordListsLabel)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(newListButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(importButton, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addGap(0, 4, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1,
|
||||
javax.swing.GroupLayout.Alignment.TRAILING,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(
|
||||
javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(keywordListsLabel)
|
||||
.addGroup(
|
||||
layout.createSequentialGroup()
|
||||
.addComponent(
|
||||
newListButton,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
114,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(
|
||||
importButton,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE,
|
||||
126,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addGap(0, 4, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(keywordListsLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 414, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(newListButton)
|
||||
.addComponent(importButton))
|
||||
.addContainerGap())
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(keywordListsLabel)
|
||||
.addPreferredGap(
|
||||
javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
414, Short.MAX_VALUE)
|
||||
.addPreferredGap(
|
||||
javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(layout.createParallelGroup(
|
||||
javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(
|
||||
newListButton)
|
||||
.addComponent(
|
||||
importButton))
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void newListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newListButtonActionPerformed
|
||||
private void newListButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newListButtonActionPerformed
|
||||
KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
|
||||
String listName = (String) JOptionPane.showInputDialog(null, NbBundle.getMessage(this.getClass(), "KeywordSearch.newKwListTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"), JOptionPane.PLAIN_MESSAGE, null, null, "");
|
||||
String listName = (String) JOptionPane
|
||||
.showInputDialog(null, NbBundle.getMessage(this.getClass(), "KeywordSearch.newKwListTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"),
|
||||
JOptionPane.PLAIN_MESSAGE, null, null, "");
|
||||
if (listName == null || listName.trim().equals("")) {
|
||||
return;
|
||||
}
|
||||
boolean shouldAdd = false;
|
||||
if (writer.listExists(listName)) {
|
||||
if (writer.getList(listName).isLocked() ) {
|
||||
boolean replace = KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.keywordListAlreadyExistMsg", listName), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
if (writer.getList(listName).isLocked()) {
|
||||
boolean replace = KeywordSearchUtil
|
||||
.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearch.newKeywordListMsg"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearch.keywordListAlreadyExistMsg", listName),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
if (replace) {
|
||||
shouldAdd = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean replace = KeywordSearchUtil.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearch.newKwListTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListAlreadyExistMsg", listName), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
} else {
|
||||
boolean replace = KeywordSearchUtil
|
||||
.displayConfirmDialog(NbBundle.getMessage(this.getClass(), "KeywordSearch.newKwListTitle"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearch.kwListAlreadyExistMsg", listName),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.WARN);
|
||||
if (replace) {
|
||||
shouldAdd = true;
|
||||
}
|
||||
@ -211,12 +250,14 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
tableModel.resync();
|
||||
}//GEN-LAST:event_newListButtonActionPerformed
|
||||
|
||||
private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
|
||||
private void importButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
final String[] EXTENSION = new String[]{"xml", "txt"};
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.fileExtensionFilterLbl"), EXTENSION);
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsManagementPanel.fileExtensionFilterLbl"),
|
||||
EXTENSION);
|
||||
chooser.setFileFilter(filter);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
|
||||
@ -229,23 +270,26 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
|
||||
//force append extension if not given
|
||||
String fileAbs = selFile.getAbsolutePath();
|
||||
|
||||
|
||||
final KeywordSearchListsAbstract reader;
|
||||
|
||||
if(KeywordSearchUtil.isXMLList(fileAbs)) {
|
||||
|
||||
if (KeywordSearchUtil.isXMLList(fileAbs)) {
|
||||
reader = new KeywordSearchListsXML(fileAbs);
|
||||
} else {
|
||||
reader = new KeywordSearchListsEncase(fileAbs);
|
||||
}
|
||||
|
||||
|
||||
if (!reader.load()) {
|
||||
KeywordSearchUtil.displayDialog(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.importListFileDialogMsg", fileAbs),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> toImport = reader.getListsL();
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> toImportConfirmed = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> toImportConfirmed
|
||||
= new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
|
||||
final KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
|
||||
|
||||
@ -253,16 +297,19 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
//check name collisions
|
||||
if (writer.listExists(list.getName())) {
|
||||
Object[] options = {NbBundle.getMessage(this.getClass(), "KeywordSearch.yesOwMsg"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.noSkipMsg"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.cancelImportMsg")};
|
||||
int choice = JOptionPane.showOptionDialog(this,
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.overwriteListPrompt", list.getName()),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.importOwConflict"),
|
||||
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
options,
|
||||
options[0]);
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearch.overwriteListPrompt",
|
||||
list.getName()),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"KeywordSearch.importOwConflict"),
|
||||
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
options,
|
||||
options[0]);
|
||||
if (choice == JOptionPane.OK_OPTION) {
|
||||
toImportConfirmed.add(list);
|
||||
} else if (choice == JOptionPane.CANCEL_OPTION) {
|
||||
@ -282,7 +329,9 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
|
||||
if (!writer.writeLists(toImportConfirmed)) {
|
||||
KeywordSearchUtil.displayDialog(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"), NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"), KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.listImportFeatureTitle"),
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearch.kwListFailImportMsg"),
|
||||
KeywordSearchUtil.DIALOG_MESSAGE_TYPE.INFO);
|
||||
}
|
||||
|
||||
}
|
||||
@ -290,9 +339,9 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
}//GEN-LAST:event_importButtonActionPerformed
|
||||
|
||||
private void listsTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_listsTableKeyPressed
|
||||
if(evt.getKeyCode() == KeyEvent.VK_DELETE) {
|
||||
if (evt.getKeyCode() == KeyEvent.VK_DELETE) {
|
||||
int[] selected = listsTable.getSelectedRows();
|
||||
if(selected.length == 0) {
|
||||
if (selected.length == 0) {
|
||||
return;
|
||||
}
|
||||
KeywordSearchListsXML deleter = KeywordSearchListsXML.getCurrent();
|
||||
@ -319,12 +368,12 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
public void load() {
|
||||
listsTable.clearSelection();
|
||||
}
|
||||
|
||||
|
||||
void resync() {
|
||||
tableModel.resync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class KeywordListTableModel extends AbstractTableModel {
|
||||
//data
|
||||
|
||||
@ -368,7 +417,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
//delete selected from handle, events are fired from the handle
|
||||
void deleteSelected(int[] selected) {
|
||||
List<String> toDel = new ArrayList<String>();
|
||||
for(int i = 0; i < selected.length; i++){
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
toDel.add((String) getValueAt(0, selected[i]));
|
||||
}
|
||||
for (String del : toDel) {
|
||||
@ -381,7 +430,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel implements Op
|
||||
fireTableDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addListSelectionListener(ListSelectionListener l) {
|
||||
listsTable.getSelectionModel().addListSelectionListener(l);
|
||||
}
|
||||
|
@ -163,31 +163,38 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
|
||||
private void initIngest(boolean running) {
|
||||
if (running) {
|
||||
ingestRunning = true;
|
||||
searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
|
||||
searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestMsg" ));
|
||||
searchAddButton.setText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestTitle"));
|
||||
searchAddButton.setToolTipText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIngestMsg"));
|
||||
listsTableModel.resync();
|
||||
|
||||
|
||||
} else {
|
||||
ingestRunning = false;
|
||||
searchAddButton.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
|
||||
searchAddButton.setToolTipText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
|
||||
searchAddButton.setText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.searchIngestTitle"));
|
||||
searchAddButton.setToolTipText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.addIdxSearchMsg"));
|
||||
listsTableModel.resync();
|
||||
}
|
||||
updateIngestIndexLabel(running);
|
||||
}
|
||||
|
||||
|
||||
private void updateIngestIndexLabel(boolean ingestRunning) {
|
||||
if (ingestRunning) {
|
||||
ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg", filesIndexed));
|
||||
}
|
||||
else {
|
||||
ingestIndexLabel.setText(NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.fileIndexCtMsg", filesIndexed));
|
||||
ingestIndexLabel.setText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.ongoingIngestMsg",
|
||||
filesIndexed));
|
||||
} else {
|
||||
ingestIndexLabel.setText(
|
||||
NbBundle.getMessage(this.getClass(), "KeywordSearchListsViewerPanel.initIngest.fileIndexCtMsg",
|
||||
filesIndexed));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void postFilesIndexedChange() {
|
||||
updateIngestIndexLabel(ingestRunning);
|
||||
updateIngestIndexLabel(ingestRunning);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,18 +241,22 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
|
||||
|
||||
jSplitPane1.setRightComponent(rightPane);
|
||||
|
||||
manageListsButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.manageListsButton.text")); // NOI18N
|
||||
manageListsButton.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.manageListsButton.toolTipText")); // NOI18N
|
||||
manageListsButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class,
|
||||
"KeywordSearchListsViewerPanel.manageListsButton.text")); // NOI18N
|
||||
manageListsButton.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class,
|
||||
"KeywordSearchListsViewerPanel.manageListsButton.toolTipText")); // NOI18N
|
||||
manageListsButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
manageListsButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
searchAddButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.searchAddButton.text")); // NOI18N
|
||||
searchAddButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class,
|
||||
"KeywordSearchListsViewerPanel.searchAddButton.text")); // NOI18N
|
||||
|
||||
ingestIndexLabel.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
|
||||
ingestIndexLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.ingestIndexLabel.text")); // NOI18N
|
||||
ingestIndexLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class,
|
||||
"KeywordSearchListsViewerPanel.ingestIndexLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@ -278,9 +289,11 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void manageListsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageListsButtonActionPerformed
|
||||
private void manageListsButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageListsButtonActionPerformed
|
||||
SystemAction.get(KeywordSearchConfigurationAction.class).performAction();
|
||||
}//GEN-LAST:event_manageListsButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel ingestIndexLabel;
|
||||
private javax.swing.JSplitPane jSplitPane1;
|
||||
@ -440,7 +453,8 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer {
|
||||
}
|
||||
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> getSelectedListsL() {
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> ret = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
List<KeywordSearchListsAbstract.KeywordSearchList> ret
|
||||
= new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
|
||||
for (String s : getSelectedLists()) {
|
||||
ret.add(listsHandle.getList(s));
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import java.util.logging.Level;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
@ -39,7 +40,7 @@ import org.w3c.dom.NodeList;
|
||||
* Manages reading and writing of keyword lists to user settings XML file keywords.xml
|
||||
* or to any file provided in constructor
|
||||
*/
|
||||
public class KeywordSearchListsXML extends KeywordSearchListsAbstract{
|
||||
public class KeywordSearchListsXML extends KeywordSearchListsAbstract {
|
||||
|
||||
private static final String ROOT_EL = "keyword_lists";
|
||||
private static final String LIST_EL = "keyword_list";
|
||||
@ -57,23 +58,23 @@ public class KeywordSearchListsXML extends KeywordSearchListsAbstract{
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchListsXML.class.getName());
|
||||
private DateFormat dateFormatter;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to obtain handle on other that the current keyword list
|
||||
* (such as for import or export)
|
||||
*
|
||||
* @param xmlFile xmlFile to obtain KeywordSearchListsXML handle on
|
||||
*/
|
||||
KeywordSearchListsXML(String xmlFile) {
|
||||
super(xmlFile);
|
||||
dateFormatter = new SimpleDateFormat(DATE_FORMAT);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean save() {
|
||||
return save(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean save(boolean isExport) {
|
||||
boolean success = false;
|
||||
@ -102,7 +103,7 @@ public class KeywordSearchListsXML extends KeywordSearchListsAbstract{
|
||||
listEl.setAttribute(LIST_NAME_ATTR, listName);
|
||||
listEl.setAttribute(LIST_CREATE_ATTR, created);
|
||||
listEl.setAttribute(LIST_MOD_ATTR, modified);
|
||||
|
||||
|
||||
// only write the 'useForIngest' and 'ingestMessages' attributes
|
||||
// if we're not exporting the list
|
||||
if (!isExport) {
|
||||
@ -112,7 +113,7 @@ public class KeywordSearchListsXML extends KeywordSearchListsAbstract{
|
||||
|
||||
for (Keyword keyword : keywords) {
|
||||
Element keywordEl = doc.createElement(KEYWORD_EL);
|
||||
String literal = keyword.isLiteral()?"true":"false";
|
||||
String literal = keyword.isLiteral() ? "true" : "false";
|
||||
keywordEl.setAttribute(KEYWORD_LITERAL_ATTR, literal);
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE selectorType = keyword.getType();
|
||||
if (selectorType != null) {
|
||||
@ -154,30 +155,29 @@ public class KeywordSearchListsXML extends KeywordSearchListsAbstract{
|
||||
final String name = listEl.getAttribute(LIST_NAME_ATTR);
|
||||
final String created = listEl.getAttribute(LIST_CREATE_ATTR);
|
||||
final String modified = listEl.getAttribute(LIST_MOD_ATTR);
|
||||
|
||||
|
||||
//set these bools to true by default, if they don't exist in XML
|
||||
Boolean useForIngestBool;
|
||||
Boolean ingestMessagesBool;
|
||||
|
||||
if (listEl.hasAttribute(LIST_USE_FOR_INGEST) ) {
|
||||
Boolean ingestMessagesBool;
|
||||
|
||||
if (listEl.hasAttribute(LIST_USE_FOR_INGEST)) {
|
||||
useForIngestBool = Boolean.parseBoolean(listEl.getAttribute(LIST_USE_FOR_INGEST));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
useForIngestBool = true;
|
||||
}
|
||||
|
||||
if (listEl.hasAttribute(LIST_INGEST_MSGS)) {
|
||||
ingestMessagesBool = Boolean.parseBoolean(listEl.getAttribute(LIST_INGEST_MSGS));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ingestMessagesBool = true;
|
||||
}
|
||||
|
||||
|
||||
Date createdDate = dateFormatter.parse(created);
|
||||
Date modDate = dateFormatter.parse(modified);
|
||||
|
||||
List<Keyword> words = new ArrayList<Keyword>();
|
||||
KeywordSearchList list = new KeywordSearchList(name, createdDate, modDate, useForIngestBool, ingestMessagesBool, words);
|
||||
KeywordSearchList list = new KeywordSearchList(name, createdDate, modDate, useForIngestBool,
|
||||
ingestMessagesBool, words);
|
||||
|
||||
//parse all words
|
||||
NodeList wordsNList = listEl.getElementsByTagName(KEYWORD_EL);
|
||||
@ -188,12 +188,13 @@ public class KeywordSearchListsXML extends KeywordSearchListsAbstract{
|
||||
boolean isLiteral = literal.equals("true");
|
||||
Keyword keyword = new Keyword(wordEl.getTextContent(), isLiteral);
|
||||
String selector = wordEl.getAttribute(KEYWORD_SELECTOR_ATTR);
|
||||
if (! selector.equals("")) {
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE selectorType = BlackboardAttribute.ATTRIBUTE_TYPE.fromLabel(selector);
|
||||
if (!selector.equals("")) {
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE selectorType = BlackboardAttribute.ATTRIBUTE_TYPE
|
||||
.fromLabel(selector);
|
||||
keyword.setType(selectorType);
|
||||
}
|
||||
words.add(keyword);
|
||||
|
||||
|
||||
}
|
||||
theLists.put(name, list);
|
||||
}
|
||||
|
@ -35,6 +35,6 @@ class KeywordSearchModuleException extends Exception {
|
||||
public KeywordSearchModuleException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,17 +7,19 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
|
||||
@OptionsPanelController.TopLevelRegistration(
|
||||
categoryName = "#OptionsCategory_Name_KeywordSearchOptions",
|
||||
iconBase = "org/sleuthkit/autopsy/keywordsearch/options-icon.png",
|
||||
position = 2,
|
||||
keywords = "#OptionsCategory_Keywords_KeywordSearchOptions",
|
||||
keywordsCategory = "KeywordSearchOptions")
|
||||
@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_KeywordSearchOptions=Keyword Search", "OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search"})
|
||||
categoryName = "#OptionsCategory_Name_KeywordSearchOptions",
|
||||
iconBase = "org/sleuthkit/autopsy/keywordsearch/options-icon.png",
|
||||
position = 2,
|
||||
keywords = "#OptionsCategory_Keywords_KeywordSearchOptions",
|
||||
keywordsCategory = "KeywordSearchOptions")
|
||||
@org.openide.util.NbBundle.Messages({"OptionsCategory_Name_KeywordSearchOptions=Keyword Search",
|
||||
"OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search"})
|
||||
public final class KeywordSearchOptionsPanelController extends OptionsPanelController {
|
||||
|
||||
private KeywordSearchConfigurationPanel panel;
|
||||
|
@ -34,20 +34,23 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
|
||||
/**
|
||||
* Keyword search toolbar (in upper right, by default) which allows to search for single terms or phrases
|
||||
*
|
||||
* The toolbar uses a different font from the rest of the application, Monospaced 14,
|
||||
* due to the necessity to find a font that displays both Arabic and Asian fonts at an acceptable size.
|
||||
* The default, Tahoma 14, could not perform this task at the desired size, and neither could numerous other fonts.
|
||||
* <p/>
|
||||
* The toolbar uses a different font from the rest of the application, Monospaced 14,
|
||||
* due to the necessity to find a font that displays both Arabic and Asian fonts at an acceptable size.
|
||||
* The default, Tahoma 14, could not perform this task at the desired size, and neither could numerous other fonts.
|
||||
*/
|
||||
class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
|
||||
@ -57,7 +60,9 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
private boolean entered = false;
|
||||
private static KeywordSearchPanel instance;
|
||||
|
||||
/** Creates new form KeywordSearchPanel */
|
||||
/**
|
||||
* Creates new form KeywordSearchPanel
|
||||
*/
|
||||
private KeywordSearchPanel() {
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
@ -78,8 +83,7 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
//nothing to update
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void customizeComponents() {
|
||||
|
||||
listener = new KeywordPropertyChangeListener();
|
||||
@ -172,7 +176,8 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
entered = false;
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
@ -195,19 +200,24 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
searchButton = new javax.swing.JLabel();
|
||||
listsButton = new javax.swing.JButton();
|
||||
|
||||
regExCheckboxMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.regExCheckboxMenuItem.text")); // NOI18N
|
||||
regExCheckboxMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.regExCheckboxMenuItem.text")); // NOI18N
|
||||
settingsMenu.add(regExCheckboxMenuItem);
|
||||
|
||||
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.cutMenuItem.text")); // NOI18N
|
||||
cutMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.cutMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(cutMenuItem);
|
||||
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.copyMenuItem.text")); // NOI18N
|
||||
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.copyMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(copyMenuItem);
|
||||
|
||||
pasteMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.pasteMenuItem.text")); // NOI18N
|
||||
pasteMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.pasteMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(pasteMenuItem);
|
||||
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.selectAllMenuItem.text")); // NOI18N
|
||||
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.selectAllMenuItem.text")); // NOI18N
|
||||
rightClickMenu.add(selectAllMenuItem);
|
||||
|
||||
setOpaque(false);
|
||||
@ -217,7 +227,8 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
|
||||
searchBox.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N
|
||||
searchBox.setForeground(java.awt.Color.lightGray);
|
||||
searchBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.searchBox.text")); // NOI18N
|
||||
searchBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.searchBox.text")); // NOI18N
|
||||
searchBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 3, 4, 1));
|
||||
searchBox.setEnabled(false);
|
||||
searchBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -226,8 +237,10 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
}
|
||||
});
|
||||
|
||||
settingsLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/dropdown-icon.png"))); // NOI18N
|
||||
settingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.settingsLabel.text")); // NOI18N
|
||||
settingsLabel.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/dropdown-icon.png"))); // NOI18N
|
||||
settingsLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.settingsLabel.text")); // NOI18N
|
||||
settingsLabel.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 2, 1, 2));
|
||||
settingsLabel.setEnabled(false);
|
||||
settingsLabel.setMaximumSize(new java.awt.Dimension(23, 20));
|
||||
@ -237,16 +250,20 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
public void mouseEntered(java.awt.event.MouseEvent evt) {
|
||||
settingsLabelMouseEntered(evt);
|
||||
}
|
||||
|
||||
public void mouseExited(java.awt.event.MouseEvent evt) {
|
||||
settingsLabelMouseExited(evt);
|
||||
}
|
||||
|
||||
public void mousePressed(java.awt.event.MouseEvent evt) {
|
||||
settingsLabelMousePressed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
searchButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/search-icon.png"))); // NOI18N
|
||||
searchButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "KeywordSearchPanel.searchButton.text")); // NOI18N
|
||||
searchButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/search-icon.png"))); // NOI18N
|
||||
searchButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class,
|
||||
"KeywordSearchPanel.searchButton.text")); // NOI18N
|
||||
searchButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 2, 1, 2));
|
||||
searchButton.setEnabled(false);
|
||||
searchButton.setMaximumSize(new java.awt.Dimension(23, 20));
|
||||
@ -276,13 +293,16 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
.addComponent(searchButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
listsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/watchbutton-icon.png"))); // NOI18N
|
||||
listsButton.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/watchbutton-icon.png"))); // NOI18N
|
||||
listsButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchPanel.class, "ListBundleName")); // NOI18N
|
||||
listsButton.setBorderPainted(false);
|
||||
listsButton.setContentAreaFilled(false);
|
||||
listsButton.setEnabled(false);
|
||||
listsButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/watchbutton-icon-rollover.png"))); // NOI18N
|
||||
listsButton.setRolloverSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/watchbutton-icon-pressed.png"))); // NOI18N
|
||||
listsButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource(
|
||||
"/org/sleuthkit/autopsy/keywordsearch/watchbutton-icon-rollover.png"))); // NOI18N
|
||||
listsButton.setRolloverSelectedIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/watchbutton-icon-pressed.png"))); // NOI18N
|
||||
listsButton.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mousePressed(java.awt.event.MouseEvent evt) {
|
||||
listsButtonMousePressed(evt);
|
||||
@ -297,17 +317,21 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(listsButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
|
||||
.addComponent(searchBoxPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(listsButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18,
|
||||
Short.MAX_VALUE)
|
||||
.addComponent(searchBoxPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 244,
|
||||
javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listsButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(searchBoxPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE)
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listsButton, javax.swing.GroupLayout.Alignment.TRAILING,
|
||||
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
|
||||
Short.MAX_VALUE)
|
||||
.addComponent(searchBoxPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -331,7 +355,8 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
maybeShowListsPopup(evt);
|
||||
}//GEN-LAST:event_listsButtonMousePressed
|
||||
|
||||
private void listsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_listsButtonActionPerformed
|
||||
private void listsButtonActionPerformed(
|
||||
java.awt.event.ActionEvent evt) {//GEN-FIRST:event_listsButtonActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_listsButtonActionPerformed
|
||||
|
||||
@ -340,12 +365,15 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
}//GEN-LAST:event_searchButtonMousePressed
|
||||
|
||||
private void settingsLabelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_settingsLabelMouseEntered
|
||||
settingsLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/dropdown-icon-rollover.png")));
|
||||
settingsLabel.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/dropdown-icon-rollover.png")));
|
||||
}//GEN-LAST:event_settingsLabelMouseEntered
|
||||
|
||||
private void settingsLabelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_settingsLabelMouseExited
|
||||
settingsLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/dropdown-icon.png")));
|
||||
settingsLabel.setIcon(new javax.swing.ImageIcon(
|
||||
getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/dropdown-icon.png")));
|
||||
}//GEN-LAST:event_settingsLabelMouseExited
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JMenuItem copyMenuItem;
|
||||
private javax.swing.JMenuItem cutMenuItem;
|
||||
@ -405,11 +433,9 @@ class KeywordSearchPanel extends AbstractKeywordSearchPerformer {
|
||||
final int numIndexedFiles = KeywordSearch.getServer().queryNumIndexedFiles();
|
||||
KeywordSearch.fireNumIndexedFilesChange(null, new Integer(numIndexedFiles));
|
||||
//setFilesIndexed(numIndexedFiles);
|
||||
}
|
||||
catch (NoOpenCoreException ex) {
|
||||
} catch (NoOpenCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error executing Solr query, " + ex);
|
||||
}
|
||||
catch (KeywordSearchModuleException se) {
|
||||
} catch (KeywordSearchModuleException se) {
|
||||
logger.log(Level.SEVERE, "Error executing Solr query, " + se.getMessage());
|
||||
}
|
||||
break;
|
||||
|
@ -25,43 +25,48 @@ import java.util.List;
|
||||
* KeywordSearchPerformers are perform different searches from
|
||||
* different interfaces and places in the application. Its
|
||||
* results are then passed to a KeywordSearchQuery implementation
|
||||
* to perform the actual search.
|
||||
* to perform the actual search.
|
||||
*/
|
||||
interface KeywordSearchPerformerInterface {
|
||||
|
||||
|
||||
/**
|
||||
* Does this interface support multi-word queries?
|
||||
* @return
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isMultiwordQuery();
|
||||
|
||||
|
||||
/**
|
||||
* True if the user did not choose to do a regular expression search
|
||||
* @return
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isLuceneQuerySelected();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the query/keyword string that the user entered/selected
|
||||
*
|
||||
* @return Keyword to search
|
||||
*/
|
||||
String getQueryText();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of Keyword objects that the user entered/selected
|
||||
* @return
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Keyword> getQueryList();
|
||||
|
||||
|
||||
/**
|
||||
* Set the number of files that have been indexed
|
||||
* @param filesIndexed
|
||||
*
|
||||
* @param filesIndexed
|
||||
*/
|
||||
void setFilesIndexed(int filesIndexed);
|
||||
|
||||
|
||||
/**
|
||||
* Performs the search using the selected keywords.
|
||||
* Creates a DataResultTopComponent with the results.
|
||||
* Performs the search using the selected keywords.
|
||||
* Creates a DataResultTopComponent with the results.
|
||||
*/
|
||||
void search();
|
||||
}
|
||||
|
@ -21,92 +21,99 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.solr.client.solrj.response.TermsResponse.Term;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Interface for a search query. Implemented by various
|
||||
* engines or methods of using the same engine. One of these
|
||||
* is created for each query.
|
||||
* is created for each query.
|
||||
*/
|
||||
interface KeywordSearchQuery {
|
||||
|
||||
/**
|
||||
* validate the query pre execution
|
||||
*
|
||||
* @return true if the query passed validation
|
||||
*/
|
||||
public boolean validate();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* execute query and return results without publishing them
|
||||
* return results for all matching terms
|
||||
*
|
||||
* @return
|
||||
* @throws NoOpenCoreException if query failed due to server error, this could be a notification to stop processing
|
||||
* @return
|
||||
*/
|
||||
public Map<String,List<ContentHit>> performQuery() throws NoOpenCoreException;
|
||||
|
||||
|
||||
public Map<String, List<ContentHit>> performQuery() throws NoOpenCoreException;
|
||||
|
||||
|
||||
/**
|
||||
* Set an optional filter to narrow down the search
|
||||
* Adding multiple filters ANDs them together.
|
||||
* For OR, add multiple ids to a single filter
|
||||
*
|
||||
* @param filter filter to set on the query
|
||||
*/
|
||||
public void addFilter(KeywordQueryFilter filter);
|
||||
|
||||
|
||||
/**
|
||||
* Set an optional SOLR field to narrow down the search
|
||||
*
|
||||
* @param field field to set on the query
|
||||
*/
|
||||
public void setField(String field);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* escape the query string and use the escaped string in the query
|
||||
*/
|
||||
public void escape();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if query was escaped
|
||||
*/
|
||||
public boolean isEscaped();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if query is a literal query (non regex)
|
||||
*/
|
||||
public boolean isLiteral();
|
||||
|
||||
|
||||
/**
|
||||
* return original keyword/query string
|
||||
*
|
||||
* @return the query String supplied originally
|
||||
*/
|
||||
public String getQueryString();
|
||||
|
||||
|
||||
/**
|
||||
* return escaped keyword/query string if escaping was done
|
||||
*
|
||||
* @return the escaped query string, or original string if no escaping done
|
||||
*/
|
||||
public String getEscapedQueryString();
|
||||
|
||||
|
||||
/**
|
||||
* get terms associated with the query if any
|
||||
*
|
||||
* @return collection of terms associated with the query
|
||||
*/
|
||||
public Collection<Term>getTerms();
|
||||
|
||||
public Collection<Term> getTerms();
|
||||
|
||||
/**
|
||||
* write results to blackboard per single term and file hit
|
||||
* this method is useful if something else should keep track of partial results to write
|
||||
* @param termHit term for only which to write results
|
||||
*
|
||||
* @param termHit term for only which to write results
|
||||
* @param newFsHit AbstractFile for which to write results for this hit
|
||||
* @param snippet snippet preview with hit context, or null if there is no snippet
|
||||
* @param snippet snippet preview with hit context, or null if there is no snippet
|
||||
* @param listName listname
|
||||
* @return collection of results (with cached bb artifacts/attributes) created and written
|
||||
*/
|
||||
public KeywordWriteResult writeToBlackBoard(String termHit, AbstractFile newFsHit, String snippet, String listName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -36,17 +36,18 @@ import org.sleuthkit.autopsy.keywordsearch.KeywordSearch.QueryType;
|
||||
|
||||
/**
|
||||
* Responsible for running a keyword search query and displaying
|
||||
* the results.
|
||||
* the results.
|
||||
*/
|
||||
class KeywordSearchQueryManager {
|
||||
|
||||
// how to display the results
|
||||
public enum Presentation {
|
||||
FLAT, // all results are in a single level (even if multiple keywords and reg-exps are used). We made this because we were having problems with multiple-levels of nodes and the thumbnail and table view sharing an ExplorerManager. IconView seemed to change EM so that it did not allow lower levels to be selected.
|
||||
FLAT,
|
||||
// all results are in a single level (even if multiple keywords and reg-exps are used). We made this because we were having problems with multiple-levels of nodes and the thumbnail and table view sharing an ExplorerManager. IconView seemed to change EM so that it did not allow lower levels to be selected.
|
||||
COLLAPSE, // two levels. Keywords on top, files on bottom.
|
||||
DETAIL // not currently used, but seems like it has three levels of nodes
|
||||
};
|
||||
|
||||
|
||||
private List<Keyword> keywords;
|
||||
private Presentation presentation;
|
||||
private List<KeywordSearchQuery> queryDelegates;
|
||||
@ -55,8 +56,7 @@ class KeywordSearchQueryManager {
|
||||
private static Logger logger = Logger.getLogger(KeywordSearchQueryManager.class.getName());
|
||||
|
||||
/**
|
||||
*
|
||||
* @param queries Keywords to search for
|
||||
* @param queries Keywords to search for
|
||||
* @param presentation Presentation layout
|
||||
*/
|
||||
public KeywordSearchQueryManager(List<Keyword> queries, Presentation presentation) {
|
||||
@ -67,9 +67,8 @@ class KeywordSearchQueryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param query Keyword to search for
|
||||
* @param qt Query type
|
||||
* @param query Keyword to search for
|
||||
* @param qt Query type
|
||||
* @param presentation Presentation Layout
|
||||
*/
|
||||
public KeywordSearchQueryManager(String query, QueryType qt, Presentation presentation) {
|
||||
@ -81,9 +80,8 @@ class KeywordSearchQueryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param query Keyword to search for
|
||||
* @param isLiteral false if reg-exp
|
||||
* @param query Keyword to search for
|
||||
* @param isLiteral false if reg-exp
|
||||
* @param presentation Presentation layout
|
||||
*/
|
||||
public KeywordSearchQueryManager(String query, boolean isLiteral, Presentation presentation) {
|
||||
@ -138,7 +136,7 @@ class KeywordSearchQueryManager {
|
||||
// q.execute();
|
||||
// }
|
||||
// } else {
|
||||
|
||||
|
||||
//Collapsed view
|
||||
Collection<KeyValueQuery> things = new ArrayList<>();
|
||||
int queryID = 0;
|
||||
@ -154,11 +152,14 @@ class KeywordSearchQueryManager {
|
||||
String queryConcatStr = queryConcat.toString();
|
||||
final int queryConcatStrLen = queryConcatStr.length();
|
||||
final String queryStrShort = queryConcatStrLen > 15 ? queryConcatStr.substring(0, 14) + "..." : queryConcatStr;
|
||||
final String windowTitle = NbBundle.getMessage(this.getClass(), "KeywordSearchQueryManager.execute.exeWinTitle", ++resultWindowCount, queryStrShort);
|
||||
final String windowTitle = NbBundle
|
||||
.getMessage(this.getClass(), "KeywordSearchQueryManager.execute.exeWinTitle", ++resultWindowCount,
|
||||
queryStrShort);
|
||||
DataResultTopComponent searchResultWin = DataResultTopComponent.createInstance(windowTitle);
|
||||
if (things.size() > 0) {
|
||||
Children childThingNodes =
|
||||
Children.create(new KeywordSearchResultFactory(keywords, things, presentation, searchResultWin), true);
|
||||
Children.create(new KeywordSearchResultFactory(keywords, things, presentation, searchResultWin),
|
||||
true);
|
||||
|
||||
rootNode = new AbstractNode(childThingNodes);
|
||||
} else {
|
||||
@ -175,6 +176,7 @@ class KeywordSearchQueryManager {
|
||||
|
||||
/**
|
||||
* validate the queries before they are run
|
||||
*
|
||||
* @return false if any are invalid
|
||||
*/
|
||||
public boolean validate() {
|
||||
|
@ -27,9 +27,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
@ -54,7 +57,6 @@ import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
|
||||
|
||||
/**
|
||||
*
|
||||
* factory produces top level nodes with query
|
||||
* responsible for assembling nodes and columns in the right way
|
||||
* and performing lazy queries as needed
|
||||
@ -66,41 +68,41 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
public static enum CommonPropertyTypes {
|
||||
|
||||
KEYWORD {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getDisplayName();
|
||||
}
|
||||
},
|
||||
REGEX {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getDisplayName();
|
||||
}
|
||||
},
|
||||
CONTEXT {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getDisplayName();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
private final Presentation presentation;
|
||||
private List<Keyword> queries;
|
||||
private Collection<KeyValueQuery> things;
|
||||
private final DataResultTopComponent viewer; //viewer driving this child node factory
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchResultFactory.class.getName());
|
||||
|
||||
KeywordSearchResultFactory(List<Keyword> queries, Collection<KeyValueQuery> things, Presentation presentation, DataResultTopComponent viewer) {
|
||||
KeywordSearchResultFactory(List<Keyword> queries, Collection<KeyValueQuery> things, Presentation presentation,
|
||||
DataResultTopComponent viewer) {
|
||||
this.queries = queries;
|
||||
this.things = things;
|
||||
this.presentation = presentation;
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
KeywordSearchResultFactory(Keyword query, Collection<KeyValueQuery> things, Presentation presentation, DataResultTopComponent viewer) {
|
||||
KeywordSearchResultFactory(Keyword query, Collection<KeyValueQuery> things, Presentation presentation,
|
||||
DataResultTopComponent viewer) {
|
||||
queries = new ArrayList<>();
|
||||
queries.add(query);
|
||||
this.presentation = presentation;
|
||||
@ -109,9 +111,10 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
}
|
||||
|
||||
/**
|
||||
* call this at least for the parent Node, to make sure all common
|
||||
* call this at least for the parent Node, to make sure all common
|
||||
* properties are displayed as columns (since we are doing lazy child Node load
|
||||
* we need to preinitialize properties when sending parent Node)
|
||||
*
|
||||
* @param toSet property set map for a Node
|
||||
*/
|
||||
public static void initCommonProperties(Map<String, Object> toSet) {
|
||||
@ -121,7 +124,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
toSet.put(commonTypes[i].toString(), "");
|
||||
}
|
||||
|
||||
AbstractAbstractFileNode.AbstractFilePropertyType[] fsTypes = AbstractAbstractFileNode.AbstractFilePropertyType.values();
|
||||
AbstractAbstractFileNode.AbstractFilePropertyType[] fsTypes = AbstractAbstractFileNode.AbstractFilePropertyType
|
||||
.values();
|
||||
final int FS_PROPS_LEN = fsTypes.length;
|
||||
for (int i = 0; i < FS_PROPS_LEN; ++i) {
|
||||
toSet.put(fsTypes[i].toString(), "");
|
||||
@ -150,9 +154,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
setCommonProperty(map, CommonPropertyTypes.REGEX, Boolean.valueOf(!thing.getQuery().isEscaped()));
|
||||
ResultCollapsedChildFactory childFactory = new ResultCollapsedChildFactory(thing);
|
||||
childFactory.createKeysForFlatNodes(toPopulate);
|
||||
}
|
||||
}
|
||||
else if (presentation == Presentation.DETAIL) {
|
||||
}
|
||||
} else if (presentation == Presentation.DETAIL) {
|
||||
Iterator<KeyValueQuery> it = things.iterator();
|
||||
for (Keyword keyword : queries) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
@ -176,7 +179,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
toPopulate.add(thing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -185,9 +188,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
ChildFactory<KeyValueQuery> childFactory;
|
||||
if (presentation == Presentation.FLAT) {
|
||||
ResultCollapsedChildFactory factory = new ResultCollapsedChildFactory(thing);
|
||||
return factory.createFlatNodeForKey(thing);
|
||||
}
|
||||
else if (presentation == Presentation.COLLAPSE) {
|
||||
return factory.createFlatNodeForKey(thing);
|
||||
} else if (presentation == Presentation.COLLAPSE) {
|
||||
childFactory = new ResultCollapsedChildFactory(thing);
|
||||
final Node ret = new KeyValueNode(thing, Children.create(childFactory, true));
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@ -224,7 +226,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
public boolean createKeysForFlatNodes(List<KeyValueQuery> toPopulate) {
|
||||
return createKeys(toPopulate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<KeyValueQuery> toPopulate) {
|
||||
final KeyValueQuery queryThingQuery = queryThing;
|
||||
@ -236,7 +238,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
}
|
||||
|
||||
List<KeyValueQuery> tempList = new ArrayList<>();
|
||||
|
||||
|
||||
//execute the query and get fscontents matching
|
||||
Map<String, List<ContentHit>> tcqRes;
|
||||
try {
|
||||
@ -249,7 +251,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
|
||||
//get listname
|
||||
String listName = "";
|
||||
KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchListsXML.getCurrent().getListWithKeyword(tcq.getQueryString());
|
||||
KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchListsXML.getCurrent().getListWithKeyword(
|
||||
tcq.getQueryString());
|
||||
if (list != null) {
|
||||
listName = list.getName();
|
||||
}
|
||||
@ -264,7 +267,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
|
||||
try {
|
||||
String snippet;
|
||||
|
||||
|
||||
String snippetQuery = null;
|
||||
|
||||
if (literal_query) {
|
||||
@ -305,13 +308,14 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
}
|
||||
|
||||
final String highlightQueryEscaped = getHighlightQuery(tcq, literal_query, tcqRes, f);
|
||||
tempList.add(new KeyValueQueryContent(f.getName(), resMap, ++resID, f, highlightQueryEscaped, tcq, previewChunk, tcqRes));
|
||||
tempList.add(new KeyValueQueryContent(f.getName(), resMap, ++resID, f, highlightQueryEscaped, tcq,
|
||||
previewChunk, tcqRes));
|
||||
}
|
||||
|
||||
|
||||
// Add all the nodes to toPopulate at once. Minimizes node creation
|
||||
// EDT threads, which can slow and/or hang the UI on large queries.
|
||||
toPopulate.addAll(tempList);
|
||||
|
||||
|
||||
//write to bb
|
||||
//cannot reuse snippet in ResultWriter
|
||||
//because for regex searches in UI we compress results by showing a file per regex once (even if multiple term hits)
|
||||
@ -321,7 +325,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getHighlightQuery(KeywordSearchQuery tcq, boolean literal_query, Map<String, List<ContentHit>> tcqRes, AbstractFile f) {
|
||||
private String getHighlightQuery(KeywordSearchQuery tcq, boolean literal_query,
|
||||
Map<String, List<ContentHit>> tcqRes, AbstractFile f) {
|
||||
String highlightQueryEscaped;
|
||||
if (literal_query) {
|
||||
//literal, treat as non-regex, non-term component query
|
||||
@ -377,8 +382,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
// @@@ This method is a workaround until we decide whether we need all three presentation modes or FLAT is sufficient.
|
||||
public Node createFlatNodeForKey(KeyValueQuery thing) {
|
||||
return createNodeForKey(thing);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(KeyValueQuery thing) {
|
||||
final KeyValueQueryContent thingContent = (KeyValueQueryContent) thing;
|
||||
@ -389,7 +394,9 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
|
||||
Node kvNode = new KeyValueNode(thingContent, Children.LEAF, Lookups.singleton(content));
|
||||
//wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization
|
||||
HighlightedMatchesSource highlights = new HighlightedMatchesSource(content, queryStr, !thingContent.getQuery().isEscaped(), false, hits);
|
||||
HighlightedMatchesSource highlights = new HighlightedMatchesSource(content, queryStr,
|
||||
!thingContent.getQuery().isEscaped(),
|
||||
false, hits);
|
||||
return new KeywordSearchFilterNode(highlights, kvNode, queryStr, previewChunk);
|
||||
}
|
||||
}
|
||||
@ -448,22 +455,24 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
int resID = 0;
|
||||
|
||||
final KeywordSearchQuery origQuery = thing.getQuery();
|
||||
|
||||
|
||||
List<KeyValueQuery> tempList = new ArrayList<>();
|
||||
|
||||
|
||||
for (final AbstractFile f : uniqueMatches.keySet()) {
|
||||
final int previewChunkId = uniqueMatches.get(f);
|
||||
Map<String, Object> resMap = new LinkedHashMap<>();
|
||||
if (f.getType() == TSK_DB_FILES_TYPE_ENUM.FS) {
|
||||
AbstractFsContentNode.fillPropertyMap(resMap, (FsContent) f);
|
||||
}
|
||||
tempList.add(new KeyValueQueryContent(f.getName(), resMap, ++resID, f, keywordQuery, thing.getQuery(), previewChunkId, matchesRes));
|
||||
tempList.add(
|
||||
new KeyValueQueryContent(f.getName(), resMap, ++resID, f, keywordQuery, thing.getQuery(),
|
||||
previewChunkId, matchesRes));
|
||||
}
|
||||
|
||||
|
||||
// Add all the nodes to toPopulate at once. Minimizes node creation
|
||||
// EDT threads, which can slow and/or hang the UI on large queries.
|
||||
toPopulate.addAll(tempList);
|
||||
|
||||
|
||||
//write to bb
|
||||
new ResultWriter(matchesRes, origQuery, "").execute();
|
||||
|
||||
@ -480,7 +489,9 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
|
||||
Node kvNode = new KeyValueNode(thingContent, Children.LEAF, Lookups.singleton(content));
|
||||
//wrap in KeywordSearchFilterNode for the markup content
|
||||
HighlightedMatchesSource highlights = new HighlightedMatchesSource(content, query, !thingContent.getQuery().isEscaped(), hits);
|
||||
HighlightedMatchesSource highlights = new HighlightedMatchesSource(content, query,
|
||||
!thingContent.getQuery().isEscaped(),
|
||||
hits);
|
||||
return new KeywordSearchFilterNode(highlights, kvNode, query, previewChunk);
|
||||
}
|
||||
}
|
||||
@ -512,7 +523,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
return hits;
|
||||
}
|
||||
|
||||
public KeyValueQueryContent(String name, Map<String, Object> map, int id, Content content, String queryStr, KeywordSearchQuery query, int previewChunk, Map<String, List<ContentHit>> hits) {
|
||||
public KeyValueQueryContent(String name, Map<String, Object> map, int id, Content content, String queryStr,
|
||||
KeywordSearchQuery query, int previewChunk, Map<String, List<ContentHit>> hits) {
|
||||
super(name, map, id, query);
|
||||
this.content = content;
|
||||
this.queryStr = queryStr;
|
||||
@ -522,7 +534,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
}
|
||||
|
||||
/**
|
||||
* worker for writing results to bb, with progress bar, cancellation,
|
||||
* worker for writing results to bb, with progress bar, cancellation,
|
||||
* and central registry of workers to be stopped when case is closed
|
||||
*/
|
||||
static class ResultWriter extends SwingWorker<Object, Void> {
|
||||
@ -556,7 +568,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
});
|
||||
|
||||
if (!this.isCancelled() && !na.isEmpty()) {
|
||||
IngestServices.getDefault().fireModuleDataEvent(new ModuleDataEvent(KeywordSearchIngestModule.MODULE_NAME, ARTIFACT_TYPE.TSK_KEYWORD_HIT, na));
|
||||
IngestServices.getDefault().fireModuleDataEvent(
|
||||
new ModuleDataEvent(KeywordSearchIngestModule.MODULE_NAME, ARTIFACT_TYPE.TSK_KEYWORD_HIT, na));
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,7 +581,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
//writerLock.lock();
|
||||
try {
|
||||
final String queryStr = query.getQueryString();
|
||||
final String queryDisp = queryStr.length() > QUERY_DISPLAY_LEN ? queryStr.substring(0, QUERY_DISPLAY_LEN - 1) + " ..." : queryStr;
|
||||
final String queryDisp = queryStr.length() > QUERY_DISPLAY_LEN ?
|
||||
queryStr.substring(0, QUERY_DISPLAY_LEN - 1) + " ..." : queryStr;
|
||||
progress = ProgressHandleFactory.createHandle("Saving results: " + queryDisp, new Cancellable() {
|
||||
|
||||
@Override
|
||||
@ -590,7 +604,8 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQuery> {
|
||||
final String snippetQuery = KeywordSearchUtil.escapeLuceneQuery(hit);
|
||||
String snippet;
|
||||
try {
|
||||
snippet = LuceneQuery.querySnippet(snippetQuery, f.getId(), chunkId, !query.isLiteral(), true);
|
||||
snippet = LuceneQuery
|
||||
.querySnippet(snippetQuery, f.getId(), chunkId, !query.isLiteral(), true);
|
||||
} catch (NoOpenCoreException e) {
|
||||
logger.log(Level.WARNING, "Error querying snippet: " + snippetQuery, e);
|
||||
//no reason to continie
|
||||
|
@ -25,6 +25,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||
import org.sleuthkit.autopsy.coreutils.StringExtract;
|
||||
@ -35,105 +36,111 @@ import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.UpdateFrequ
|
||||
//This file contains constants and settings for KeywordSearch
|
||||
class KeywordSearchSettings {
|
||||
public static final String MODULE_NAME = "KeywordSearch";
|
||||
static final String PROPERTIES_OPTIONS = MODULE_NAME+"_Options";
|
||||
static final String PROPERTIES_NSRL = MODULE_NAME+"_NSRL";
|
||||
static final String PROPERTIES_SCRIPTS = MODULE_NAME+"_Scripts";
|
||||
static final String PROPERTIES_OPTIONS = MODULE_NAME + "_Options";
|
||||
static final String PROPERTIES_NSRL = MODULE_NAME + "_NSRL";
|
||||
static final String PROPERTIES_SCRIPTS = MODULE_NAME + "_Scripts";
|
||||
private static boolean skipKnown = true;
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchSettings.class.getName());
|
||||
private static UpdateFrequency UpdateFreq = UpdateFrequency.DEFAULT;
|
||||
private static List<StringExtract.StringExtractUnicodeTable.SCRIPT> stringExtractScripts = new ArrayList<StringExtract.StringExtractUnicodeTable.SCRIPT>();
|
||||
private static Map<String,String> stringExtractOptions = new HashMap<String,String>();
|
||||
|
||||
private static List<StringExtract.StringExtractUnicodeTable.SCRIPT> stringExtractScripts
|
||||
= new ArrayList<StringExtract.StringExtractUnicodeTable.SCRIPT>();
|
||||
private static Map<String, String> stringExtractOptions = new HashMap<String, String>();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the update Frequency from KeywordSearch_Options.properties
|
||||
*
|
||||
* @return KeywordSearchIngestModule's update frequency
|
||||
*/
|
||||
static UpdateFrequency getUpdateFrequency(){
|
||||
if(ModuleSettings.getConfigSetting(PROPERTIES_OPTIONS, "UpdateFrequency") != null){
|
||||
*/
|
||||
static UpdateFrequency getUpdateFrequency() {
|
||||
if (ModuleSettings.getConfigSetting(PROPERTIES_OPTIONS, "UpdateFrequency") != null) {
|
||||
return UpdateFrequency.valueOf(ModuleSettings.getConfigSetting(PROPERTIES_OPTIONS, "UpdateFrequency"));
|
||||
}
|
||||
//if it failed, return the default/last known value
|
||||
logger.log(Level.WARNING, "Could not read property for UpdateFrequency, returning backup value.");
|
||||
return UpdateFrequency.DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets the update frequency and writes to KeywordSearch_Options.properties
|
||||
*
|
||||
* @param freq Sets KeywordSearchIngestModule to this value.
|
||||
*/
|
||||
static void setUpdateFrequency(UpdateFrequency freq){
|
||||
static void setUpdateFrequency(UpdateFrequency freq) {
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_OPTIONS, "UpdateFrequency", freq.name());
|
||||
UpdateFreq = freq;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether or not to skip adding known good files to the search during index.
|
||||
* @param skip
|
||||
*
|
||||
* @param skip
|
||||
*/
|
||||
static void setSkipKnown(boolean skip) {
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_NSRL, "SkipKnown", Boolean.toString(skip));
|
||||
skipKnown = skip;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Gets the setting for whether or not this ingest is skipping adding known good files to the index.
|
||||
*
|
||||
* @return skip setting
|
||||
*/
|
||||
static boolean getSkipKnown() {
|
||||
if(ModuleSettings.getConfigSetting(PROPERTIES_NSRL, "SkipKnown") != null){
|
||||
if (ModuleSettings.getConfigSetting(PROPERTIES_NSRL, "SkipKnown") != null) {
|
||||
return Boolean.parseBoolean(ModuleSettings.getConfigSetting(PROPERTIES_NSRL, "SkipKnown"));
|
||||
}
|
||||
//if it fails, return the default/last known value
|
||||
logger.log(Level.WARNING, "Could not read property for SkipKnown, returning backup value.");
|
||||
return skipKnown;
|
||||
//if it fails, return the default/last known value
|
||||
logger.log(Level.WARNING, "Could not read property for SkipKnown, returning backup value.");
|
||||
return skipKnown;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets what scripts to extract during ingest
|
||||
*
|
||||
* @param scripts List of scripts to extract
|
||||
*/
|
||||
static void setStringExtractScripts(List<StringExtract.StringExtractUnicodeTable.SCRIPT> scripts) {
|
||||
stringExtractScripts.clear();
|
||||
stringExtractScripts.addAll(scripts);
|
||||
|
||||
|
||||
//Disabling scripts that weren't selected
|
||||
for(String s : ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS).keySet()){
|
||||
if (! scripts.contains(StringExtract.StringExtractUnicodeTable.SCRIPT.valueOf(s))){
|
||||
for (String s : ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS).keySet()) {
|
||||
if (!scripts.contains(StringExtract.StringExtractUnicodeTable.SCRIPT.valueOf(s))) {
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_SCRIPTS, s, "false");
|
||||
}
|
||||
}
|
||||
//Writing and enabling selected scripts
|
||||
for(StringExtract.StringExtractUnicodeTable.SCRIPT s : stringExtractScripts){
|
||||
for (StringExtract.StringExtractUnicodeTable.SCRIPT s : stringExtractScripts) {
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_SCRIPTS, s.name(), "true");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Set / override string extract option
|
||||
*
|
||||
* @param key option name to set
|
||||
* @param val option value to set
|
||||
*/
|
||||
static void setStringExtractOption(String key, String val) {
|
||||
static void setStringExtractOption(String key, String val) {
|
||||
stringExtractOptions.put(key, val);
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_OPTIONS, key, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* gets the currently set scripts to use
|
||||
*
|
||||
* @return the list of currently used script
|
||||
*/
|
||||
static List<SCRIPT> getStringExtractScripts(){
|
||||
if(ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS) != null && !ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS).isEmpty()){
|
||||
static List<SCRIPT> getStringExtractScripts() {
|
||||
if (ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS) != null && !ModuleSettings
|
||||
.getConfigSettings(PROPERTIES_SCRIPTS).isEmpty()) {
|
||||
List<SCRIPT> scripts = new ArrayList<SCRIPT>();
|
||||
for(Map.Entry<String,String> kvp : ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS).entrySet()){
|
||||
if(kvp.getValue().equals("true")){
|
||||
for (Map.Entry<String, String> kvp : ModuleSettings.getConfigSettings(PROPERTIES_SCRIPTS).entrySet()) {
|
||||
if (kvp.getValue().equals("true")) {
|
||||
scripts.add(SCRIPT.valueOf(kvp.getKey()));
|
||||
}
|
||||
}
|
||||
@ -143,72 +150,77 @@ class KeywordSearchSettings {
|
||||
logger.log(Level.WARNING, "Could not read properties for extracting scripts, returning backup values.");
|
||||
return new ArrayList<SCRIPT>(stringExtractScripts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get string extract option for the key
|
||||
*
|
||||
* @param key option name
|
||||
* @return option string value, or empty string if the option is not set
|
||||
*/
|
||||
static String getStringExtractOption(String key) {
|
||||
if (ModuleSettings.getConfigSetting(PROPERTIES_OPTIONS, key) != null){
|
||||
if (ModuleSettings.getConfigSetting(PROPERTIES_OPTIONS, key) != null) {
|
||||
return ModuleSettings.getConfigSetting(PROPERTIES_OPTIONS, key);
|
||||
}
|
||||
else {
|
||||
logger.log(Level.WARNING, "Could not read property for key "+ key + ", returning backup value.");
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Could not read property for key " + key + ", returning backup value.");
|
||||
return stringExtractOptions.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the map of string extract options.
|
||||
*
|
||||
* @return Map<String,String> of extract options.
|
||||
*/
|
||||
static Map<String,String> getStringExtractOptions(){
|
||||
Map<String,String> settings = ModuleSettings.getConfigSettings(PROPERTIES_OPTIONS);
|
||||
if(settings == null){
|
||||
Map<String,String> settingsv2 = new HashMap<String,String>();
|
||||
logger.log(Level.WARNING, "Could not read properties for " + PROPERTIES_OPTIONS + ".properties, returning backup values");
|
||||
static Map<String, String> getStringExtractOptions() {
|
||||
Map<String, String> settings = ModuleSettings.getConfigSettings(PROPERTIES_OPTIONS);
|
||||
if (settings == null) {
|
||||
Map<String, String> settingsv2 = new HashMap<String, String>();
|
||||
logger.log(Level.WARNING,
|
||||
"Could not read properties for " + PROPERTIES_OPTIONS + ".properties, returning backup values");
|
||||
settingsv2.putAll(stringExtractOptions);
|
||||
return settingsv2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default values of the KeywordSearch properties files if none already exist.
|
||||
*/
|
||||
static void setDefaults(){
|
||||
static void setDefaults() {
|
||||
logger.log(Level.INFO, "Detecting default settings.");
|
||||
//setting default NSRL
|
||||
if(!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_NSRL, "SkipKnown")){
|
||||
logger.log(Level.INFO, "No configuration for NSRL found, generating default...");
|
||||
KeywordSearchSettings.setSkipKnown(true);
|
||||
}
|
||||
//setting default Update Frequency
|
||||
if(!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_OPTIONS, "UpdateFrequency")){
|
||||
logger.log(Level.INFO, "No configuration for Update Frequency found, generating default...");
|
||||
KeywordSearchSettings.setUpdateFrequency(UpdateFrequency.DEFAULT);
|
||||
}
|
||||
//setting default Extract UTF8
|
||||
if(!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_OPTIONS, AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString())){
|
||||
logger.log(Level.INFO, "No configuration for UTF8 found, generating default...");
|
||||
KeywordSearchSettings.setStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString(), Boolean.TRUE.toString());
|
||||
}
|
||||
//setting default NSRL
|
||||
if (!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_NSRL, "SkipKnown")) {
|
||||
logger.log(Level.INFO, "No configuration for NSRL found, generating default...");
|
||||
KeywordSearchSettings.setSkipKnown(true);
|
||||
}
|
||||
//setting default Update Frequency
|
||||
if (!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_OPTIONS, "UpdateFrequency")) {
|
||||
logger.log(Level.INFO, "No configuration for Update Frequency found, generating default...");
|
||||
KeywordSearchSettings.setUpdateFrequency(UpdateFrequency.DEFAULT);
|
||||
}
|
||||
//setting default Extract UTF8
|
||||
if (!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_OPTIONS,
|
||||
AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString())) {
|
||||
logger.log(Level.INFO, "No configuration for UTF8 found, generating default...");
|
||||
KeywordSearchSettings.setStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF8.toString(),
|
||||
Boolean.TRUE.toString());
|
||||
}
|
||||
//setting default Extract UTF16
|
||||
if(!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_OPTIONS, AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString())){
|
||||
logger.log(Level.INFO, "No configuration for UTF16 found, generating defaults...");
|
||||
KeywordSearchSettings.setStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString(), Boolean.TRUE.toString());
|
||||
}
|
||||
if (!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_OPTIONS,
|
||||
AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString())) {
|
||||
logger.log(Level.INFO, "No configuration for UTF16 found, generating defaults...");
|
||||
KeywordSearchSettings.setStringExtractOption(AbstractFileExtract.ExtractOptions.EXTRACT_UTF16.toString(),
|
||||
Boolean.TRUE.toString());
|
||||
}
|
||||
//setting default Latin-1 Script
|
||||
if(!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_SCRIPTS, SCRIPT.LATIN_1.name())){
|
||||
logger.log(Level.INFO, "No configuration for Scripts found, generating defaults...");
|
||||
ModuleSettings.setConfigSetting(KeywordSearchSettings.PROPERTIES_SCRIPTS, SCRIPT.LATIN_1.name(), Boolean.toString(true));
|
||||
if (!ModuleSettings.settingExists(KeywordSearchSettings.PROPERTIES_SCRIPTS, SCRIPT.LATIN_1.name())) {
|
||||
logger.log(Level.INFO, "No configuration for Scripts found, generating defaults...");
|
||||
ModuleSettings.setConfigSetting(KeywordSearchSettings.PROPERTIES_SCRIPTS, SCRIPT.LATIN_1.name(),
|
||||
Boolean.toString(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,8 +21,11 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.awt.Component;
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
@ -32,9 +35,10 @@ class KeywordSearchUtil {
|
||||
public enum DIALOG_MESSAGE_TYPE {
|
||||
|
||||
ERROR, WARN, INFO
|
||||
};
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchUtil.class.getName());
|
||||
}
|
||||
|
||||
;
|
||||
private static final Logger logger = Logger.getLogger(KeywordSearchUtil.class.getName());
|
||||
|
||||
|
||||
/**
|
||||
@ -117,7 +121,8 @@ class KeywordSearchUtil {
|
||||
messageType);
|
||||
}
|
||||
|
||||
public static boolean displayConfirmDialog(final String title, final String message, final DIALOG_MESSAGE_TYPE type) {
|
||||
public static boolean displayConfirmDialog(final String title, final String message,
|
||||
final DIALOG_MESSAGE_TYPE type) {
|
||||
int messageType;
|
||||
if (type == DIALOG_MESSAGE_TYPE.ERROR) {
|
||||
messageType = JOptionPane.ERROR_MESSAGE;
|
||||
@ -126,7 +131,8 @@ class KeywordSearchUtil {
|
||||
} else {
|
||||
messageType = JOptionPane.INFORMATION_MESSAGE;
|
||||
}
|
||||
if (JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION, messageType) == JOptionPane.YES_OPTION) {
|
||||
if (JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION, messageType)
|
||||
== JOptionPane.YES_OPTION) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
This file describes the schema definition for its twin files, which are loaded at runtime as notable keyword files.
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
|
||||
<!-- definition of simple elements -->
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="literal" type="xs:boolean"/>
|
||||
@ -11,7 +11,7 @@ This file describes the schema definition for its twin files, which are loaded a
|
||||
<xs:attribute name="use_for_ingest" type="xs:boolean"/>
|
||||
<xs:attribute name="key" type="xs:string"/>
|
||||
|
||||
<xs:attribute name="created" >
|
||||
<xs:attribute name="created">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:whiteSpace value="preserve"/>
|
||||
@ -42,11 +42,11 @@ This file describes the schema definition for its twin files, which are loaded a
|
||||
<xs:sequence>
|
||||
<xs:element ref="keyword" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute ref="created" use="required"/>
|
||||
<xs:attribute ref="ingest_messages" default="true" use="optional"/>
|
||||
<xs:attribute ref="modified" use="optional"/>
|
||||
<xs:attribute ref="name" use="required"/>
|
||||
<xs:attribute ref="use_for_ingest" default="true" use="optional"/>
|
||||
<xs:attribute ref="created" use="required"/>
|
||||
<xs:attribute ref="ingest_messages" default="true" use="optional"/>
|
||||
<xs:attribute ref="modified" use="optional"/>
|
||||
<xs:attribute ref="name" use="required"/>
|
||||
<xs:attribute ref="use_for_ingest" default="true" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrRequest.METHOD;
|
||||
@ -44,7 +45,7 @@ import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
* Performs a normal string (i.e. non-regexp) query to SOLR/Lucene.
|
||||
* By default, matches in all fields.
|
||||
* By default, matches in all fields.
|
||||
*/
|
||||
class LuceneQuery implements KeywordSearchQuery {
|
||||
|
||||
@ -53,7 +54,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
private String keywordStringEscaped;
|
||||
private boolean isEscaped;
|
||||
private Keyword keywordQuery = null;
|
||||
private final List <KeywordQueryFilter> filters = new ArrayList<KeywordQueryFilter>();
|
||||
private final List<KeywordQueryFilter> filters = new ArrayList<KeywordQueryFilter>();
|
||||
private String field = null;
|
||||
private static final int MAX_RESULTS = 20000;
|
||||
static final int SNIPPET_LENGTH = 50;
|
||||
@ -62,12 +63,13 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
static final String HIGHLIGHT_FIELD_REGEX = Server.Schema.CONTENT.toString();
|
||||
//TODO use content_ws stored="true" in solr schema for perfect highlight hits
|
||||
//static final String HIGHLIGHT_FIELD_REGEX = Server.Schema.CONTENT_WS.toString()
|
||||
|
||||
|
||||
private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT);
|
||||
|
||||
/**
|
||||
* Constructor with query to process.
|
||||
* @param keywordQuery
|
||||
*
|
||||
* @param keywordQuery
|
||||
*/
|
||||
public LuceneQuery(Keyword keywordQuery) {
|
||||
this(keywordQuery.getQuery());
|
||||
@ -76,6 +78,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
|
||||
/**
|
||||
* Constructor with keyword string to process
|
||||
*
|
||||
* @param queryStr Keyword to search for
|
||||
*/
|
||||
public LuceneQuery(String queryStr) {
|
||||
@ -88,7 +91,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
public void addFilter(KeywordQueryFilter filter) {
|
||||
this.filters.add(filter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setField(String field) {
|
||||
this.field = field;
|
||||
@ -141,7 +144,8 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeywordWriteResult writeToBlackBoard(String termHit, AbstractFile newFsHit, String snippet, String listName) {
|
||||
public KeywordWriteResult writeToBlackBoard(String termHit, AbstractFile newFsHit, String snippet,
|
||||
String listName) {
|
||||
final String MODULE_NAME = KeywordSearchIngestModule.MODULE_NAME;
|
||||
|
||||
KeywordWriteResult writeResult = null;
|
||||
@ -156,7 +160,8 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
if (snippet != null) {
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID(), MODULE_NAME, snippet));
|
||||
attributes
|
||||
.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID(), MODULE_NAME, snippet));
|
||||
}
|
||||
//keyword
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID(), MODULE_NAME, termHit));
|
||||
@ -186,9 +191,10 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Perform the query and return result
|
||||
*
|
||||
* @return list of ContentHit objects
|
||||
* @throws NoOpenCoreException
|
||||
*/
|
||||
@ -212,7 +218,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
sb.append(field).append(":").append(groupedQuery);
|
||||
theQueryStr = sb.toString();
|
||||
}
|
||||
|
||||
|
||||
q.setQuery(theQueryStr);
|
||||
q.setRows(MAX_RESULTS);
|
||||
q.setFields(Server.Schema.ID.toString());
|
||||
@ -286,26 +292,30 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
|
||||
/**
|
||||
* return snippet preview context
|
||||
* @param query the keyword query for text to highlight. Lucene special cahrs should already be escaped.
|
||||
*
|
||||
* @param query the keyword query for text to highlight. Lucene special cahrs should already be escaped.
|
||||
* @param contentID content id associated with the file
|
||||
* @param isRegex whether the query is a regular expression (different Solr fields are then used to generate the preview)
|
||||
* @param group whether the query should look for all terms grouped together in the query order, or not
|
||||
* @return
|
||||
* @param isRegex whether the query is a regular expression (different Solr fields are then used to generate the preview)
|
||||
* @param group whether the query should look for all terms grouped together in the query order, or not
|
||||
* @return
|
||||
*/
|
||||
public static String querySnippet(String query, long contentID, boolean isRegex, boolean group) throws NoOpenCoreException {
|
||||
public static String querySnippet(String query, long contentID, boolean isRegex, boolean group)
|
||||
throws NoOpenCoreException {
|
||||
return querySnippet(query, contentID, 0, isRegex, group);
|
||||
}
|
||||
|
||||
/**
|
||||
* return snippet preview context
|
||||
* @param query the keyword query for text to highlight. Lucene special cahrs should already be escaped.
|
||||
*
|
||||
* @param query the keyword query for text to highlight. Lucene special cahrs should already be escaped.
|
||||
* @param contentID content id associated with the hit
|
||||
* @param chunkID chunk id associated with the content hit, or 0 if no chunks
|
||||
* @param isRegex whether the query is a regular expression (different Solr fields are then used to generate the preview)
|
||||
* @param group whether the query should look for all terms grouped together in the query order, or not
|
||||
* @return
|
||||
* @param chunkID chunk id associated with the content hit, or 0 if no chunks
|
||||
* @param isRegex whether the query is a regular expression (different Solr fields are then used to generate the preview)
|
||||
* @param group whether the query should look for all terms grouped together in the query order, or not
|
||||
* @return
|
||||
*/
|
||||
public static String querySnippet(String query, long contentID, int chunkID, boolean isRegex, boolean group) throws NoOpenCoreException {
|
||||
public static String querySnippet(String query, long contentID, int chunkID, boolean isRegex, boolean group)
|
||||
throws NoOpenCoreException {
|
||||
Server solrServer = KeywordSearch.getServer();
|
||||
|
||||
String highlightField = null;
|
||||
@ -318,7 +328,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
SolrQuery q = new SolrQuery();
|
||||
|
||||
String queryStr = null;
|
||||
|
||||
|
||||
if (isRegex) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(highlightField).append(":");
|
||||
@ -336,7 +346,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
//always force grouping/quotes
|
||||
queryStr = KeywordSearchUtil.quoteQuery(query);
|
||||
}
|
||||
|
||||
|
||||
q.setQuery(queryStr);
|
||||
|
||||
String contentIDStr = null;
|
||||
@ -355,21 +365,20 @@ class LuceneQuery implements KeywordSearchQuery {
|
||||
//q.setHighlightSimplePost("»"); //original highlighter only
|
||||
q.setHighlightSnippets(1);
|
||||
q.setHighlightFragsize(SNIPPET_LENGTH);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//tune the highlighter
|
||||
q.setParam("hl.useFastVectorHighlighter", "on"); //fast highlighter scales better than standard one
|
||||
q.setParam("hl.tag.pre", "«"); //makes sense for FastVectorHighlighter only
|
||||
q.setParam("hl.tag.post", "«"); //makes sense for FastVectorHighlighter only
|
||||
q.setParam("hl.fragListBuilder", "simple"); //makes sense for FastVectorHighlighter only
|
||||
|
||||
//Solr bug if fragCharSize is smaller than Query string, StringIndexOutOfBoundsException is thrown.
|
||||
|
||||
//Solr bug if fragCharSize is smaller than Query string, StringIndexOutOfBoundsException is thrown.
|
||||
q.setParam("hl.fragCharSize", Integer.toString(queryStr.length())); //makes sense for FastVectorHighlighter only
|
||||
|
||||
|
||||
//docs says makes sense for the original Highlighter only, but not really
|
||||
//analyze all content SLOW! consider lowering
|
||||
q.setParam("hl.maxAnalyzedChars", Server.HL_ANALYZE_CHARS_UNLIMITED);
|
||||
q.setParam("hl.maxAnalyzedChars", Server.HL_ANALYZE_CHARS_UNLIMITED);
|
||||
|
||||
try {
|
||||
QueryResponse response = solrServer.query(q, METHOD.POST);
|
||||
|
@ -22,34 +22,34 @@ import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* Interface to provide HTML text to display in ExtractedContentViewer.
|
||||
* There is a SOLR implementaiton of this that interfaces with SOLR to
|
||||
* There is a SOLR implementaiton of this that interfaces with SOLR to
|
||||
* highlight the keyword hits and a version that does not do markup
|
||||
* so that you can simply view the stored text.
|
||||
* so that you can simply view the stored text.
|
||||
*/
|
||||
interface MarkupSource {
|
||||
|
||||
/**
|
||||
* @return text optionally marked up with the subsest of HTML that Swing
|
||||
* components can handle in their setText() method.
|
||||
*
|
||||
*/
|
||||
String getMarkup();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if markup is marked to be searchable
|
||||
*/
|
||||
boolean isSearchable();
|
||||
|
||||
|
||||
/**
|
||||
* If searchable markup, returns prefix of anchor, otherwise return empty string
|
||||
* @return
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getAnchorPrefix();
|
||||
|
||||
|
||||
/**
|
||||
* if searchable markup, returns number of hits found and encoded in the markup
|
||||
* @return
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getNumberHits();
|
||||
|
||||
@ -58,80 +58,92 @@ interface MarkupSource {
|
||||
*/
|
||||
@Override
|
||||
String toString();
|
||||
|
||||
|
||||
/**
|
||||
* get number pages/chunks
|
||||
*
|
||||
* @return number pages
|
||||
*/
|
||||
int getNumberPages();
|
||||
|
||||
|
||||
/**
|
||||
* get the current page number
|
||||
*
|
||||
* @return current page number
|
||||
*/
|
||||
int getCurrentPage();
|
||||
|
||||
|
||||
/**
|
||||
* Check if has next page
|
||||
*
|
||||
* @return true, if next page exists in the source
|
||||
*/
|
||||
boolean hasNextPage();
|
||||
|
||||
|
||||
/**
|
||||
* Move to next page
|
||||
*
|
||||
* @return the new page number
|
||||
*/
|
||||
int nextPage();
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Check if has previous page
|
||||
*
|
||||
* @return true, if previous page exists in the source
|
||||
*/
|
||||
boolean hasPreviousPage();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Move to previous page
|
||||
*
|
||||
* @return the new page number
|
||||
*/
|
||||
int previousPage();
|
||||
|
||||
|
||||
/**
|
||||
* Check if has next searchable item
|
||||
*
|
||||
* @return true, if next item exists in the source
|
||||
*/
|
||||
boolean hasNextItem();
|
||||
|
||||
|
||||
/**
|
||||
* Move to next item
|
||||
*
|
||||
* @return the new item number
|
||||
*/
|
||||
int nextItem();
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Check if has previous item
|
||||
*
|
||||
* @return true, if previous item exists in the source
|
||||
*/
|
||||
boolean hasPreviousItem();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Move to previous item
|
||||
*
|
||||
* @return the new item number
|
||||
*/
|
||||
int previousItem();
|
||||
|
||||
|
||||
/**
|
||||
* Get the current item number, do not change anything
|
||||
*
|
||||
* @return the current item number
|
||||
*/
|
||||
int currentItem();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get a map storing which pages have matches to their number, or 0 if unknown
|
||||
*
|
||||
* @return map storing pages with matches, or null if not supported
|
||||
*/
|
||||
LinkedHashMap<Integer,Integer> getHitsPages();
|
||||
|
||||
LinkedHashMap<Integer, Integer> getHitsPages();
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
/**
|
||||
*
|
||||
* Exception thrown when no core is open
|
||||
*/
|
||||
class NoOpenCoreException extends Exception {
|
||||
@ -28,5 +27,5 @@ class NoOpenCoreException extends Exception {
|
||||
super("No currently open Solr core.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -41,8 +41,11 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
@ -133,8 +136,11 @@ class Server {
|
||||
return "num_chunks";
|
||||
}
|
||||
},
|
||||
};
|
||||
public static final String HL_ANALYZE_CHARS_UNLIMITED = "500000"; //max 1MB in a chunk. use -1 for unlimited, but -1 option may not be supported (not documented)
|
||||
}
|
||||
|
||||
;
|
||||
public static final String HL_ANALYZE_CHARS_UNLIMITED = "500000";
|
||||
//max 1MB in a chunk. use -1 for unlimited, but -1 option may not be supported (not documented)
|
||||
//max content size we can send to Solr
|
||||
public static final long MAX_CONTENT_SIZE = 1L * 1024 * 1024 * 1024;
|
||||
private static final Logger logger = Logger.getLogger(Server.class.getName());
|
||||
@ -143,7 +149,8 @@ class Server {
|
||||
public static final String CORE_EVT = "CORE_EVT";
|
||||
public static final char ID_CHUNK_SEP = '_';
|
||||
private String javaPath = "java";
|
||||
public static final Charset DEFAULT_INDEXED_TEXT_CHARSET = Charset.forName("UTF-8"); ///< default Charset to index text as
|
||||
public static final Charset DEFAULT_INDEXED_TEXT_CHARSET = Charset.forName("UTF-8");
|
||||
///< default Charset to index text as
|
||||
private static final int MAX_SOLR_MEM_MB = 512; //TODO set dynamically based on avail. system resources
|
||||
private Process curSolrProcess = null;
|
||||
private static Ingester ingester = null;
|
||||
@ -160,7 +167,9 @@ class Server {
|
||||
public enum CORE_EVT_STATES {
|
||||
|
||||
STOPPED, STARTED
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
private SolrServer solrServer;
|
||||
private String instanceDir;
|
||||
private File solrFolder;
|
||||
@ -189,26 +198,34 @@ class Server {
|
||||
private void initSettings() {
|
||||
if (ModuleSettings.settingExists(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT)) {
|
||||
try {
|
||||
currentSolrServerPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT));
|
||||
currentSolrServerPort = Integer
|
||||
.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT));
|
||||
} catch (NumberFormatException nfe) {
|
||||
logger.log(Level.WARNING, "Could not decode indexing server port, value was not a valid port number, using the default. ", nfe);
|
||||
logger.log(Level.WARNING,
|
||||
"Could not decode indexing server port, value was not a valid port number, using the default. ",
|
||||
nfe);
|
||||
currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
|
||||
}
|
||||
} else {
|
||||
currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT, String.valueOf(currentSolrServerPort));
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT,
|
||||
String.valueOf(currentSolrServerPort));
|
||||
}
|
||||
|
||||
if (ModuleSettings.settingExists(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT)) {
|
||||
try {
|
||||
currentSolrStopPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT));
|
||||
currentSolrStopPort = Integer
|
||||
.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT));
|
||||
} catch (NumberFormatException nfe) {
|
||||
logger.log(Level.WARNING, "Could not decode indexing server stop port, value was not a valid port number, using default", nfe);
|
||||
logger.log(Level.WARNING,
|
||||
"Could not decode indexing server stop port, value was not a valid port number, using default",
|
||||
nfe);
|
||||
currentSolrStopPort = DEFAULT_SOLR_STOP_PORT;
|
||||
}
|
||||
} else {
|
||||
currentSolrStopPort = DEFAULT_SOLR_STOP_PORT;
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT, String.valueOf(currentSolrStopPort));
|
||||
ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT,
|
||||
String.valueOf(currentSolrStopPort));
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,7 +316,7 @@ class Server {
|
||||
logger.log(Level.WARNING, "Error closing Solr output stream writer");
|
||||
}
|
||||
}
|
||||
if (br != null) {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
@ -366,21 +383,21 @@ class Server {
|
||||
|
||||
final String loggingProperties = loggingPropertiesOpt + loggingPropertiesFilePath;
|
||||
|
||||
final String [] SOLR_START_CMD = {
|
||||
javaPath,
|
||||
MAX_SOLR_MEM_MB_PAR,
|
||||
"-DSTOP.PORT=" + currentSolrStopPort,
|
||||
"-Djetty.port=" + currentSolrServerPort,
|
||||
"-DSTOP.KEY=" + KEY,
|
||||
loggingProperties,
|
||||
"-jar",
|
||||
"start.jar"};
|
||||
|
||||
final String[] SOLR_START_CMD = {
|
||||
javaPath,
|
||||
MAX_SOLR_MEM_MB_PAR,
|
||||
"-DSTOP.PORT=" + currentSolrStopPort,
|
||||
"-Djetty.port=" + currentSolrServerPort,
|
||||
"-DSTOP.KEY=" + KEY,
|
||||
loggingProperties,
|
||||
"-jar",
|
||||
"start.jar"};
|
||||
|
||||
StringBuilder cmdSb = new StringBuilder();
|
||||
for (int i = 0; i<SOLR_START_CMD.length; ++i ) {
|
||||
for (int i = 0; i < SOLR_START_CMD.length; ++i) {
|
||||
cmdSb.append(SOLR_START_CMD[i]).append(" ");
|
||||
}
|
||||
|
||||
|
||||
logger.log(Level.INFO, "Starting Solr using: " + cmdSb.toString());
|
||||
curSolrProcess = Runtime.getRuntime().exec(SOLR_START_CMD, null, solrFolder);
|
||||
logger.log(Level.INFO, "Finished starting Solr");
|
||||
@ -409,7 +426,8 @@ class Server {
|
||||
throw new KeywordSearchModuleException("Could not start Solr server process", ex);
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Could not start Solr server process, port [" + currentSolrServerPort + "] not available!");
|
||||
logger.log(Level.WARNING,
|
||||
"Could not start Solr server process, port [" + currentSolrServerPort + "] not available!");
|
||||
throw new SolrServerNoPortException(currentSolrServerPort);
|
||||
}
|
||||
}
|
||||
@ -465,20 +483,20 @@ class Server {
|
||||
|
||||
/**
|
||||
* Tries to stop a Solr instance.
|
||||
*
|
||||
* <p/>
|
||||
* Waits for the stop command to finish before returning.
|
||||
*/
|
||||
synchronized void stop() {
|
||||
try {
|
||||
logger.log(Level.INFO, "Stopping Solr server from: " + solrFolder.getAbsolutePath());
|
||||
//try graceful shutdown
|
||||
final String [] SOLR_STOP_CMD = {
|
||||
javaPath,
|
||||
"-DSTOP.PORT=" + currentSolrStopPort,
|
||||
"-DSTOP.KEY=" + KEY,
|
||||
"-jar",
|
||||
"start.jar",
|
||||
"--stop",
|
||||
final String[] SOLR_STOP_CMD = {
|
||||
javaPath,
|
||||
"-DSTOP.PORT=" + currentSolrStopPort,
|
||||
"-DSTOP.KEY=" + KEY,
|
||||
"-jar",
|
||||
"start.jar",
|
||||
"--stop",
|
||||
};
|
||||
Process stop = Runtime.getRuntime().exec(SOLR_STOP_CMD, null, solrFolder);
|
||||
logger.log(Level.INFO, "Waiting for stopping Solr server");
|
||||
@ -532,7 +550,8 @@ class Server {
|
||||
// TODO: check if SocketExceptions should actually happen (is
|
||||
// probably caused by starting a connection as the server finishes
|
||||
// shutting down)
|
||||
if (cause instanceof ConnectException || cause instanceof SocketException) { //|| cause instanceof NoHttpResponseException) {
|
||||
if (cause instanceof ConnectException
|
||||
|| cause instanceof SocketException) { //|| cause instanceof NoHttpResponseException) {
|
||||
logger.log(Level.INFO, "Solr server is not running, cause: " + cause.getMessage());
|
||||
return false;
|
||||
} else {
|
||||
@ -544,6 +563,7 @@ class Server {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ** Convenience methods for use while we only open one case at a time ***
|
||||
*/
|
||||
@ -769,13 +789,14 @@ class Server {
|
||||
/**
|
||||
* Execute solr query
|
||||
*
|
||||
* @param sq the query
|
||||
* @param sq the query
|
||||
* @param method http method to use
|
||||
* @return query response
|
||||
* @throws KeywordSearchModuleException
|
||||
* @throws NoOpenCoreException
|
||||
*/
|
||||
public QueryResponse query(SolrQuery sq, SolrRequest.METHOD method) throws KeywordSearchModuleException, NoOpenCoreException {
|
||||
public QueryResponse query(SolrQuery sq, SolrRequest.METHOD method)
|
||||
throws KeywordSearchModuleException, NoOpenCoreException {
|
||||
if (currentCore == null) {
|
||||
throw new NoOpenCoreException();
|
||||
}
|
||||
@ -824,7 +845,7 @@ class Server {
|
||||
*
|
||||
* @param content to get the text for
|
||||
* @param chunkID chunk number to query (starting at 1), or 0 if there is no
|
||||
* chunks for that content
|
||||
* chunks for that content
|
||||
* @return content text string or null if error quering
|
||||
* @throws NoOpenCoreException
|
||||
*/
|
||||
@ -849,7 +870,7 @@ class Server {
|
||||
* chunk as stored in Solr, e.g. FILEID_CHUNKID
|
||||
*
|
||||
* @param parentID the parent file id (id of the source content)
|
||||
* @param childID the child chunk id
|
||||
* @param childID the child chunk id
|
||||
* @return formatted string id
|
||||
*/
|
||||
public static String getChunkIdString(long parentID, int childID) {
|
||||
@ -860,7 +881,7 @@ class Server {
|
||||
* Open a new core
|
||||
*
|
||||
* @param coreName name to refer to the core by in Solr
|
||||
* @param dataDir directory to load/store the core data from/to
|
||||
* @param dataDir directory to load/store the core data from/to
|
||||
* @return new core
|
||||
*/
|
||||
private Core openCore(String coreName, File dataDir) throws KeywordSearchModuleException {
|
||||
@ -958,19 +979,24 @@ class Server {
|
||||
try {
|
||||
solrCore.add(doc);
|
||||
} catch (SolrServerException ex) {
|
||||
logger.log(Level.SEVERE, "Could not add document to index via update handler: " + doc.getField("id"), ex);
|
||||
throw new KeywordSearchModuleException("Could not add document to index via update handler: " + doc.getField("id"), ex);
|
||||
logger.log(Level.SEVERE, "Could not add document to index via update handler: " + doc.getField("id"),
|
||||
ex);
|
||||
throw new KeywordSearchModuleException(
|
||||
"Could not add document to index via update handler: " + doc.getField("id"), ex);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Could not add document to index via update handler: " + doc.getField("id"), ex);
|
||||
throw new KeywordSearchModuleException("Could not add document to index via update handler: " + doc.getField("id"), ex);
|
||||
logger.log(Level.SEVERE, "Could not add document to index via update handler: " + doc.getField("id"),
|
||||
ex);
|
||||
throw new KeywordSearchModuleException(
|
||||
"Could not add document to index via update handler: " + doc.getField("id"), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the text from the content field for the given file
|
||||
*
|
||||
* @param contentID
|
||||
* @param chunkID
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
private String getSolrContent(long contentID, int chunkID) {
|
||||
final SolrQuery q = new SolrQuery();
|
||||
@ -1059,7 +1085,7 @@ class Server {
|
||||
* Execute query that gets number of indexed file chunks for a file
|
||||
*
|
||||
* @param contentID file id of the original file broken into chunks and
|
||||
* indexed
|
||||
* indexed
|
||||
* @return int representing number of indexed file chunks, 0 if there is
|
||||
* no chunks
|
||||
* @throws SolrServerException
|
||||
@ -1092,8 +1118,8 @@ class Server {
|
||||
|
||||
SolrServerNoPortException(int port) {
|
||||
super("Indexing server could not bind to port " + port
|
||||
+ ", port is not available, consider change the default "
|
||||
+ Server.PROPERTIES_CURRENT_SERVER_PORT + " port.");
|
||||
+ ", port is not available, consider change the default "
|
||||
+ Server.PROPERTIES_CURRENT_SERVER_PORT + " port.");
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.response.TermsResponse;
|
||||
@ -43,7 +46,7 @@ import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
|
||||
/**
|
||||
* Performs a regular expression query to the SOLR/Lucene instance.
|
||||
* Performs a regular expression query to the SOLR/Lucene instance.
|
||||
*/
|
||||
class TermComponentQuery implements KeywordSearchQuery {
|
||||
|
||||
@ -61,7 +64,7 @@ class TermComponentQuery implements KeywordSearchQuery {
|
||||
private final List<KeywordQueryFilter> filters = new ArrayList<KeywordQueryFilter>();
|
||||
private String field = null;
|
||||
private static int MAX_TERMS_RESULTS = 20000;
|
||||
|
||||
|
||||
private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT);
|
||||
|
||||
public TermComponentQuery(Keyword keywordQuery) {
|
||||
@ -167,7 +170,8 @@ class TermComponentQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeywordWriteResult writeToBlackBoard(String termHit, AbstractFile newFsHit, String snippet, String listName) {
|
||||
public KeywordWriteResult writeToBlackBoard(String termHit, AbstractFile newFsHit, String snippet,
|
||||
String listName) {
|
||||
final String MODULE_NAME = KeywordSearchIngestModule.MODULE_NAME;
|
||||
|
||||
//there is match actually in this file, create artifact only then
|
||||
@ -193,7 +197,8 @@ class TermComponentQuery implements KeywordSearchQuery {
|
||||
|
||||
//preview
|
||||
if (snippet != null) {
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID(), MODULE_NAME, snippet));
|
||||
attributes
|
||||
.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID(), MODULE_NAME, snippet));
|
||||
}
|
||||
//regex keyword
|
||||
attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID(), MODULE_NAME, termsQuery));
|
||||
@ -226,12 +231,12 @@ class TermComponentQuery implements KeywordSearchQuery {
|
||||
|
||||
final SolrQuery q = createQuery();
|
||||
q.setShowDebugInfo(DEBUG);
|
||||
q.setTermsLimit(MAX_TERMS_RESULTS);
|
||||
q.setTermsLimit(MAX_TERMS_RESULTS);
|
||||
logger.log(Level.INFO, "Query: " + q.toString());
|
||||
terms = executeQuery(q);
|
||||
|
||||
int resultSize = 0;
|
||||
|
||||
|
||||
for (Term term : terms) {
|
||||
final String termStr = KeywordSearchUtil.escapeLuceneQuery(term.getTerm());
|
||||
|
||||
@ -260,7 +265,7 @@ class TermComponentQuery implements KeywordSearchQuery {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//TODO limit how many results we store, not to hit memory limits
|
||||
logger.log(Level.INFO, "Regex # results: " + resultSize);
|
||||
|
||||
|
@ -21,8 +21,8 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
interface TextLanguageIdentifier {
|
||||
|
||||
@ -31,7 +31,7 @@ interface TextLanguageIdentifier {
|
||||
* black board for the given {@code AbstractFile} as a TSK_TEXT_LANGUAGE
|
||||
* attribute on a TSK_GEN_INFO artifact.
|
||||
*
|
||||
* @param extracted the String whose language is to be identified
|
||||
* @param extracted the String whose language is to be identified
|
||||
* @param sourceFile the AbstractFile the string is extracted from.
|
||||
* @return
|
||||
*/
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@ -53,9 +54,11 @@ class TikaLanguageIdentifier implements TextLanguageIdentifier {
|
||||
genInfo.addAttribute(textLang);
|
||||
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "failed to add TSK_TEXT_LANGUAGE attribute to TSK_GEN_INFO artifact for file: " + sourceFile.getName(), ex);
|
||||
logger.log(Level.WARNING,
|
||||
"failed to add TSK_TEXT_LANGUAGE attribute to TSK_GEN_INFO artifact for file: " + sourceFile
|
||||
.getName(), ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@HelpSetRegistration(helpSet = "keywordsearch-hs.xml", position = 3521)
|
||||
package org.sleuthkit.autopsy.keywordsearch.docs;
|
||||
@HelpSetRegistration(helpSet = "keywordsearch-hs.xml",
|
||||
position = 3521) package org.sleuthkit.autopsy.keywordsearch.docs;
|
||||
|
||||
import org.netbeans.api.javahelp.HelpSetRegistration;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
|
||||
<filesystem>
|
||||
|
||||
|
||||
<!-- ======================================================
|
||||
Actions
|
||||
====================================================== -->
|
||||
@ -10,22 +10,24 @@
|
||||
<file name="org-sleuthkit-autopsy-keywordsearch-KeywordSearchConfigurationAction.instance"/>
|
||||
<file name="org-sleuthkit-autopsy-keywordsearch-KeywordSearchAction.instance">
|
||||
<attr name="delegate" newvalue="org.sleuthkit.autopsy.keywordsearch.KeywordSearchAction"/>
|
||||
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.keywordsearch.Bundle#CTL_KeywordSearchAction"/>
|
||||
<attr name="displayName"
|
||||
bundlevalue="org.sleuthkit.autopsy.keywordsearch.Bundle#CTL_KeywordSearchAction"/>
|
||||
</file>
|
||||
</folder>
|
||||
</folder>
|
||||
</folder>
|
||||
|
||||
|
||||
<!-- ======================================================
|
||||
Services
|
||||
======================================================= -->
|
||||
<folder name="Services">
|
||||
<file name="org-sleuthkit-autopsy-keywordsearch-HighlightedMatchesSource.instance">
|
||||
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.datamodel.HighlightLookup"/>
|
||||
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.keywordsearch.HighlightedMatchesSource.getDefault"/>
|
||||
<attr name="instanceCreate"
|
||||
methodvalue="org.sleuthkit.autopsy.keywordsearch.HighlightedMatchesSource.getDefault"/>
|
||||
<attr name="position" intvalue="250"/>
|
||||
</file>
|
||||
</folder>
|
||||
|
||||
|
||||
<!-- ======================================================
|
||||
Toolbars
|
||||
====================================================== -->
|
||||
@ -33,9 +35,10 @@
|
||||
<folder name="Keyword">
|
||||
<attr name="position" intvalue="104"/>
|
||||
<file name="org-sleuthkit-autopsy-keywordsearch-KeywordSearchAction.shadow">
|
||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-keywordsearch-KeywordSearchAction.instance"/>
|
||||
<attr name="originalFile"
|
||||
stringvalue="Actions/Tools/org-sleuthkit-autopsy-keywordsearch-KeywordSearchAction.instance"/>
|
||||
</file>
|
||||
</folder>
|
||||
</folder>
|
||||
|
||||
|
||||
</filesystem>
|
||||
|
Loading…
x
Reference in New Issue
Block a user