From 55dd19b39c24a8736b8ba962f8dbcadd8c46a23c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sun, 20 Aug 2017 18:30:07 -0400 Subject: [PATCH] WIP --- .../autopsy/keywordsearch/KeywordHit.java | 30 +++++++++++-------- .../KeywordSearchResultFactory.java | 18 ++++++----- .../autopsy/keywordsearch/LuceneQuery.java | 8 +++-- .../autopsy/keywordsearch/RegexQuery.java | 9 +++--- .../keywordsearch/TermsComponentQuery.java | 23 +++++++------- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordHit.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordHit.java index 87ddac3d22..1d588dcf58 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordHit.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordHit.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.keywordsearch; import java.util.Comparator; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -26,10 +27,10 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** - * Stores the fact that file or an artifact associated with a file had a keyword - * hit. All instances make both the document id of the Solr document where the - * keyword was found and the object Id available to clients. Artifact keyword - * hits also make the artifact available to clients. + * Represents the fact that a file or an artifact associated with a file had a + * keyword hit. All instances make both the document id of the Solr document + * where the keyword was found and the object Id of the file available to + * clients. Artifact keyword hits also make the artifact available to clients. */ class KeywordHit implements Comparable { @@ -38,7 +39,7 @@ class KeywordHit implements Comparable { private final int chunkId; private final String snippet; private final long contentID; - private final BlackboardArtifact artifact; + private final boolean hitOnArtifact; private final String hit; public String getHit() { @@ -67,18 +68,18 @@ class KeywordHit implements Comparable { this.solrObjectId = Long.parseLong(solrDocumentId); this.chunkId = 0; } + hitOnArtifact = this.solrObjectId < 0; /* * If the high order bit of the object id is set (ie, it is negative), * the hit was in an artifact, look up the artifact. */ - if (this.solrObjectId < 0) { + if (hitOnArtifact) { SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase(); - this.artifact = caseDb.getBlackboardArtifact(this.solrObjectId); + BlackboardArtifact artifact = caseDb.getBlackboardArtifact(this.solrObjectId); contentID = artifact.getObjectID(); } else { //else the object id is for content. - this.artifact = null; contentID = this.solrObjectId; } } @@ -113,17 +114,20 @@ class KeywordHit implements Comparable { * @return */ boolean isArtifactHit() { - return (null != this.artifact); + return hitOnArtifact; } /** * If this hit is in the indexed text of an artifact, get that artifact. * - * @return The artifact whose indexed text this hit is in, or null if it is - * not an artifacts hit. + * @return The artifact whose indexed text this hit is in. */ - BlackboardArtifact getArtifact() { - return this.artifact; + Optional getArtifactID() { + if (hitOnArtifact) { + return Optional.of(solrObjectId); + } else { + return Optional.empty(); + } } @Override diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java index b603f7b68c..bcc08a3726 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java @@ -140,7 +140,7 @@ class KeywordSearchResultFactory extends ChildFactory { queryResults = queryRequest.performQuery(); } catch (KeywordSearchModuleException | NoOpenCoreException ex) { logger.log(Level.SEVERE, "Could not perform the query " + queryRequest.getQueryString(), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.KeywordSearchResultFactory_query_exception_msg() + queryRequest.getQueryString(), ex.getCause().getMessage()); + MessageNotifyUtil.Notify.error(org.sleuthkit.autopsy.keywordsearch.Bundle.KeywordSearchResultFactory_query_exception_msg() + queryRequest.getQueryString(), ex.getCause().getMessage()); return false; } SleuthkitCase tskCase = null; @@ -186,12 +186,16 @@ class KeywordSearchResultFactory extends ChildFactory { properties.put(TSK_KEYWORD_PREVIEW.getDisplayName(), hit.getSnippet()); } - String hitName = hit.isArtifactHit() - ? hit.getArtifact().getDisplayName() + " Artifact" //NON-NLS - : contentName; - - hitNumber++; - tempList.add(new KeyValueQueryContent(hitName, properties, hitNumber, hit.getSolrObjectId(), content, queryRequest, queryResults)); + try { + String hitName = hit.isArtifactHit() + ? tskCase.getBlackboardArtifact(hit.getArtifactID().get()).getDisplayName() + " Artifact" //NON-NLS + : contentName; + hitNumber++; + tempList.add(new KeyValueQueryContent(hitName, properties, hitNumber, hit.getSolrObjectId(), content, queryRequest, queryResults)); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + return false; + } } // Add all the nodes to toPopulate at once. Minimizes node creation diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java index 3821501574..f89dae123d 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/LuceneQuery.java @@ -225,9 +225,11 @@ class LuceneQuery implements KeywordSearchQuery { } } - if (hit.isArtifactHit()) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, hit.getArtifact().getArtifactID())); - } + + hit.getArtifactID().ifPresent(artifactID + -> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + ); + try { bba.addAttributes(attributes); //write out to bb diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 6b91c9c2fb..a422d9f9c3 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -417,7 +417,7 @@ final class RegexQuery implements KeywordSearchQuery { final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { if (hit.isArtifactHit()) { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifact().getArtifactID())); //NON-NLS + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS } else { LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", foundKeyword.getSearchTerm(), hit.getSnippet(), hit.getContentID())); //NON-NLS } @@ -480,9 +480,10 @@ final class RegexQuery implements KeywordSearchQuery { if (snippet != null) { attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); } - if (hit.isArtifactHit()) { - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, hit.getArtifact().getArtifactID())); - } + + hit.getArtifactID().ifPresent(artifactID + -> attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + ); attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.REGEX.ordinal())); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java index 62c7dd601d..f37be9952e 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermsComponentQuery.java @@ -359,7 +359,7 @@ final class TermsComponentQuery implements KeywordSearchQuery { final BlackboardAttribute ccnAttribute = parsedTrackAttributeMap.get(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)); if (ccnAttribute == null || StringUtils.isBlank(ccnAttribute.getValueString())) { if (hit.isArtifactHit()) { - LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", searchTerm, hit.getSnippet(), hit.getArtifact().getArtifactID())); //NON-NLS + LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for artifact keyword hit: term = %s, snippet = '%s', artifact id = %d", searchTerm, hit.getSnippet(), hit.getArtifactID().get())); //NON-NLS } else { LOGGER.log(Level.SEVERE, String.format("Failed to parse credit card account number for content keyword hit: term = %s, snippet = '%s', object id = %d", searchTerm, hit.getSnippet(), hit.getContentID())); //NON-NLS } @@ -398,7 +398,7 @@ final class TermsComponentQuery implements KeywordSearchQuery { * hit. */ if (content instanceof AbstractFile) { - AbstractFile file = (AbstractFile)content; + AbstractFile file = (AbstractFile) content; if (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) { attributes.add(new BlackboardAttribute(KEYWORD_SEARCH_DOCUMENT_ID, MODULE_NAME, hit.getSolrDocumentId())); @@ -422,9 +422,10 @@ final class TermsComponentQuery implements KeywordSearchQuery { if (snippet != null) { attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW, MODULE_NAME, snippet)); } - if (hit.isArtifactHit()) { - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, hit.getArtifact().getArtifactID())); - } + + hit.getArtifactID().ifPresent( + artifactID -> attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, artifactID)) + ); // TermsComponentQuery is now being used exclusively for substring searches. attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE, MODULE_NAME, KeywordSearch.QueryType.SUBSTRING.ordinal())); @@ -472,12 +473,12 @@ final class TermsComponentQuery implements KeywordSearchQuery { * Creates an attribute of the the given type to the given artifact with a * value parsed from the snippet for a credit account number hit. * - * @param attributesMap A map of artifact attribute objects, used to avoid - * creating duplicate attributes. - * @param attrType The type of attribute to create. - * @param groupName The group name of the regular expression that was - * used to parse the attribute data. - * @param matcher A matcher for the snippet. + * @param attributeMap A map of artifact attribute objects, used to avoid + * creating duplicate attributes. + * @param attrType The type of attribute to create. + * @param groupName The group name of the regular expression that was + * used to parse the attribute data. + * @param matcher A matcher for the snippet. */ static private void addAttributeIfNotAlreadyCaptured(Map attributeMap, ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) { BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType);