diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java index 43f0d7baf8..b8fef30f01 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentViewer.java @@ -27,13 +27,14 @@ import java.util.Collection; import java.util.List; import java.util.logging.Level; import org.openide.nodes.Node; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.QueryContent; +import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.AdHocQueryResult; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -51,7 +52,7 @@ import org.sleuthkit.datamodel.TskCoreException; @ServiceProvider(service = DataContentViewer.class, position = 4) public class ExtractedContentViewer implements DataContentViewer { - private static final Logger LOGGER = Logger.getLogger(ExtractedContentViewer.class.getName()); + private static final Logger logger = Logger.getLogger(ExtractedContentViewer.class.getName()); private static final long INVALID_DOCUMENT_ID = 0L; private static final BlackboardAttribute.Type TSK_ASSOCIATED_ARTIFACT_TYPE = new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT); @@ -93,9 +94,6 @@ public class ExtractedContentViewer implements DataContentViewer { currentNode = node; } - Lookup nodeLookup = node.getLookup(); - AbstractFile content = nodeLookup.lookup(AbstractFile.class); - /* * Assemble a collection of all of the indexed text "sources" for the * node. @@ -104,44 +102,37 @@ public class ExtractedContentViewer implements DataContentViewer { IndexedText highlightedHitText = null; IndexedText rawContentText = null; - if (null != content && solrHasContent(content.getId())) { - /* - * Results for Keyword Hits. - */ - BlackboardArtifact artifact = nodeLookup.lookup(BlackboardArtifact.class); - if (artifact != null) { - if (artifact.getArtifactTypeID() == TSK_ACCOUNT.getTypeID()) { - try { - /* - * Generate AccountsText for the account artifact. - */ - highlightedHitText = getAccountsText(content, nodeLookup); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to create AccountsText for " + content, ex); //NON-NLS - } - } else if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) { - try { - /* - * Generate HighlightedText for the keyword hit artifact. - */ - highlightedHitText = new HighlightedText(artifact); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to create HighlightedText for " + artifact, ex); //NON-NLS - } + Lookup nodeLookup = node.getLookup(); + + AdHocQueryResult adHocQueryResult = nodeLookup.lookup(AdHocQueryResult.class); + BlackboardArtifact artifact = nodeLookup.lookup(BlackboardArtifact.class); + AbstractFile content = nodeLookup.lookup(AbstractFile.class); + + if (adHocQueryResult != null) { + highlightedHitText = new HighlightedText(adHocQueryResult.getSolrObjectId(), adHocQueryResult.getResults()); + } else if (artifact != null) { + if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) { + try { + highlightedHitText = new HighlightedText(artifact); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + } else if (artifact.getArtifactTypeID() == TSK_ACCOUNT.getTypeID() && content != null) { + try { + highlightedHitText = getAccountsText(content, nodeLookup); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); } } - } else { - /* - * Results for ad-hoc search. - */ - QueryContent queryContent = nodeLookup.lookup(QueryContent.class); - content = (AbstractFile) queryContent.getContent(); - - if (null != content && solrHasContent(content.getId())) { - QueryResults queryResults = queryContent.getResults(); - if (queryResults != null) { - highlightedHitText = new HighlightedText(queryContent.getSolrObjectId(), queryResults); - } + } + + if (content != null) { + rawContentText = new RawText(content, content.getId()); + } else if (artifact != null) { + try { + rawContentText = getRawArtifactText(nodeLookup); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); } } @@ -150,11 +141,10 @@ public class ExtractedContentViewer implements DataContentViewer { } /* - * Next, add the "raw" (not highlighted) text, if any, for any - * content associated with the node. + * Next, add the "raw" (not highlighted) text, if any, for any content + * associated with the node. */ - if (content != null) { - rawContentText = new RawText(content, content.getId()); + if (rawContentText != null) { sources.add(rawContentText); } @@ -166,7 +156,7 @@ public class ExtractedContentViewer implements DataContentViewer { try { rawArtifactText = getRawArtifactText(nodeLookup); } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error creating RawText for " + content, ex); //NON-NLS + logger.log(Level.SEVERE, "Error creating RawText for " + content, ex); //NON-NLS } if (rawArtifactText != null) { @@ -289,6 +279,11 @@ public class ExtractedContentViewer implements DataContentViewer { return false; } + AdHocQueryResult adHocQueryResult = node.getLookup().lookup(AdHocQueryResult.class); + if (adHocQueryResult != null) { + return true; + } + /* * Is there a credit card or keyword hit artifact in the lookup */ @@ -296,26 +291,63 @@ public class ExtractedContentViewer implements DataContentViewer { if (artifacts != null) { for (BlackboardArtifact art : artifacts) { final int artifactTypeID = art.getArtifactTypeID(); - if (artifactTypeID == TSK_ACCOUNT.getTypeID()) { + if (artifactTypeID == TSK_KEYWORD_HIT.getTypeID()) { + return true; + } else if (artifactTypeID == TSK_ACCOUNT.getTypeID()) { try { BlackboardAttribute attribute = art.getAttribute(TSK_ACCOUNT_TYPE); if (attribute != null && Account.Type.CREDIT_CARD.getTypeName().equals(attribute.getValueString())) { return true; } } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error getting TSK_ACCOUNT_TYPE attribute from artifact " + art.getArtifactID(), ex); + logger.log(Level.SEVERE, "Error getting TSK_ACCOUNT_TYPE attribute from artifact " + art.getArtifactID(), ex); + return true; } - } else if (artifactTypeID == TSK_KEYWORD_HIT.getTypeID()) { - return true; } } } + /** + * If the node is a Blackboard artifact node for anything other than a + * keyword hit, the document ID for the text extracted from the artifact + * (the concatenation of its attributes) is the artifact ID, a large, + * negative integer. If it is a keyword hit, see if there is an + * associated artifact. If there is, get the associated artifact's ID + * and return it. + */ + long documentID = INVALID_DOCUMENT_ID; + + BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); + if (null != artifact) { + if (artifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { + documentID = artifact.getArtifactID(); + } else { + try { + // Get the associated artifact attribute and return its value as the ID + BlackboardAttribute blackboardAttribute = artifact.getAttribute(TSK_ASSOCIATED_ARTIFACT_TYPE); + if (blackboardAttribute != null) { + documentID = blackboardAttribute.getValueLong(); + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Error getting associated artifact attributes", ex); //NON-NLS + } + } + } + + /* + * For keyword search hit artifact nodes and all other nodes, the + * document ID for the extracted text is the ID of the associated + * content, if any, unless there is an associated artifact, which is + * handled above. + */ + Content content = node.getLookup().lookup(Content.class); + if (content != null) { + documentID = content.getId(); + } /* * No highlighted text for a keyword hit, so is there any indexed text * at all for this node? */ - long documentID = getDocumentId(node); if (INVALID_DOCUMENT_ID == documentID) { return false; } @@ -367,69 +399,11 @@ public class ExtractedContentViewer implements DataContentViewer { try { return solrServer.queryIsIndexed(objectId); } catch (NoOpenCoreException | KeywordSearchModuleException ex) { - LOGGER.log(Level.SEVERE, "Error querying Solr server", ex); //NON-NLS + logger.log(Level.SEVERE, "Error querying Solr server", ex); //NON-NLS return false; } } - /** - * Gets the object ID to use as the document ID for accessing any indexed - * text for the given node. - * - * @param node The node. - * - * @return The document ID or zero, which is an invalid document ID. - */ - private Long getDocumentId(Node node) { - /** - * If the node is a Blackboard artifact node for anything other than a - * keyword hit, the document ID for the text extracted from the artifact - * (the concatenation of its attributes) is the artifact ID, a large, - * negative integer. If it is a keyword hit, see if there is an - * associated artifact. If there is, get the associated artifact's ID - * and return it. - */ - BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); - if (null != artifact) { - if (artifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - return artifact.getArtifactID(); - } else { - try { - // Get the associated artifact attribute and return its value as the ID - BlackboardAttribute blackboardAttribute = artifact.getAttribute(TSK_ASSOCIATED_ARTIFACT_TYPE); - if (blackboardAttribute != null) { - return blackboardAttribute.getValueLong(); - } - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error getting associated artifact attributes", ex); //NON-NLS - } - } - } - - /* - * For keyword search hit artifact nodes and all other nodes, the - * document ID for the extracted text is the ID of the associated - * content, if any, unless there is an associated artifact, which is - * handled above. - */ - Content content = node.getLookup().lookup(Content.class); - if (content == null) { - QueryContent queryContent = node.getLookup().lookup(QueryContent.class); - if (queryContent != null) { - content = queryContent.getContent(); - } - } - - if (content != null) { - return content.getId(); - } - - /* - * No extracted text, return an invalid docuemnt ID. - */ - return 0L; - } - private class NextFindActionListener implements ActionListener { @Override diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedText.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedText.java index 9bcbdd7b2a..2fa4bbf999 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedText.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/HighlightedText.java @@ -54,7 +54,7 @@ import org.sleuthkit.datamodel.TskCoreException; */ class HighlightedText implements IndexedText { - private static final Logger LOGGER = Logger.getLogger(HighlightedText.class.getName()); + private static final Logger logger = Logger.getLogger(HighlightedText.class.getName()); private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT); @@ -400,7 +400,7 @@ class HighlightedText implements IndexedText { // either be a single chunk containing hits or we narrow our // query down to the current page/chunk. if (response.getResults().size() > 1) { - LOGGER.log(Level.WARNING, "Unexpected number of results for Solr highlighting query: {0}", q); //NON-NLS + logger.log(Level.WARNING, "Unexpected number of results for Solr highlighting query: {0}", q); //NON-NLS } String highlightedContent; Map>> responseHighlight = response.getHighlighting(); @@ -426,7 +426,7 @@ class HighlightedText implements IndexedText { return "
" + highlightedContent + "
"; //NON-NLS } catch (TskCoreException | KeywordSearchModuleException | NoOpenCoreException ex) { - LOGGER.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + solrObjectId + ", chunkID " + chunkID + ", highlight query: " + highlightField, ex); //NON-NLS + logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + solrObjectId + ", chunkID " + chunkID + ", highlight query: " + highlightField, ex); //NON-NLS return NbBundle.getMessage(this.getClass(), "HighlightedMatchesSource.getMarkup.queryFailedMsg"); } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java index b848892691..58876870e5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchFilterNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; -import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.QueryContent; +import org.sleuthkit.autopsy.keywordsearch.KeywordSearchResultFactory.AdHocQueryResult; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentVisitor; @@ -60,11 +60,11 @@ class KeywordSearchFilterNode extends FilterNode { /** * Instantiate a KeywordSearchFilterNode. * - * @param queryContent The query content. - * @param original The original source node. + * @param adHocQueryResult The query content. + * @param original The original source node. */ - KeywordSearchFilterNode(QueryContent queryContent, Node original) { - super(original, null, new ProxyLookup(Lookups.singleton(queryContent), original.getLookup())); + KeywordSearchFilterNode(AdHocQueryResult adHocQueryResult, Node original) { + super(original, null, new ProxyLookup(Lookups.singleton(adHocQueryResult), original.getLookup())); } @Override diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java index c8c1c07b15..fb37a84e59 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java @@ -66,7 +66,7 @@ import org.sleuthkit.datamodel.TskCoreException; */ class KeywordSearchResultFactory extends ChildFactory { - private static final Logger LOGGER = Logger.getLogger(KeywordSearchResultFactory.class.getName()); + private static final Logger logger = Logger.getLogger(KeywordSearchResultFactory.class.getName()); //common properties (superset of all Node properties) to be displayed as columns static final List COMMON_PROPERTIES @@ -140,7 +140,7 @@ class KeywordSearchResultFactory extends ChildFactory { try { queryResults = queryRequest.performQuery(); } catch (KeywordSearchModuleException | NoOpenCoreException ex) { - LOGGER.log(Level.SEVERE, "Could not perform the query " + queryRequest.getQueryString(), ex); //NON-NLS + 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()); return false; } @@ -148,7 +148,7 @@ class KeywordSearchResultFactory extends ChildFactory { try { tskCase = Case.getCurrentCase().getSleuthkitCase(); } catch (IllegalStateException ex) { - LOGGER.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS + logger.log(Level.SEVERE, "There was no case open.", ex); //NON-NLS return false; } @@ -165,11 +165,11 @@ class KeywordSearchResultFactory extends ChildFactory { try { content = tskCase.getContentById(hit.getContentID()); if (content == null) { - LOGGER.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS + logger.log(Level.SEVERE, "There was a error getting content by id."); //NON-NLS return false; } } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS + logger.log(Level.SEVERE, "There was a error getting content by id.", ex); //NON-NLS return false; } @@ -192,7 +192,7 @@ class KeywordSearchResultFactory extends ChildFactory { try { hitName = tskCase.getBlackboardArtifact(hit.getArtifactID().get()).getDisplayName() + " Artifact"; //NON-NLS } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Error getting blckboard artifact by id", ex); + logger.log(Level.SEVERE, "Error getting blckboard artifact by id", ex); return false; } } else { @@ -250,12 +250,12 @@ class KeywordSearchResultFactory extends ChildFactory { Node resultNode; if (key instanceof KeyValueQueryContent) { - QueryContent queryContent = new QueryContent((KeyValueQueryContent) key); + AdHocQueryResult adHocQueryResult = new AdHocQueryResult((KeyValueQueryContent) key); - Node kvNode = new KeyValueNode(key, Children.LEAF, Lookups.singleton(queryContent)); + Node kvNode = new KeyValueNode(key, Children.LEAF); //wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization - resultNode = new KeywordSearchFilterNode(queryContent, kvNode); + resultNode = new KeywordSearchFilterNode(adHocQueryResult, kvNode); } else { resultNode = new EmptyNode("This Node Is Empty"); resultNode.setDisplayName(NbBundle.getMessage(this.getClass(), "KeywordSearchResultFactory.createNodeForKey.noResultsFound.text")); @@ -269,19 +269,19 @@ class KeywordSearchResultFactory extends ChildFactory { * This class encapsulates content, query results, and an associated Solr * object ID for storing in the Lookup to be read later. */ - class QueryContent { + final class AdHocQueryResult { private final long solrObjectId; private final Content content; private final QueryResults results; /** - * Instantiate a QueryContent object. + * Instantiate a AdHocQueryResult object. * * @param solrObjectId The Solr object ID associated with the content. * @param content The content for the query result. * @param results The query results. */ - QueryContent(KeyValueQueryContent key) { + AdHocQueryResult(KeyValueQueryContent key) { this.solrObjectId = key.getSolrObjectId(); this.content = key.getContent(); this.results = key.getHits(); @@ -407,9 +407,9 @@ class KeywordSearchResultFactory extends ChildFactory { try { get(); } catch (InterruptedException | CancellationException ex) { - LOGGER.log(Level.WARNING, "User cancelled writing of ad hoc search query results for '{0}' to the blackboard", query.getQueryString()); //NON-NLS + logger.log(Level.WARNING, "User cancelled writing of ad hoc search query results for '{0}' to the blackboard", query.getQueryString()); //NON-NLS } catch (ExecutionException ex) { - LOGGER.log(Level.SEVERE, "Error writing of ad hoc search query results for " + query.getQueryString() + " to the blackboard", ex); //NON-NLS + logger.log(Level.SEVERE, "Error writing of ad hoc search query results for " + query.getQueryString() + " to the blackboard", ex); //NON-NLS } }