19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.awt.Component;
22 import java.awt.Cursor;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.beans.PropertyChangeEvent;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.EnumSet;
29 import java.util.LinkedHashMap;
30 import java.util.List;
32 import java.util.logging.Level;
33 import org.apache.tika.mime.MimeTypes;
34 import org.openide.nodes.Node;
35 import org.openide.util.Lookup;
36 import org.openide.util.NbBundle;
37 import org.openide.util.lookup.ServiceProvider;
49 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
50 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
52 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
62 @ServiceProvider(service = TextViewer.class, position = 2)
67 private static final BlackboardAttribute.Type TSK_ASSOCIATED_ARTIFACT_TYPE =
new BlackboardAttribute.Type(TSK_ASSOCIATED_ARTIFACT);
68 private static final BlackboardAttribute.Type TSK_ACCOUNT_TYPE =
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE);
70 private ExtractedContentPanel
panel;
71 private volatile Node currentNode = null;
72 private ExtractedText currentSource = null;
88 logger.log(Level.SEVERE,
"Failed to initialize FileTypeDetector", ex);
116 if (node.equals(currentNode)) {
126 List<ExtractedText> sources =
new ArrayList<>();
127 Lookup nodeLookup = node.getLookup();
133 AdHocQueryResult adHocQueryResult = nodeLookup.lookup(AdHocQueryResult.class);
134 AbstractFile file = nodeLookup.lookup(AbstractFile.class);
135 BlackboardArtifact artifact = nodeLookup.lookup(BlackboardArtifact.class);
136 Report report = nodeLookup.lookup(Report.class);
142 ExtractedText highlightedHitText = null;
143 if (adHocQueryResult != null) {
147 highlightedHitText =
new HighlightedText(adHocQueryResult.getSolrObjectId(), adHocQueryResult.getResults());
148 }
else if (artifact != null) {
149 if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()) {
154 highlightedHitText =
new HighlightedText(artifact);
155 }
catch (TskCoreException ex) {
156 logger.log(Level.SEVERE,
"Failed to create HighlightedText for " + artifact, ex);
158 }
else if (artifact.getArtifactTypeID() == TSK_ACCOUNT.getTypeID() && file != null) {
160 BlackboardAttribute attribute = artifact.getAttribute(TSK_ACCOUNT_TYPE);
161 if (attribute != null && Account.Type.CREDIT_CARD.getTypeName().equals(attribute.getValueString())) {
165 highlightedHitText = getAccountsText(file, nodeLookup);
167 }
catch (TskCoreException ex) {
168 logger.log(Level.SEVERE,
"Failed to create AccountsText for " + file, ex);
172 if (highlightedHitText != null) {
173 sources.add(highlightedHitText);
180 ExtractedText rawContentText = null;
184 if (solrHasFullyIndexedContent(file.getId())) {
185 rawContentText =
new SolrIndexedText(file, file.getId());
186 sources.add(rawContentText);
190 if (ableToExtractTextFromFile(file)) {
192 rawContentText =
new FileReaderExtractedText(file);
193 sources.add(rawContentText);
205 if (report != null) {
207 if (solrHasFullyIndexedContent(report.getId())) {
208 rawContentText =
new SolrIndexedText(report, report.getId());
209 sources.add(rawContentText);
217 ExtractedText rawArtifactText = null;
219 rawArtifactText = getRawArtifactText(artifact);
220 if (rawArtifactText != null) {
221 sources.add(rawArtifactText);
224 logger.log(Level.SEVERE,
"Error creating RawText for " + file, ex);
228 if (highlightedHitText != null) {
229 currentSource = highlightedHitText;
230 }
else if (rawArtifactText != null) {
231 currentSource = rawArtifactText;
233 currentSource = rawContentText;
237 for (ExtractedText source : sources) {
238 int currentPage = source.getCurrentPage();
239 if (currentPage == 0 && source.hasNextPage()) {
243 panel.updateControls(currentSource);
245 String contentName =
"";
247 contentName = file.getName();
249 setPanel(contentName, sources);
254 ExtractedText rawArtifactText = null;
255 if (null != artifact) {
260 if (artifact.getArtifactTypeID() == TSK_KEYWORD_HIT.getTypeID()
261 || artifact.getArtifactTypeID() == TSK_ACCOUNT.getTypeID()) {
263 BlackboardAttribute attribute = artifact.getAttribute(TSK_ASSOCIATED_ARTIFACT_TYPE);
264 if (attribute != null) {
265 long artifactId = attribute.getValueLong();
267 if (solrHasFullyIndexedContent(associatedArtifact.getArtifactID())) {
268 rawArtifactText =
new SolrIndexedText(associatedArtifact, associatedArtifact.getArtifactID());
273 if (solrHasFullyIndexedContent(artifact.getArtifactID())) {
274 rawArtifactText =
new SolrIndexedText(artifact, artifact.getArtifactID());
278 return rawArtifactText;
281 static private ExtractedText
getAccountsText(Content content, Lookup nodeLookup)
throws TskCoreException {
286 Collection<? extends BlackboardArtifact> artifacts = nodeLookup.lookupAll(BlackboardArtifact.class);
287 artifacts = (artifacts == null || artifacts.isEmpty())
288 ? content.getArtifacts(TSK_ACCOUNT)
291 return new AccountsText(content.getId(), artifacts);
295 final ExtractedText source = panel.getSelectedSource();
296 if (source == null || !source.isSearchable()) {
300 panel.scrollToAnchor(source.getAnchorPrefix() + Integer.toString(source.currentItem()));
305 return NbBundle.getMessage(this.getClass(),
"ExtractedContentViewer.getTitle");
310 return NbBundle.getMessage(this.getClass(),
"ExtractedContentViewer.toolTip");
321 panel =
new ExtractedContentPanel();
333 panel.resetDisplay();
335 currentSource = null;
336 panel.updateControls(currentSource);
349 AdHocQueryResult adHocQueryResult = node.getLookup().lookup(AdHocQueryResult.class);
350 if (adHocQueryResult != null) {
359 BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
360 if (artifact != null) {
361 final int artifactTypeID = artifact.getArtifactTypeID();
362 if (artifactTypeID == TSK_KEYWORD_HIT.getTypeID()) {
364 }
else if (artifactTypeID == TSK_ACCOUNT.getTypeID()) {
366 BlackboardAttribute attribute = artifact.getAttribute(TSK_ACCOUNT_TYPE);
367 if (attribute != null && Account.Type.CREDIT_CARD.getTypeName().equals(attribute.getValueString())) {
370 }
catch (TskCoreException ex) {
376 logger.log(Level.SEVERE,
"Error getting TSK_ACCOUNT_TYPE attribute from artifact " + artifact.getArtifactID(), ex);
387 AbstractFile file = node.getLookup().lookup(AbstractFile.class);
391 if (solrHasFullyIndexedContent(file.getId())) {
397 if (ableToExtractTextFromFile(file)) {
408 if (artifact != null) {
409 return solrHasFullyIndexedContent(artifact.getArtifactID());
417 Report report = node.getLookup().lookup(Report.class);
418 if (report != null) {
419 return solrHasFullyIndexedContent(report.getId());
442 private void setPanel(String contentName, List<ExtractedText> sources) {
444 panel.setSources(contentName, sources);
468 if (solrServer.coreIsOpen() ==
false) {
477 return isFullyIndexed;
479 logger.log(Level.SEVERE,
"Error querying Solr server", ex);
496 TskData.TSK_DB_FILES_TYPE_ENUM fileType = file.getType();
498 if (fileType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR)) {
502 if ((fileType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
503 || fileType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))
504 || (fileType.equals(TskData.TSK_DB_FILES_TYPE_ENUM.CARVED))) {
508 final long size = file.getSize();
509 if (file.isDir() || size == 0) {
513 String mimeType = fileTypeDetector.
getMIMEType(file).trim().toLowerCase();
519 if (MimeTypes.OCTET_STREAM.equals(mimeType)) {
527 FileReaderExtractedText tmp =
new FileReaderExtractedText(file);
542 ExtractedText source = panel.getSelectedSource();
543 if (source == null) {
545 panel.updateControls(null);
548 final boolean hasNextItem = source.hasNextItem();
549 final boolean hasNextPage = source.hasNextPage();
551 if (hasNextItem || hasNextPage) {
555 indexVal = source.currentItem();
557 indexVal = source.nextItem();
561 panel.scrollToAnchor(source.getAnchorPrefix() + Integer.toString(indexVal));
564 panel.updateCurrentMatchDisplay(source.currentItem());
565 panel.updateTotaMatcheslDisplay(source.getNumberHits());
568 if (!source.hasNextItem() && !source.hasNextPage()) {
569 panel.enableNextMatchControl(
false);
571 if (source.hasPreviousItem() || source.hasPreviousPage()) {
572 panel.enablePrevMatchControl(
true);
585 ExtractedText source = panel.getSelectedSource();
586 final boolean hasPreviousItem = source.hasPreviousItem();
587 final boolean hasPreviousPage = source.hasPreviousPage();
589 if (hasPreviousItem || hasPreviousPage) {
590 if (!hasPreviousItem) {
593 indexVal = source.currentItem();
595 indexVal = source.previousItem();
599 panel.scrollToAnchor(source.getAnchorPrefix() + Integer.toString(indexVal));
602 panel.updateCurrentMatchDisplay(source.currentItem());
603 panel.updateTotaMatcheslDisplay(source.getNumberHits());
606 if (!source.hasPreviousItem() && !source.hasPreviousPage()) {
607 panel.enablePrevMatchControl(
false);
609 if (source.hasNextItem() || source.hasNextPage()) {
610 panel.enableNextMatchControl(
true);
623 currentSource = panel.getSelectedSource();
625 if (currentSource == null) {
630 panel.updateControls(currentSource);
636 if (currentSource == null) {
637 panel.updateControls(null);
641 if (currentSource.hasNextPage()) {
642 currentSource.nextPage();
645 panel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
646 panel.refreshCurrentMarkup();
647 panel.setCursor(null);
650 panel.updateCurrentPageDisplay(currentSource.getCurrentPage());
653 scrollToCurrentHit();
656 if (!currentSource.hasNextPage()) {
657 panel.enableNextPageControl(
false);
659 if (currentSource.hasPreviousPage()) {
660 panel.enablePrevPageControl(
true);
663 panel.updateSearchControls(currentSource);
669 if (currentSource == null) {
670 panel.updateControls(null);
674 if (currentSource.hasPreviousPage()) {
675 currentSource.previousPage();
678 panel.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
679 panel.refreshCurrentMarkup();
680 panel.setCursor(null);
683 panel.updateCurrentPageDisplay(currentSource.getCurrentPage());
686 scrollToCurrentHit();
689 if (!currentSource.hasPreviousPage()) {
690 panel.enablePrevPageControl(
false);
692 if (currentSource.hasNextPage()) {
693 panel.enableNextPageControl(
true);
696 panel.updateSearchControls(currentSource);
729 private static final int CACHE_SIZE = 10;
730 private final LinkedHashMap<Long, Boolean>
cache;
733 this.cache =
new LinkedHashMap<Long, Boolean>(CACHE_SIZE, 0.75f,
true) {
735 protected boolean removeEldestEntry(Map.Entry<Long, Boolean> eldest) {
736 return size() > CACHE_SIZE;
742 cache.put(key, value);
746 return cache.get(key);
754 return cache.containsKey(key);
boolean queryIsFullyIndexed(long contentID)
static synchronized Server getServer()
String getMIMEType(AbstractFile file)
SleuthkitCase getSleuthkitCase()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)