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