make RawText handle both Content and BlackBoardArtifacts

This commit is contained in:
Karl Mortensen 2015-11-19 11:09:19 -05:00
parent eeef9ef4af
commit 83d51934ac
9 changed files with 101 additions and 101 deletions

View File

@ -146,12 +146,12 @@
<Component class="javax.swing.JComboBox" name="sourceComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new javax.swing.DefaultComboBoxModel&lt;org.sleuthkit.autopsy.keywordsearch.TextMarkup&gt;()" type="code"/>
<Connection code="new javax.swing.DefaultComboBoxModel&lt;org.sleuthkit.autopsy.keywordsearch.IndexedText&gt;()" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox&lt;&gt;()"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;org.sleuthkit.autopsy.keywordsearch.TextMarkup&gt;"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;org.sleuthkit.autopsy.keywordsearch.IndexedText&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="hitLabel">

View File

@ -130,13 +130,13 @@ class ExtractedContentPanel extends javax.swing.JPanel {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
TextMarkup source = (TextMarkup) e.getItem();
IndexedText source = (IndexedText) e.getItem();
setMarkup(source);
}
}
});
setSources(new ArrayList<TextMarkup>());
setSources(new ArrayList<IndexedText>());
extractedTextPane.setComponentPopupMenu(rightClickMenu);
ActionListener actList = new ActionListener() {
@ -204,7 +204,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
extractedTextPane.setPreferredSize(new java.awt.Dimension(700, 400));
jScrollPane1.setViewportView(extractedTextPane);
sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel<TextMarkup>());
sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel<IndexedText>());
hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N
hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N
@ -357,11 +357,11 @@ class ExtractedContentPanel extends javax.swing.JPanel {
private javax.swing.JLabel pagesLabel;
private javax.swing.JPopupMenu rightClickMenu;
private javax.swing.JMenuItem selectAllMenuItem;
private javax.swing.JComboBox<TextMarkup> sourceComboBox;
private javax.swing.JComboBox<IndexedText> sourceComboBox;
// End of variables declaration//GEN-END:variables
void refreshCurrentMarkup() {
TextMarkup ms = (TextMarkup) sourceComboBox.getSelectedItem();
IndexedText ms = (IndexedText) sourceComboBox.getSelectedItem();
setMarkup(ms);
}
@ -371,11 +371,11 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @param sources
*/
void setSources(List<TextMarkup> sources) {
void setSources(List<IndexedText> sources) {
sourceComboBox.removeAllItems();
setPanelText(null, false);
for (TextMarkup ms : sources) {
for (IndexedText ms : sources) {
sourceComboBox.addItem(ms);
}
@ -390,8 +390,8 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @return currently available sources on the panel
*/
public List<TextMarkup> getSources() {
ArrayList<TextMarkup> sources = new ArrayList<>();
public List<IndexedText> getSources() {
ArrayList<IndexedText> sources = new ArrayList<>();
for (int i = 0; i < sourceComboBox.getItemCount(); ++i) {
sources.add(sourceComboBox.getItemAt(i));
}
@ -403,8 +403,8 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @return currently selected Source
*/
public TextMarkup getSelectedSource() {
return (TextMarkup) sourceComboBox.getSelectedItem();
public IndexedText getSelectedSource() {
return (IndexedText) sourceComboBox.getSelectedItem();
}
private void setPanelText(String text, boolean detectDirection) {
@ -565,7 +565,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @param source the selected source
*/
void updateControls(TextMarkup source) {
void updateControls(IndexedText source) {
updatePageControls(source);
updateSearchControls(source);
}
@ -575,7 +575,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @param source selected source
*/
void updatePageControls(TextMarkup source) {
void updatePageControls(IndexedText source) {
if (source == null) {
enableNextPageControl(false);
enablePrevPageControl(false);
@ -612,7 +612,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @param source selected source
*/
void updateSearchControls(TextMarkup source) {
void updateSearchControls(IndexedText source) {
//setup search controls
if (source != null && source.isSearchable()) {
@ -644,7 +644,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*
* @param source
*/
private void scrollToCurrentHit(final TextMarkup source) {
private void scrollToCurrentHit(final IndexedText source) {
if (source == null || !source.isSearchable()) {
return;
}
@ -664,7 +664,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
* text). Updates GUI in GUI thread and gets markup in background thread. To
* be invoked from GUI thread only.
*/
private void setMarkup(TextMarkup source) {
private void setMarkup(IndexedText source) {
setPanelText(NbBundle.getMessage(this.getClass(), "ExtractedContentPanel.setMarkup.panelTxt"), false);
new SetMarkupWorker(source).execute();
}
@ -676,11 +676,11 @@ class ExtractedContentPanel extends javax.swing.JPanel {
*/
private final class SetMarkupWorker extends SwingWorker<Object, Void> {
private TextMarkup source;
private IndexedText source;
private String markup;
private ProgressHandle progress;
SetMarkupWorker(TextMarkup source) {
SetMarkupWorker(IndexedText source) {
this.source = source;
}
@ -693,7 +693,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
progress.start();
progress.switchToIndeterminate();
markup = source.getMarkup();
markup = source.getText();
return null;
}

View File

@ -48,7 +48,7 @@ public class ExtractedContentViewer implements DataContentViewer {
private static final long INVALID_DOCUMENT_ID = 0L;
private ExtractedContentPanel panel;
private volatile Node currentNode = null;
private TextMarkup currentSource = null;
private IndexedText currentSource = null;
private final IsDirVisitor isDirVisitor = new IsDirVisitor();
public ExtractedContentViewer() {
@ -81,8 +81,8 @@ public class ExtractedContentViewer implements DataContentViewer {
* marked up with HTML to highlight keyword hits that will be present if
* the node is a keyword hit blakcboard artifact.
*/
final List<TextMarkup> sources = new ArrayList<>();
sources.addAll(selectedNode.getLookup().lookupAll(TextMarkup.class));
final List<IndexedText> sources = new ArrayList<>();
sources.addAll(selectedNode.getLookup().lookupAll(IndexedText.class));
/*
* Now look for the "raw" extracted text if this is a node for another
@ -93,21 +93,18 @@ public class ExtractedContentViewer implements DataContentViewer {
setPanel(sources);
return;
}
/*
* KDM TODO: Make RawTextMarkup able to handle artifacts as well as
* Content, or use RawTextMarkup as a base class for subclasses that
* handle artifacts and content.
*/
IndexedText rawSource;
if (documentID > INVALID_DOCUMENT_ID) {
/*
* Add a source for the raw text.
*/
// Add a content item
Content content = currentNode.getLookup().lookup(Content.class);
TextMarkup rawSource = new RawTextMarkup(content, content.getId());
currentSource = rawSource;
sources.add(rawSource);
rawSource = new RawText(content, content.getId());
} else {
// Add an artifact item
BlackboardArtifact blackboardArtifact = currentNode.getLookup().lookup(BlackboardArtifact.class);
rawSource = new RawText(blackboardArtifact, documentID);
}
currentSource = rawSource;
sources.add(rawSource);
/*
* Initialize the pages for the sources. The first source in the list
@ -122,7 +119,7 @@ public class ExtractedContentViewer implements DataContentViewer {
}
private void scrollToCurrentHit() {
final TextMarkup source = panel.getSelectedSource();
final IndexedText source = panel.getSelectedSource();
if (source == null || !source.isSearchable()) {
return;
}
@ -161,7 +158,7 @@ public class ExtractedContentViewer implements DataContentViewer {
@Override
public void resetComponent() {
setPanel(new ArrayList<TextMarkup>());
setPanel(new ArrayList<IndexedText>());
panel.resetDisplay();
currentNode = null;
currentSource = null;
@ -179,7 +176,7 @@ public class ExtractedContentViewer implements DataContentViewer {
* by either an ad hoc keyword search result (keyword search toolbar
* widgets) or a keyword search by the keyword search ingest module.
*/
Collection<? extends TextMarkup> sources = node.getLookup().lookupAll(TextMarkup.class);
Collection<? extends IndexedText> sources = node.getLookup().lookupAll(IndexedText.class);
if (sources.isEmpty() == false) {
return true;
}
@ -215,7 +212,7 @@ public class ExtractedContentViewer implements DataContentViewer {
*
* @param sources
*/
private void setPanel(List<TextMarkup> sources) {
private void setPanel(List<IndexedText> sources) {
if (panel != null) {
panel.setSources(sources);
}
@ -291,7 +288,7 @@ public class ExtractedContentViewer implements DataContentViewer {
@Override
public void actionPerformed(ActionEvent e) {
TextMarkup source = panel.getSelectedSource();
IndexedText source = panel.getSelectedSource();
if (source == null) {
// reset
panel.updateControls(null);
@ -331,7 +328,7 @@ public class ExtractedContentViewer implements DataContentViewer {
@Override
public void actionPerformed(ActionEvent e) {
TextMarkup source = panel.getSelectedSource();
IndexedText source = panel.getSelectedSource();
final boolean hasPreviousItem = source.hasPreviousItem();
final boolean hasPreviousPage = source.hasPreviousPage();
int indexVal = 0;

View File

@ -39,12 +39,12 @@ import org.sleuthkit.autopsy.keywordsearch.KeywordQueryFilter.FilterType;
* Highlights hits for a given document. Knows about pages and such for the
* content viewer.
*/
class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
class HighlightedText implements IndexedText, TextMarkupLookup {
private static final Logger logger = Logger.getLogger(HighlightedTextMarkup.class.getName());
private static final Logger logger = Logger.getLogger(HighlightedText.class.getName());
private static final String HIGHLIGHT_PRE = "<span style='background:yellow'>"; //NON-NLS
private static final String HIGHLIGHT_POST = "</span>"; //NON-NLS
private static final String ANCHOR_PREFIX = HighlightedTextMarkup.class.getName() + "_";
private static final String ANCHOR_PREFIX = HighlightedText.class.getName() + "_";
private long objectId;
private String keywordHitQuery;
@ -64,7 +64,7 @@ class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
private boolean isPageInfoLoaded = false;
private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT);
HighlightedTextMarkup(long objectId, String keywordHitQuery, boolean isRegex) {
HighlightedText(long objectId, String keywordHitQuery, boolean isRegex) {
this.objectId = objectId;
this.keywordHitQuery = keywordHitQuery;
this.isRegex = isRegex;
@ -81,17 +81,17 @@ class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
}
//when the results are not known and need to requery to get hits
HighlightedTextMarkup(long objectId, String solrQuery, boolean isRegex, String originalQuery) {
HighlightedText(long objectId, String solrQuery, boolean isRegex, String originalQuery) {
this(objectId, solrQuery, isRegex);
this.originalQuery = originalQuery;
}
HighlightedTextMarkup(long objectId, String solrQuery, boolean isRegex, QueryResults hits) {
HighlightedText(long objectId, String solrQuery, boolean isRegex, QueryResults hits) {
this(objectId, solrQuery, isRegex);
this.hits = hits;
}
HighlightedTextMarkup(long objectId, String solrQuery, boolean isRegex, boolean group, QueryResults hits) {
HighlightedText(long objectId, String solrQuery, boolean isRegex, boolean group, QueryResults hits) {
this(objectId, solrQuery, isRegex, hits);
this.group = group;
}
@ -185,7 +185,7 @@ class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
}
//constructor for dummy singleton factory instance for Lookup
private HighlightedTextMarkup() {
private HighlightedText() {
}
long getObjectId() {
@ -293,7 +293,7 @@ class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
}
@Override
public String getMarkup() {
public String getText() {
loadPageInfo(); //inits once
String highLightField = null;
@ -441,7 +441,7 @@ class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
//this instance does not actually work with Solr
public static synchronized TextMarkupLookup getDefault() {
if (instance == null) {
instance = new HighlightedTextMarkup();
instance = new HighlightedText();
}
return instance;
}
@ -449,6 +449,6 @@ class HighlightedTextMarkup implements TextMarkup, TextMarkupLookup {
@Override
// factory method to create an instance of this object
public TextMarkupLookup createInstance(long objectId, String keywordHitQuery, boolean isRegex, String originalQuery) {
return new HighlightedTextMarkup(objectId, keywordHitQuery, isRegex, originalQuery);
return new HighlightedText(objectId, keywordHitQuery, isRegex, originalQuery);
}
}

View File

@ -22,27 +22,27 @@ import java.util.LinkedHashMap;
/**
* Interface to provide HTML text to display in ExtractedContentViewer. There is
* a SOLR implementaiton of this that interfaces with SOLR to highlight the
* a SOLR implementation of this that interfaces with SOLR to highlight the
* keyword hits and a version that does not do markup so that you can simply
* view the stored text.
*/
interface TextMarkup {
interface IndexedText {
/**
* @return text optionally marked up with the subsest of HTML that Swing
* @return text optionally marked up with the subset of HTML that Swing
* components can handle in their setText() method.
*
*/
String getMarkup();
String getText();
/**
*
* @return true if markup is marked to be searchable
* @return true if text is marked to be searchable
*/
boolean isSearchable();
/**
* If searchable markup, returns prefix of anchor, otherwise return empty
* If searchable text, returns prefix of anchor, otherwise return empty
* string
*
* @return
@ -50,15 +50,15 @@ interface TextMarkup {
String getAnchorPrefix();
/**
* if searchable markup, returns number of hits found and encoded in the
* markup
* if searchable text, returns number of hits found and encoded in the
* text
*
* @return
*/
int getNumberHits();
/**
* @return title of markup source
* @return title of text source
*/
@Override
String toString();

View File

@ -45,7 +45,7 @@ import org.sleuthkit.datamodel.File;
*/
class KeywordSearchFilterNode extends FilterNode {
KeywordSearchFilterNode(HighlightedTextMarkup highlights, Node original) {
KeywordSearchFilterNode(HighlightedText highlights, Node original) {
super(original, null, new ProxyLookup(Lookups.singleton(highlights), original.getLookup()));
}

View File

@ -310,7 +310,7 @@ class KeywordSearchResultFactory extends ChildFactory<KeyValueQueryContent> {
//wrap in KeywordSearchFilterNode for the markup content, might need to override FilterNode for more customization
// store the data in HighlightedMatchesSource so that it can be looked up (in content viewer)
HighlightedTextMarkup highlights = new HighlightedTextMarkup(key.solrObjectId, queryStr, !key.getQuery().isLiteral(), false, hits);
HighlightedText highlights = new HighlightedText(key.solrObjectId, queryStr, !key.getQuery().isLiteral(), false, hits);
return new KeywordSearchFilterNode(highlights, kvNode);
}

View File

@ -25,30 +25,31 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskData;
/**
* Display content with just raw text, no markup
* Display content with just raw text
*
*/
class RawTextMarkup implements TextMarkup {
class RawText implements IndexedText {
private int numPages = 0;
private int currentPage = 0;
private boolean hasChunks = false;
private final Content content;
private final BlackboardArtifact blackboardArtifact;
private final long objectId;
//keep last content cached
private String cachedString;
private int cachedChunk;
private static final Logger logger = Logger.getLogger(RawTextMarkup.class.getName());
private static final Logger logger = Logger.getLogger(RawText.class.getName());
/**
* Construct a new RawTextMarkup object for the given content and object id.
* Construct a new RawText object for the given content and object id.
* This constructor needs both a content object and an object id because the
* RawTextMarkup implementation attempts to provide useful messages in the
* RawText implementation attempts to provide useful messages in the
* text content viewer for (a) the case where a file has not been indexed
* because known files are being skipped and (b) the case where the file
* content has not yet been indexed.
@ -56,10 +57,31 @@ class RawTextMarkup implements TextMarkup {
* @param content Used to get access to file names and "known" status.
* @param objectId Either a file id or an artifact id.
*/
RawTextMarkup(Content content, long objectId) {
RawText(Content content, long objectId) {
this.content = content;
this.blackboardArtifact = null;
this.objectId = objectId;
initialize();
final Server solrServer = KeywordSearch.getServer();
try {
//add to page tracking if not there yet
numPages = solrServer.queryNumFileChunks(this.objectId);
if (numPages == 0) {
numPages = 1;
hasChunks = false;
} else {
hasChunks = true;
}
} catch (KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of chunks: ", ex); //NON-NLS
}
}
RawText(BlackboardArtifact bba, long objectId) {
this.content = null;
this.blackboardArtifact = bba;
this.objectId = objectId;
numPages = 1;
hasChunks = false;
}
/**
@ -137,13 +159,17 @@ class RawTextMarkup implements TextMarkup {
}
@Override
public String getMarkup() {
public String getText() {
try {
return getSolrContent(currentPage, hasChunks);
} catch (SolrServerException ex) {
if (this.content != null) {
return getSolrContent(currentPage, hasChunks);
} else if (this.blackboardArtifact != null) {
return KeywordSearch.getServer().getSolrContent(this.objectId, 1);
}
} catch (SolrServerException | NoOpenCoreException ex) {
logger.log(Level.WARNING, "Couldn't get extracted content.", ex); //NON-NLS
return "";
}
return "Error getting text";
}
@Override
@ -176,29 +202,6 @@ class RawTextMarkup implements TextMarkup {
return numPages;
}
/**
* Set the internal values, such as pages and chunks
*/
private void initialize() {
final Server solrServer = KeywordSearch.getServer();
try {
//add to page tracking if not there yet
numPages = solrServer.queryNumFileChunks(this.objectId);
if (numPages == 0) {
numPages = 1;
hasChunks = false;
} else {
hasChunks = true;
}
} catch (KeywordSearchModuleException ex) {
logger.log(Level.WARNING, "Could not get number of chunks: ", ex); //NON-NLS
} catch (NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of chunks: ", ex); //NON-NLS
}
}
/**
* Get extracted content for a node from Solr
*

View File

@ -19,9 +19,9 @@
Services
======================================================= -->
<folder name="Services">
<file name="org-sleuthkit-autopsy-keywordsearch-HighlightedTextMarkup.instance">
<file name="org-sleuthkit-autopsy-keywordsearch-HighlightedText.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.datamodel.TextMarkupLookup"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.keywordsearch.HighlightedTextMarkup.getDefault"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.keywordsearch.HighlightedText.getDefault"/>
<attr name="position" intvalue="250"/>
</file>
</folder>