mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Renamed interface and classes to more appropriate name
This commit is contained in:
parent
3757ca606d
commit
318917bcc6
@ -50,7 +50,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* and HighlightedText are very similar and could probably use some refactoring
|
||||
* to reduce code duplication.
|
||||
*/
|
||||
class AccountsText implements IndexedText {
|
||||
class AccountsText implements ExtractedText {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AccountsText.class.getName());
|
||||
private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT);
|
||||
@ -312,7 +312,7 @@ class AccountsText implements IndexedText {
|
||||
return "<html><pre>" + highlightedText + "</pre></html>"; //NON-NLS
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + this.solrObjectId + ", chunkID " + this.currentPage, ex); //NON-NLS
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ ExtractAllTermsReport.error.noOpenCase=No currently open case.
|
||||
ExtractAllTermsReport.export.error=Error During Unique Word Extraction
|
||||
ExtractAllTermsReport.exportComplete=Unique Word Extraction Complete
|
||||
ExtractAllTermsReport.getName.text=Extract Unique Words
|
||||
# {0} - Number of extracted terms
|
||||
ExtractAllTermsReport.numberExtractedTerms=Extracted {0} terms...
|
||||
ExtractAllTermsReport.search.ingestInProgressBody=<html>Keyword Search Ingest is currently running.<br />Not all files have been indexed and unique word extraction might yield incomplete results.<br />Do you want to proceed with unique word extraction anyway?</html>
|
||||
ExtractAllTermsReport.search.noFilesInIdxMsg=No files are in index yet. If Solr keyword search indexing and Solr indexing were enabled, wait for ingest to complete.
|
||||
@ -22,13 +23,15 @@ ExtractAllTermsReport.search.noFilesInIdxMsg2=No files are in index yet. Re-inge
|
||||
ExtractAllTermsReport.search.searchIngestInProgressTitle=Keyword Search Ingest in Progress
|
||||
ExtractAllTermsReport.startExport=Starting Unique Word Extraction
|
||||
ExtractedContentPanel.setMarkup.panelTxt=<span style='font-style:italic'>Loading text... Please wait</span>
|
||||
# {0} - Content name
|
||||
ExtractedContentPanel.SetMarkup.progress.loading=Loading text for {0}
|
||||
ExtractedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving text.</span>
|
||||
ExtractedText.FileText=File Text
|
||||
ExtractedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span>
|
||||
ExtractedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No text available for this file.</span>
|
||||
GlobalEditListPanel.editKeyword.title=Edit Keyword
|
||||
GlobalEditListPanel.warning.text=Boundary characters ^ and $ do not match word boundaries. Consider\nreplacing with an explicit list of boundary characters, such as [ \\.,]
|
||||
GlobalEditListPanel.warning.title=Warning
|
||||
IndexedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving indexed text.</span>
|
||||
IndexedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span>
|
||||
IndexedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No indexed text for this file.</span>
|
||||
KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsLimitedOCR=Only process images which are over 100KB in size or extracted from a document. (Beta) (Requires Windows 64-bit)
|
||||
KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsOCR=Enable Optical Character Recognition (OCR) (Requires Windows 64-bit)
|
||||
KeywordSearchGlobalSettingsPanel.Title=Global Keyword Search Settings
|
||||
@ -49,7 +52,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found
|
||||
KeywordSearchResultFactory.query.exception.msg=Could not perform the query
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
|
||||
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
|
||||
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
|
||||
OpenIDE-Module-Name=KeywordSearch
|
||||
OptionsCategory_Name_KeywordSearchOptions=Keyword Search
|
||||
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search
|
||||
@ -91,7 +94,7 @@ AbstractKeywordSearchPerformer.search.emptyKeywordErrorBody=Keyword list is empt
|
||||
AbstractKeywordSearchPerformer.search.noFilesInIdxMsg=<html>No files are in index yet. <br />If Solr keyword search indexing was enabled, wait for ingest to complete</html>
|
||||
AbstractKeywordSearchPerformer.search.noFilesIdxdMsg=<html>No files were indexed.<br />Re-ingest the image with the Keyword Search Module and Solr indexing enabled. </html>
|
||||
ExtractedContentViewer.toolTip=Displays extracted text from files and keyword-search results. Requires Keyword Search ingest to be run on a file to activate this viewer.
|
||||
ExtractedContentViewer.getTitle=Indexed Text
|
||||
ExtractedContentViewer.getTitle=Extracted Text
|
||||
HighlightedMatchesSource.toString=Search Results
|
||||
Installer.reportPortError=Indexing server port {0} is not available. Check if your security software does not block {1} and consider changing {2} in {3} property file in the application user folder. Then try rebooting your system if another process was causing the conflict.
|
||||
Installer.reportStopPortError=Indexing server stop port {0} is not available. Consider changing {1} in {2} property file in the application user folder.
|
||||
@ -137,8 +140,6 @@ KeywordSearchIngestModule.init.onlyIdxKwSkipMsg=Only indexing will be done and k
|
||||
KeywordSearchIngestModule.doInBackGround.displayName=Periodic Keyword Search
|
||||
KeywordSearchIngestModule.doInBackGround.finalizeMsg=Finalizing
|
||||
KeywordSearchIngestModule.doInBackGround.pendingMsg=(Pending)
|
||||
RawText.FileText=File Text
|
||||
RawText.ResultText=Result Text
|
||||
SearchRunner.doInBackGround.cancelMsg=(Cancelling...)
|
||||
KeywordSearchIngestModule.postIndexSummary.knowFileHeaderLbl=Files with known types
|
||||
KeywordSearchIngestModule.postIndexSummary.fileGenStringsHead=Files with general strings extracted
|
||||
@ -224,6 +225,7 @@ KeywordSearchSettings.properties_options.text={0}_Options
|
||||
KeywordSearchSettings.propertiesNSRL.text={0}_NSRL
|
||||
KeywordSearchSettings.propertiesScripts.text={0}_Scripts
|
||||
NoOpenCoreException.err.noOpenSorlCore.msg=No currently open Solr core.
|
||||
# {0} - colelction name
|
||||
Server.deleteCore.exception.msg=Failed to delete Solr colelction {0}
|
||||
Server.exceptionMessage.unableToBackupCollection=Unable to backup Solr collection
|
||||
Server.exceptionMessage.unableToCreateCollection=Unable to create Solr collection
|
||||
@ -336,6 +338,8 @@ GlobalListsManagementPanel.copyListButton.text=Copy List
|
||||
GlobalListsManagementPanel.renameListButton.text=Edit List Name
|
||||
GlobalEditListPanel.editWordButton.text=Edit Keyword
|
||||
SolrConnectionCheck.Port=Invalid port number.
|
||||
SolrIndexedText.FileText=File Text
|
||||
SolrIndexedText.ResultText=Result Text
|
||||
SolrSearch.checkingForLatestIndex.msg=Looking for text index with latest Solr and schema version
|
||||
SolrSearch.complete.msg=Text index successfully opened
|
||||
SolrSearch.creatingNewIndex.msg=Creating new text index
|
||||
|
@ -565,7 +565,7 @@
|
||||
<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<org.sleuthkit.autopsy.keywordsearch.IndexedText>()" type="code"/>
|
||||
<Connection code="new javax.swing.DefaultComboBoxModel<org.sleuthkit.autopsy.keywordsearch.ExtractedText>()" type="code"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[150, 32767]"/>
|
||||
@ -579,7 +579,7 @@
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JComboBox<>()"/>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.keywordsearch.IndexedText>"/>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.keywordsearch.ExtractedText>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
|
@ -396,7 +396,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
textSourcePanel.add(jLabel1);
|
||||
textSourcePanel.add(fillerSmall12);
|
||||
|
||||
sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel<org.sleuthkit.autopsy.keywordsearch.IndexedText>());
|
||||
sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel<org.sleuthkit.autopsy.keywordsearch.ExtractedText>());
|
||||
sourceComboBox.setMaximumSize(new java.awt.Dimension(150, 32767));
|
||||
sourceComboBox.setMinimumSize(new java.awt.Dimension(150, 25));
|
||||
sourceComboBox.setPreferredSize(new java.awt.Dimension(150, 25));
|
||||
@ -443,7 +443,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
private javax.swing.JLabel pagesLabel;
|
||||
private javax.swing.JPopupMenu rightClickMenu;
|
||||
private javax.swing.JMenuItem selectAllMenuItem;
|
||||
private javax.swing.JComboBox<org.sleuthkit.autopsy.keywordsearch.IndexedText> sourceComboBox;
|
||||
private javax.swing.JComboBox<org.sleuthkit.autopsy.keywordsearch.ExtractedText> sourceComboBox;
|
||||
private javax.swing.JPanel textSourcePanel;
|
||||
private javax.swing.JPanel zoomPanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
@ -457,10 +457,10 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
* default)
|
||||
*
|
||||
* @param contentName The name of the content to be displayed
|
||||
* @param sources A list of IndexedText that have different 'views' of
|
||||
* the content.
|
||||
* @param sources A list of ExtractedText that have different 'views' of
|
||||
the content.
|
||||
*/
|
||||
final void setSources(String contentName, List<IndexedText> sources) {
|
||||
final void setSources(String contentName, List<ExtractedText> sources) {
|
||||
this.lastKnownAnchor = null;
|
||||
this.contentName = contentName;
|
||||
setPanelText(null, false);
|
||||
@ -480,8 +480,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
*
|
||||
* @return currently selected Source
|
||||
*/
|
||||
public IndexedText getSelectedSource() {
|
||||
return (IndexedText) sourceComboBox.getSelectedItem();
|
||||
public ExtractedText getSelectedSource() {
|
||||
return (ExtractedText) sourceComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
private void setPanelText(String text, boolean detectDirection) {
|
||||
@ -636,7 +636,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
*
|
||||
* @param source the selected source
|
||||
*/
|
||||
void updateControls(IndexedText source) {
|
||||
void updateControls(ExtractedText source) {
|
||||
updatePageControls(source);
|
||||
updateSearchControls(source);
|
||||
}
|
||||
@ -646,7 +646,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
*
|
||||
* @param source selected source
|
||||
*/
|
||||
void updatePageControls(IndexedText source) {
|
||||
void updatePageControls(ExtractedText source) {
|
||||
if (source == null) {
|
||||
enableNextPageControl(false);
|
||||
enablePrevPageControl(false);
|
||||
@ -668,7 +668,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
*
|
||||
* @param source selected source
|
||||
*/
|
||||
void updateSearchControls(IndexedText source) {
|
||||
void updateSearchControls(ExtractedText source) {
|
||||
//setup search controls
|
||||
if (source != null && source.isSearchable()) {
|
||||
updateCurrentMatchDisplay(source.currentItem());
|
||||
@ -688,7 +688,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
private void scrollToCurrentHit(final IndexedText source) {
|
||||
private void scrollToCurrentHit(final ExtractedText source) {
|
||||
if (source == null || !source.isSearchable()) {
|
||||
return;
|
||||
}
|
||||
@ -704,7 +704,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
* be invoked from GUI thread only.
|
||||
*/
|
||||
@NbBundle.Messages("ExtractedContentPanel.setMarkup.panelTxt=<span style='font-style:italic'>Loading text... Please wait</span>")
|
||||
private void setMarkup(IndexedText source) {
|
||||
private void setMarkup(ExtractedText source) {
|
||||
setPanelText(Bundle.ExtractedContentPanel_setMarkup_panelTxt(), false);
|
||||
new SetMarkupWorker(contentName, source).execute();
|
||||
}
|
||||
@ -718,11 +718,11 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
|
||||
private final String contentName;
|
||||
|
||||
private final IndexedText source;
|
||||
private final ExtractedText source;
|
||||
|
||||
private ProgressHandle progress;
|
||||
|
||||
SetMarkupWorker(String contentName, IndexedText source) {
|
||||
SetMarkupWorker(String contentName, ExtractedText source) {
|
||||
this.contentName = contentName;
|
||||
this.source = source;
|
||||
}
|
||||
@ -753,7 +753,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP
|
||||
}
|
||||
} catch (InterruptedException | CancellationException | ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting marked up text", ex); //NON-NLS
|
||||
setPanelText(Bundle.IndexedText_errorMessage_errorGettingText(), true);
|
||||
setPanelText(Bundle.ExtractedText_errorMessage_errorGettingText(), true);
|
||||
}
|
||||
|
||||
updateControls(source);
|
||||
|
308
KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedText.java
Executable file → Normal file
308
KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedText.java
Executable file → Normal file
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2023 Basis Technology Corp.
|
||||
* Copyright 2011-2023 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -18,217 +18,131 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import com.google.common.io.CharSource;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.textextractors.TextExtractor;
|
||||
import org.sleuthkit.autopsy.textextractors.TextExtractorFactory;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* A "source" for abstractFile viewer that displays "raw" extracted text for a
|
||||
* file. Only supports file types for which there are text extractors. Uses
|
||||
* chunking algorithm used by KeywordSearchIngestModule. The readers used in
|
||||
* chunking don't have ability to go backwards or to fast forward to a specific
|
||||
* offset. Therefore there is no way to scroll pages back, or to determine how
|
||||
* many total pages there are.
|
||||
* Interface to provide HTML text to display in ExtractedContentViewer. There is
|
||||
* 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. There is also an implementation that extracts text from
|
||||
* a file using one os TextExtractors.
|
||||
*/
|
||||
class ExtractedText implements IndexedText {
|
||||
|
||||
private int numPages = 0;
|
||||
private int currentPage = 0;
|
||||
private final AbstractFile abstractFile;
|
||||
private Chunker chunker = null;
|
||||
private static final Logger logger = Logger.getLogger(ExtractedText.class.getName());
|
||||
@NbBundle.Messages({
|
||||
"ExtractedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving text.</span>",
|
||||
"ExtractedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span>",
|
||||
"ExtractedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No text available for this file.</span>"
|
||||
})
|
||||
interface ExtractedText {
|
||||
|
||||
/**
|
||||
* Construct a new ExtractedText object for the given abstract file.
|
||||
* @return text optionally marked up with the subset of HTML that Swing
|
||||
* components can handle in their setText() method.
|
||||
*
|
||||
* @param file Abstract file.
|
||||
*/
|
||||
ExtractedText(AbstractFile file) throws TextExtractorFactory.NoTextExtractorFound, TextExtractor.InitReaderException {
|
||||
this.abstractFile = file;
|
||||
this.numPages = -1; // We don't know how many pages there are until we reach end of the document
|
||||
|
||||
TextExtractor extractor = TextExtractorFactory.getExtractor(abstractFile, null);
|
||||
|
||||
Map<String, String> extractedMetadata = new HashMap<>();
|
||||
Reader sourceReader = getTikaOrTextExtractor(extractor, abstractFile, extractedMetadata);
|
||||
|
||||
//Get a reader for the content of the given source
|
||||
BufferedReader reader = new BufferedReader(sourceReader);
|
||||
this.chunker = new Chunker(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentPage() {
|
||||
return this.currentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextPage() {
|
||||
if (chunker.hasNext()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPreviousPage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextPage() {
|
||||
if (!hasNextPage()) {
|
||||
throw new IllegalStateException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.nextPage.exception.msg"));
|
||||
}
|
||||
++currentPage;
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousPage() {
|
||||
if (!hasPreviousPage()) {
|
||||
throw new IllegalStateException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.previousPage.exception.msg"));
|
||||
}
|
||||
--currentPage;
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.hasNextItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPreviousItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.hasPreviousItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.nextItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.previousItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int currentItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.currentItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
try {
|
||||
return getContentText(currentPage);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Couldn't get extracted text", ex); //NON-NLS
|
||||
}
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"ExtractedText.FileText=File Text"})
|
||||
@Override
|
||||
public String toString() {
|
||||
return Bundle.ExtractedText_FileText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnchorPrefix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberHits() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberPages() {
|
||||
return numPages;
|
||||
}
|
||||
String getText();
|
||||
|
||||
/**
|
||||
* Extract text from abstractFile
|
||||
*
|
||||
* @param currentPage currently used page
|
||||
*
|
||||
* @return the extracted text
|
||||
* @return true if text is marked to be searchable
|
||||
*/
|
||||
private String getContentText(int currentPage) throws TextExtractor.InitReaderException, IOException, Exception {
|
||||
String indexedText;
|
||||
if (chunker.hasNext()) {
|
||||
Chunker.Chunk chunk = chunker.next();
|
||||
chunk.setChunkId(currentPage);
|
||||
boolean isSearchable();
|
||||
|
||||
if (chunker.hasException()) {
|
||||
logger.log(Level.WARNING, "Error chunking content from " + abstractFile.getId() + ": " + abstractFile.getName(), chunker.getException());
|
||||
throw chunker.getException();
|
||||
}
|
||||
/**
|
||||
* If searchable text, returns prefix of anchor, otherwise return empty
|
||||
* string
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getAnchorPrefix();
|
||||
|
||||
indexedText = chunk.toString();
|
||||
} else {
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
}
|
||||
/**
|
||||
* if searchable text, returns number of hits found and encoded in the text
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getNumberHits();
|
||||
|
||||
indexedText = EscapeUtil.escapeHtml(indexedText).trim();
|
||||
StringBuilder sb = new StringBuilder(indexedText.length() + 20);
|
||||
sb.append("<pre>").append(indexedText).append("</pre>"); //NON-NLS
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Reader getTikaOrTextExtractor(TextExtractor extractor, AbstractFile aFile,
|
||||
Map<String, String> extractedMetadata) throws TextExtractor.InitReaderException {
|
||||
|
||||
Reader fileText = extractor.getReader();
|
||||
Reader finalReader;
|
||||
try {
|
||||
Map<String, String> metadata = extractor.getMetadata();
|
||||
if (!metadata.isEmpty()) {
|
||||
// save the metadata map to use after this method is complete.
|
||||
extractedMetadata.putAll(metadata);
|
||||
}
|
||||
CharSource formattedMetadata = KeywordSearchIngestModule.getMetaDataCharSource(metadata);
|
||||
//Append the metadata to end of the file text
|
||||
finalReader = CharSource.concat(new CharSource() {
|
||||
//Wrap fileText reader for concatenation
|
||||
/**
|
||||
* @return title of text source
|
||||
*/
|
||||
@Override
|
||||
public Reader openStream() throws IOException {
|
||||
return fileText;
|
||||
}
|
||||
}, formattedMetadata).openStream();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("Could not format extracted metadata for file %s [id=%d]",
|
||||
aFile.getName(), aFile.getId()), ex);
|
||||
//Just send file text.
|
||||
finalReader = fileText;
|
||||
}
|
||||
//divide into chunks
|
||||
return finalReader;
|
||||
}
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* get number pages/chunks
|
||||
*
|
||||
* @return number pages
|
||||
*/
|
||||
int getNumberPages();
|
||||
|
||||
/**
|
||||
* get the current page number
|
||||
*
|
||||
* @return current page number
|
||||
*/
|
||||
int getCurrentPage();
|
||||
|
||||
/**
|
||||
* Check if has next page
|
||||
*
|
||||
* @return true, if next page exists in the source
|
||||
*/
|
||||
boolean hasNextPage();
|
||||
|
||||
/**
|
||||
* Move to next page
|
||||
*
|
||||
* @return the new page number
|
||||
*/
|
||||
int nextPage();
|
||||
|
||||
/**
|
||||
* Check if has previous page
|
||||
*
|
||||
* @return true, if previous page exists in the source
|
||||
*/
|
||||
boolean hasPreviousPage();
|
||||
|
||||
/**
|
||||
* Move to previous page
|
||||
*
|
||||
* @return the new page number
|
||||
*/
|
||||
int previousPage();
|
||||
|
||||
/**
|
||||
* Check if has next searchable item
|
||||
*
|
||||
* @return true, if next item exists in the source
|
||||
*/
|
||||
boolean hasNextItem();
|
||||
|
||||
/**
|
||||
* Move to next item
|
||||
*
|
||||
* @return the new item number
|
||||
*/
|
||||
int nextItem();
|
||||
|
||||
/**
|
||||
* Check if has previous item
|
||||
*
|
||||
* @return true, if previous item exists in the source
|
||||
*/
|
||||
boolean hasPreviousItem();
|
||||
|
||||
/**
|
||||
* Move to previous item
|
||||
*
|
||||
* @return the new item number
|
||||
*/
|
||||
int previousItem();
|
||||
|
||||
/**
|
||||
* Get the current item number, do not change anything
|
||||
*
|
||||
* @return the current item number
|
||||
*/
|
||||
int currentItem();
|
||||
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
|
||||
private ExtractedContentPanel panel;
|
||||
private volatile Node currentNode = null;
|
||||
private IndexedText currentSource = null;
|
||||
private ExtractedText currentSource = null;
|
||||
private FileTypeDetector fileTypeDetector = null;
|
||||
|
||||
// cache of last 10 solrHasFullyIndexedContent() requests sent to Solr.
|
||||
@ -118,7 +118,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
* Assemble a collection of all of the indexed text "sources" for the
|
||||
* node.
|
||||
*/
|
||||
List<IndexedText> sources = new ArrayList<>();
|
||||
List<ExtractedText> sources = new ArrayList<>();
|
||||
Lookup nodeLookup = node.getLookup();
|
||||
|
||||
/**
|
||||
@ -134,7 +134,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
* First, get text with highlighted hits if this node is for a search
|
||||
* result.
|
||||
*/
|
||||
IndexedText highlightedHitText = null;
|
||||
ExtractedText highlightedHitText = null;
|
||||
if (adHocQueryResult != null) {
|
||||
/*
|
||||
* The node is an ad hoc search result node.
|
||||
@ -172,7 +172,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
* Next, add the "raw" (not highlighted) text, if any, for any file
|
||||
* associated with the node.
|
||||
*/
|
||||
IndexedText rawContentText = null;
|
||||
ExtractedText rawContentText = null;
|
||||
if (file != null) {
|
||||
|
||||
// see if Solr has fully indexed this file
|
||||
@ -184,7 +184,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
// see if it's a file type for which we can extract text
|
||||
if (ableToExtractTextFromFile(file)) {
|
||||
try {
|
||||
rawContentText = new ExtractedText(file);
|
||||
rawContentText = new FileReaderExtractedText(file);
|
||||
sources.add(rawContentText);
|
||||
} catch (TextExtractorFactory.NoTextExtractorFound | TextExtractor.InitReaderException ex) {
|
||||
// do nothing
|
||||
@ -209,7 +209,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
* Finally, add the "raw" (not highlighted) text, if any, for any
|
||||
* artifact associated with the node.
|
||||
*/
|
||||
IndexedText rawArtifactText = null;
|
||||
ExtractedText rawArtifactText = null;
|
||||
try {
|
||||
rawArtifactText = getRawArtifactText(artifact);
|
||||
if (rawArtifactText != null) {
|
||||
@ -229,7 +229,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
}
|
||||
|
||||
// Push the text sources into the panel.
|
||||
for (IndexedText source : sources) {
|
||||
for (ExtractedText source : sources) {
|
||||
int currentPage = source.getCurrentPage();
|
||||
if (currentPage == 0 && source.hasNextPage()) {
|
||||
source.nextPage();
|
||||
@ -245,8 +245,8 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
|
||||
}
|
||||
|
||||
private IndexedText getRawArtifactText(BlackboardArtifact artifact) throws TskCoreException, NoCurrentCaseException {
|
||||
IndexedText rawArtifactText = null;
|
||||
private ExtractedText getRawArtifactText(BlackboardArtifact artifact) throws TskCoreException, NoCurrentCaseException {
|
||||
ExtractedText rawArtifactText = null;
|
||||
if (null != artifact) {
|
||||
/*
|
||||
* For keyword hit artifacts, add the text of the artifact that hit,
|
||||
@ -273,7 +273,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
return rawArtifactText;
|
||||
}
|
||||
|
||||
static private IndexedText getAccountsText(Content content, Lookup nodeLookup) throws TskCoreException {
|
||||
static private ExtractedText getAccountsText(Content content, Lookup nodeLookup) throws TskCoreException {
|
||||
/*
|
||||
* get all the credit card artifacts
|
||||
*/
|
||||
@ -287,7 +287,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
}
|
||||
|
||||
private void scrollToCurrentHit() {
|
||||
final IndexedText source = panel.getSelectedSource();
|
||||
final ExtractedText source = panel.getSelectedSource();
|
||||
if (source == null || !source.isSearchable()) {
|
||||
return;
|
||||
}
|
||||
@ -431,10 +431,10 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
* panel hasn't been created yet)
|
||||
*
|
||||
* @param contentName The name of the content to be displayed
|
||||
* @param sources A list of IndexedText that have different 'views' of
|
||||
* the content.
|
||||
* @param sources A list of ExtractedText that have different 'views' of
|
||||
the content.
|
||||
*/
|
||||
private void setPanel(String contentName, List<IndexedText> sources) {
|
||||
private void setPanel(String contentName, List<ExtractedText> sources) {
|
||||
if (panel != null) {
|
||||
panel.setSources(contentName, sources);
|
||||
}
|
||||
@ -525,7 +525,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
IndexedText source = panel.getSelectedSource();
|
||||
ExtractedText source = panel.getSelectedSource();
|
||||
if (source == null) {
|
||||
// reset
|
||||
panel.updateControls(null);
|
||||
@ -568,7 +568,7 @@ public class ExtractedTextViewer implements TextViewer {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
IndexedText source = panel.getSelectedSource();
|
||||
ExtractedText source = panel.getSelectedSource();
|
||||
final boolean hasPreviousItem = source.hasPreviousItem();
|
||||
final boolean hasPreviousPage = source.hasPreviousPage();
|
||||
int indexVal;
|
||||
|
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2023 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 com.google.common.io.CharSource;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.textextractors.TextExtractor;
|
||||
import org.sleuthkit.autopsy.textextractors.TextExtractorFactory;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* A "source" for abstractFile viewer that displays "raw" extracted text for a
|
||||
* file. Only supports file types for which there are text extractors. Uses
|
||||
* chunking algorithm used by KeywordSearchIngestModule. The readers used in
|
||||
* chunking don't have ability to go backwards or to fast forward to a specific
|
||||
* offset. Therefore there is no way to scroll pages back, or to determine how
|
||||
* many total pages there are.
|
||||
*/
|
||||
class FileReaderExtractedText implements ExtractedText {
|
||||
|
||||
private int numPages = 0;
|
||||
private int currentPage = 0;
|
||||
private final AbstractFile abstractFile;
|
||||
private Chunker chunker = null;
|
||||
private static final Logger logger = Logger.getLogger(FileReaderExtractedText.class.getName());
|
||||
|
||||
/**
|
||||
* Construct a new ExtractedText object for the given abstract file.
|
||||
*
|
||||
* @param file Abstract file.
|
||||
*/
|
||||
FileReaderExtractedText(AbstractFile file) throws TextExtractorFactory.NoTextExtractorFound, TextExtractor.InitReaderException {
|
||||
this.abstractFile = file;
|
||||
this.numPages = -1; // We don't know how many pages there are until we reach end of the document
|
||||
|
||||
TextExtractor extractor = TextExtractorFactory.getExtractor(abstractFile, null);
|
||||
|
||||
Map<String, String> extractedMetadata = new HashMap<>();
|
||||
Reader sourceReader = getTikaOrTextExtractor(extractor, abstractFile, extractedMetadata);
|
||||
|
||||
//Get a reader for the content of the given source
|
||||
BufferedReader reader = new BufferedReader(sourceReader);
|
||||
this.chunker = new Chunker(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentPage() {
|
||||
return this.currentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextPage() {
|
||||
if (chunker.hasNext()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPreviousPage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextPage() {
|
||||
if (!hasNextPage()) {
|
||||
throw new IllegalStateException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.nextPage.exception.msg"));
|
||||
}
|
||||
++currentPage;
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousPage() {
|
||||
if (!hasPreviousPage()) {
|
||||
throw new IllegalStateException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.previousPage.exception.msg"));
|
||||
}
|
||||
--currentPage;
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.hasNextItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPreviousItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.hasPreviousItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.nextItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.previousItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int currentItem() {
|
||||
throw new UnsupportedOperationException(
|
||||
NbBundle.getMessage(this.getClass(), "ExtractedContentViewer.currentItem.exception.msg"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
try {
|
||||
return getContentText(currentPage);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Couldn't get extracted text", ex); //NON-NLS
|
||||
}
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"ExtractedText.FileText=File Text"})
|
||||
@Override
|
||||
public String toString() {
|
||||
return Bundle.ExtractedText_FileText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnchorPrefix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberHits() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberPages() {
|
||||
return numPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract text from abstractFile
|
||||
*
|
||||
* @param currentPage currently used page
|
||||
*
|
||||
* @return the extracted text
|
||||
*/
|
||||
private String getContentText(int currentPage) throws TextExtractor.InitReaderException, IOException, Exception {
|
||||
String indexedText;
|
||||
if (chunker.hasNext()) {
|
||||
Chunker.Chunk chunk = chunker.next();
|
||||
chunk.setChunkId(currentPage);
|
||||
|
||||
if (chunker.hasException()) {
|
||||
logger.log(Level.WARNING, "Error chunking content from " + abstractFile.getId() + ": " + abstractFile.getName(), chunker.getException());
|
||||
throw chunker.getException();
|
||||
}
|
||||
|
||||
indexedText = chunk.toString();
|
||||
} else {
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
|
||||
indexedText = EscapeUtil.escapeHtml(indexedText).trim();
|
||||
StringBuilder sb = new StringBuilder(indexedText.length() + 20);
|
||||
sb.append("<pre>").append(indexedText).append("</pre>"); //NON-NLS
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Reader getTikaOrTextExtractor(TextExtractor extractor, AbstractFile aFile,
|
||||
Map<String, String> extractedMetadata) throws TextExtractor.InitReaderException {
|
||||
|
||||
Reader fileText = extractor.getReader();
|
||||
Reader finalReader;
|
||||
try {
|
||||
Map<String, String> metadata = extractor.getMetadata();
|
||||
if (!metadata.isEmpty()) {
|
||||
// save the metadata map to use after this method is complete.
|
||||
extractedMetadata.putAll(metadata);
|
||||
}
|
||||
CharSource formattedMetadata = KeywordSearchIngestModule.getMetaDataCharSource(metadata);
|
||||
//Append the metadata to end of the file text
|
||||
finalReader = CharSource.concat(new CharSource() {
|
||||
//Wrap fileText reader for concatenation
|
||||
@Override
|
||||
public Reader openStream() throws IOException {
|
||||
return fileText;
|
||||
}
|
||||
}, formattedMetadata).openStream();
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("Could not format extracted metadata for file %s [id=%d]",
|
||||
aFile.getName(), aFile.getId()), ex);
|
||||
//Just send file text.
|
||||
finalReader = fileText;
|
||||
}
|
||||
//divide into chunks
|
||||
return finalReader;
|
||||
}
|
||||
|
||||
}
|
@ -52,7 +52,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* Highlights hits for a given document. Knows about pages and such for the
|
||||
* content viewer.
|
||||
*/
|
||||
class HighlightedText implements IndexedText {
|
||||
class HighlightedText implements ExtractedText {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HighlightedText.class.getName());
|
||||
|
||||
@ -475,7 +475,7 @@ class HighlightedText implements IndexedText {
|
||||
return "<html><pre>" + highlightedContent + "</pre></html>"; //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
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,7 +519,7 @@ class HighlightedText implements IndexedText {
|
||||
*/
|
||||
static String attemptManualHighlighting(SolrDocumentList solrDocumentList, String highlightField, Collection<String> keywords) {
|
||||
if (solrDocumentList.isEmpty()) {
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
|
||||
// It doesn't make sense for there to be more than a single document in
|
||||
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011-2023 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 org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
* Interface to provide HTML text to display in ExtractedContentViewer. There is
|
||||
* 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. There is also an implementation that extracts text from
|
||||
* a file using one os TextExtractors.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"IndexedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving text.</span>",
|
||||
"IndexedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span>",
|
||||
"IndexedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No text available for this file.</span>"
|
||||
})
|
||||
interface IndexedText {
|
||||
|
||||
/**
|
||||
* @return text optionally marked up with the subset of HTML that Swing
|
||||
* components can handle in their setText() method.
|
||||
*
|
||||
*/
|
||||
String getText();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if text is marked to be searchable
|
||||
*/
|
||||
boolean isSearchable();
|
||||
|
||||
/**
|
||||
* If searchable text, returns prefix of anchor, otherwise return empty
|
||||
* string
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getAnchorPrefix();
|
||||
|
||||
/**
|
||||
* if searchable text, returns number of hits found and encoded in the text
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getNumberHits();
|
||||
|
||||
/**
|
||||
* @return title of text source
|
||||
*/
|
||||
@Override
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* get number pages/chunks
|
||||
*
|
||||
* @return number pages
|
||||
*/
|
||||
int getNumberPages();
|
||||
|
||||
/**
|
||||
* get the current page number
|
||||
*
|
||||
* @return current page number
|
||||
*/
|
||||
int getCurrentPage();
|
||||
|
||||
/**
|
||||
* Check if has next page
|
||||
*
|
||||
* @return true, if next page exists in the source
|
||||
*/
|
||||
boolean hasNextPage();
|
||||
|
||||
/**
|
||||
* Move to next page
|
||||
*
|
||||
* @return the new page number
|
||||
*/
|
||||
int nextPage();
|
||||
|
||||
/**
|
||||
* Check if has previous page
|
||||
*
|
||||
* @return true, if previous page exists in the source
|
||||
*/
|
||||
boolean hasPreviousPage();
|
||||
|
||||
/**
|
||||
* Move to previous page
|
||||
*
|
||||
* @return the new page number
|
||||
*/
|
||||
int previousPage();
|
||||
|
||||
/**
|
||||
* Check if has next searchable item
|
||||
*
|
||||
* @return true, if next item exists in the source
|
||||
*/
|
||||
boolean hasNextItem();
|
||||
|
||||
/**
|
||||
* Move to next item
|
||||
*
|
||||
* @return the new item number
|
||||
*/
|
||||
int nextItem();
|
||||
|
||||
/**
|
||||
* Check if has previous item
|
||||
*
|
||||
* @return true, if previous item exists in the source
|
||||
*/
|
||||
boolean hasPreviousItem();
|
||||
|
||||
/**
|
||||
* Move to previous item
|
||||
*
|
||||
* @return the new item number
|
||||
*/
|
||||
int previousItem();
|
||||
|
||||
/**
|
||||
* Get the current item number, do not change anything
|
||||
*
|
||||
* @return the current item number
|
||||
*/
|
||||
int currentItem();
|
||||
|
||||
}
|
@ -32,7 +32,7 @@ import org.sleuthkit.datamodel.TskData;
|
||||
* A "source" for the extracted content viewer that displays "raw" (not
|
||||
* highlighted) Solr indexed text for a file or an artifact.
|
||||
*/
|
||||
class SolrIndexedText implements IndexedText {
|
||||
class SolrIndexedText implements ExtractedText {
|
||||
|
||||
private int numPages = 0;
|
||||
private int currentPage = 0;
|
||||
@ -152,7 +152,7 @@ class SolrIndexedText implements IndexedText {
|
||||
} catch (SolrServerException | NoOpenCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Couldn't get extracted text", ex); //NON-NLS
|
||||
}
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
@ -236,11 +236,11 @@ class SolrIndexedText implements IndexedText {
|
||||
//we know it's AbstractFile, but do quick check to make sure if we index other objects in future
|
||||
boolean isKnown = TskData.FileKnown.KNOWN.equals(((AbstractFile) content).getKnown());
|
||||
if (isKnown && KeywordSearchSettings.getSkipKnown()) {
|
||||
msg = Bundle.IndexedText_warningMessage_knownFile();
|
||||
msg = Bundle.ExtractedText_warningMessage_knownFile();
|
||||
}
|
||||
}
|
||||
if (msg == null) {
|
||||
msg = Bundle.IndexedText_warningMessage_noTextAvailable();
|
||||
msg = Bundle.ExtractedText_warningMessage_noTextAvailable();
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
@ -250,12 +250,12 @@ class SolrIndexedText implements IndexedText {
|
||||
String indexedText = solrServer.getSolrContent(this.objectId, chunkId);
|
||||
if (indexedText == null) {
|
||||
if (content instanceof AbstractFile) {
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
} else {
|
||||
return Bundle.IndexedText_warningMessage_noTextAvailable();
|
||||
return Bundle.ExtractedText_warningMessage_noTextAvailable();
|
||||
}
|
||||
} else if (indexedText.isEmpty()) {
|
||||
return Bundle.IndexedText_warningMessage_noTextAvailable();
|
||||
return Bundle.ExtractedText_warningMessage_noTextAvailable();
|
||||
}
|
||||
|
||||
indexedText = EscapeUtil.escapeHtml(indexedText).trim();
|
||||
@ -276,7 +276,7 @@ class SolrIndexedText implements IndexedText {
|
||||
private String getArtifactText() throws NoOpenCoreException, SolrServerException {
|
||||
String indexedText = KeywordSearch.getServer().getSolrContent(this.objectId, 1);
|
||||
if (indexedText == null || indexedText.isEmpty()) {
|
||||
return Bundle.IndexedText_errorMessage_errorGettingText();
|
||||
return Bundle.ExtractedText_errorMessage_errorGettingText();
|
||||
}
|
||||
|
||||
indexedText = EscapeUtil.escapeHtml(indexedText).trim();
|
||||
|
Loading…
x
Reference in New Issue
Block a user