mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Add snippet property to keyword search results
This commit is contained in:
parent
ac2b767da3
commit
650bcec9b7
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2011 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.keywordsearch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.nodes.PropertySupport;
|
||||||
|
import org.openide.nodes.Sheet;
|
||||||
|
import org.openide.util.lookup.Lookups;
|
||||||
|
import org.openide.util.lookup.ProxyLookup;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentFilterNode;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
||||||
|
import org.sleuthkit.autopsy.keywordsearch.Server.Core;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter Node to add a "Snippet" property containing the first snippet of
|
||||||
|
* content matching the search that the Node was found with, and to provide
|
||||||
|
* the full highlighted content as a MarkupSource
|
||||||
|
*/
|
||||||
|
class KeywordSearchFilterNode extends ContentFilterNode {
|
||||||
|
|
||||||
|
private static final int SNIPPET_LENGTH = 100;
|
||||||
|
String solrQuery;
|
||||||
|
|
||||||
|
KeywordSearchFilterNode(HighlightedMatchesSource highlights, Node original, String solrQuery) {
|
||||||
|
super((ContentNode) original, null, new ProxyLookup(Lookups.singleton(highlights), original.getLookup()));
|
||||||
|
this.solrQuery = solrQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getSnippet() {
|
||||||
|
Core solrCore = KeywordSearch.getServer().getCore();
|
||||||
|
|
||||||
|
Content content = this.getContent();
|
||||||
|
|
||||||
|
SolrQuery q = new SolrQuery();
|
||||||
|
q.setQuery(solrQuery);
|
||||||
|
q.addFilterQuery("id:" + content.getId());
|
||||||
|
q.addHighlightField("content");
|
||||||
|
q.setHighlightSimplePre("«");
|
||||||
|
q.setHighlightSimplePost("»");
|
||||||
|
q.setHighlightSnippets(1);
|
||||||
|
q.setHighlightFragsize(SNIPPET_LENGTH);
|
||||||
|
|
||||||
|
try {
|
||||||
|
QueryResponse response = solrCore.query(q);
|
||||||
|
List<String> contentHighlights = response.getHighlighting().get(Long.toString(content.getId())).get("content");
|
||||||
|
if (contentHighlights == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
// extracted content is HTML-escaped, but snippet goes in a plain text field
|
||||||
|
return StringEscapeUtils.unescapeHtml(contentHighlights.get(0)).trim();
|
||||||
|
}
|
||||||
|
} catch (SolrServerException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Property<String> getSnippetProperty() {
|
||||||
|
|
||||||
|
Property<String> prop = new PropertySupport.ReadOnly("snippet",
|
||||||
|
String.class, "Snippet", "Snippet of matching content.") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue() {
|
||||||
|
return getSnippet();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
prop.setValue("suppressCustomEditor", Boolean.TRUE); // remove the "..." (editing) button
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node.PropertySet[] getPropertySets() {
|
||||||
|
Node.PropertySet[] propertySets = super.getPropertySets();
|
||||||
|
|
||||||
|
for (int i = 0; i < propertySets.length; i++) {
|
||||||
|
Node.PropertySet ps = propertySets[i];
|
||||||
|
|
||||||
|
if (ps.getName().equals(Sheet.PROPERTIES)) {
|
||||||
|
Sheet.Set newPs = new Sheet.Set();
|
||||||
|
newPs.setName(ps.getName());
|
||||||
|
newPs.setDisplayName(ps.getDisplayName());
|
||||||
|
newPs.setShortDescription(ps.getShortDescription());
|
||||||
|
|
||||||
|
Property[] oldProperties = ps.getProperties();
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
for (Property p : oldProperties) {
|
||||||
|
if (j++ == 1) {
|
||||||
|
newPs.put(getSnippetProperty());
|
||||||
|
}
|
||||||
|
newPs.put(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
propertySets[i] = newPs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return propertySets;
|
||||||
|
}
|
||||||
|
}
|
@ -22,10 +22,6 @@ import java.sql.SQLException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.Lookup;
|
|
||||||
import org.openide.util.lookup.Lookups;
|
|
||||||
import org.openide.util.lookup.ProxyLookup;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentFilterNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
|
import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
|
||||||
import org.sleuthkit.autopsy.datamodel.RootContentChildren;
|
import org.sleuthkit.autopsy.datamodel.RootContentChildren;
|
||||||
@ -53,9 +49,8 @@ class KeywordSearchNode extends AbstractNode implements ContentNode {
|
|||||||
// to the lookup
|
// to the lookup
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Node original : originalNodes) {
|
for (Node original : originalNodes) {
|
||||||
MarkupSource markup = new HighlightedMatchesSource(key, solrQuery);
|
HighlightedMatchesSource markup = new HighlightedMatchesSource(key, solrQuery);
|
||||||
Lookup filterLookup = new ProxyLookup(Lookups.singleton(markup), original.getLookup());
|
filterNodes[i++] = new KeywordSearchFilterNode(markup, original, solrQuery);
|
||||||
filterNodes[i++] = new ContentFilterNode((ContentNode) original, null, filterLookup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return filterNodes;
|
return filterNodes;
|
||||||
@ -64,7 +59,8 @@ class KeywordSearchNode extends AbstractNode implements ContentNode {
|
|||||||
|
|
||||||
this.solrQuery = solrQuery;
|
this.solrQuery = solrQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getID() {
|
public long getID() {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user