19 package org.sleuthkit.autopsy.datamodel;
21 import com.google.common.cache.Cache;
22 import com.google.common.cache.CacheBuilder;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 import java.lang.ref.WeakReference;
26 import java.text.MessageFormat;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.EnumSet;
30 import java.util.LinkedHashMap;
31 import java.util.List;
33 import java.util.MissingResourceException;
35 import java.util.concurrent.ExecutionException;
36 import java.util.concurrent.TimeUnit;
37 import java.util.logging.Level;
38 import java.util.stream.Collectors;
39 import javax.swing.Action;
40 import org.apache.commons.lang3.StringUtils;
41 import org.apache.commons.lang3.tuple.Pair;
42 import org.openide.nodes.Sheet;
43 import org.openide.util.Lookup;
44 import org.openide.util.NbBundle;
45 import org.openide.util.WeakListeners;
46 import org.openide.util.lookup.Lookups;
73 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
75 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
95 private static Cache<Long, Content>
contentCache = CacheBuilder.newBuilder()
96 .expireAfterWrite(1, TimeUnit.MINUTES).
109 BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
110 BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
111 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
112 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(),};
118 BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),};
120 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
122 public void propertyChange(PropertyChangeEvent evt) {
123 String eventType = evt.getPropertyName();
126 if (event.getAddedTag().getArtifact().equals(artifact)) {
131 if (event.getDeletedTagInfo().getArtifactID() == artifact.getArtifactID()) {
136 if (event.getAddedTag().getContent().equals(associated)) {
141 if (event.getDeletedTagInfo().getContentID() == associated.getId()) {
146 if (event.getContentID() == associated.getId()) {
150 if (evt.getNewValue() == null) {
153 contentCache.invalidateAll();
156 SCOData scoData = (SCOData) evt.getNewValue();
157 if (scoData.getScoreAndDescription() != null) {
158 updateSheet(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
160 if (scoData.getComment() != null) {
161 updateSheet(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(),
NO_DESCR, scoData.getComment()));
163 if (scoData.getCountAndDescription() != null) {
164 updateSheet(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
178 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(pcl, null);
194 for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
195 if ((lookupContent != null) && (!(lookupContent instanceof BlackboardArtifact))) {
196 this.associated = lookupContent;
201 this.
setName(Long.toString(artifact.getArtifactID()));
203 this.setIconBaseWithExtension(iconPath);
242 "BlackboardArtifactNode.getAction.errorTitle=Error getting actions",
243 "BlackboardArtifactNode.getAction.resultErrorMessage=There was a problem getting actions for the selected result."
244 +
" The 'View Result in Timeline' action will not be available.",
245 "BlackboardArtifactNode.getAction.linkedFileMessage=There was a problem getting actions for the selected result. "
246 +
" The 'View File in Timeline' action will not be available."})
248 List<Action> actionsList =
new ArrayList<>();
249 actionsList.addAll(Arrays.asList(super.getActions(context)));
250 AbstractFile file = getLookup().lookup(AbstractFile.class);
257 }
catch (TskCoreException ex) {
258 logger.log(Level.SEVERE, MessageFormat.format(
"Error getting arttribute(s) from blackboard artifact{0}.", artifact.getArtifactID()), ex);
259 MessageNotifyUtil.
Notify.
error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_resultErrorMessage());
264 AbstractFile c = findLinked(artifact);
268 }
catch (TskCoreException ex) {
269 logger.log(Level.SEVERE, MessageFormat.format(
"Error getting linked file from blackboard artifact{0}.", artifact.getArtifactID()), ex);
270 MessageNotifyUtil.
Notify.
error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_linkedFileMessage());
278 return actionsList.toArray(
new Action[actionsList.size()]);
281 @NbBundle.Messages({
"# {0} - artifactDisplayName",
"BlackboardArtifactNode.displayName.artifact={0} Artifact"})
288 String displayName =
"";
294 && (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()
295 || artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID())) {
297 for (BlackboardAttribute attribute : artifact.getAttributes()) {
298 if (attribute.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
300 if (associatedArtifact != null) {
301 if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
302 artifact.getDisplayName();
304 displayName = NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.displayName.artifact", associatedArtifact.getDisplayName());
314 if (displayName.isEmpty() && artifact != null) {
315 displayName = artifact.getName();
330 if (associated != null) {
331 srcName = associated.getName();
337 "BlackboardArtifactNode.createSheet.artifactType.displayName=Result Type",
338 "BlackboardArtifactNode.createSheet.artifactType.name=Result Type",
339 "BlackboardArtifactNode.createSheet.artifactDetails.displayName=Result Details",
340 "BlackboardArtifactNode.createSheet.artifactDetails.name=Result Details",
341 "BlackboardArtifactNode.createSheet.artifactMD5.displayName=MD5 Hash",
342 "BlackboardArtifactNode.createSheet.artifactMD5.name=MD5 Hash",
343 "BlackboardArtifactNode.createSheet.fileSize.name=Size",
344 "BlackboardArtifactNode.createSheet.fileSize.displayName=Size",
345 "BlackboardArtifactNode.createSheet.path.displayName=Path",
346 "BlackboardArtifactNode.createSheet.path.name=Path"})
350 Sheet sheet = super.createSheet();
351 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
352 if (sheetSet == null) {
353 sheetSet = Sheet.createPropertiesSet();
357 Map<String, Object> map =
new LinkedHashMap<>();
361 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.srcFile.displayName"),
367 sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(),
VALUE_LOADING,
""));
368 sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(),
VALUE_LOADING,
""));
370 sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(),
VALUE_LOADING,
""));
373 backgroundTasksPool.submit(
new GetSCOTask(
374 new WeakReference<>(
this), weakPcl));
377 if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
379 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
380 if (attribute != null) {
383 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.artifactType.displayName"),
385 associatedArtifact.getDisplayName()));
387 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.artifactDetails.displayName"),
389 associatedArtifact.getShortDescription()));
396 for (Map.Entry<String, Object> entry : map.entrySet()) {
404 if (customProperties != null) {
410 final int artifactTypeId = artifact.getArtifactTypeID();
413 if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) {
415 String actualMimeType =
"";
416 if (associated instanceof AbstractFile) {
417 AbstractFile af = (AbstractFile) associated;
418 ext = af.getNameExtension();
419 actualMimeType = af.getMIMEType();
420 if (actualMimeType == null) {
430 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.mimeType.displayName"),
435 if (Arrays.asList(SHOW_UNIQUE_PATH).contains(artifactTypeId)) {
436 String sourcePath =
"";
438 sourcePath = associated.getUniquePath();
439 }
catch (TskCoreException ex) {
440 logger.log(Level.WARNING,
"Failed to get unique path from: {0}", associated.getName());
443 if (sourcePath.isEmpty() ==
false) {
446 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.filePath.displayName"),
451 if (Arrays.asList(SHOW_FILE_METADATA).contains(artifactTypeId)) {
452 AbstractFile file = associated instanceof AbstractFile ? (AbstractFile) associated : null;
454 NbBundle.getMessage(
BlackboardArtifactNode.class,
"ContentTagNode.createSheet.fileModifiedTime.displayName"),
458 NbBundle.getMessage(
BlackboardArtifactNode.class,
"ContentTagNode.createSheet.fileChangedTime.displayName"),
462 NbBundle.getMessage(
BlackboardArtifactNode.class,
"ContentTagNode.createSheet.fileAccessedTime.displayName"),
466 NbBundle.getMessage(
BlackboardArtifactNode.class,
"ContentTagNode.createSheet.fileCreatedTime.displayName"),
472 associated.getSize()));
473 sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(),
474 Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(),
476 file == null ?
"" : StringUtils.defaultString(file.getMd5Hash())));
479 String dataSourceStr =
"";
481 Content dataSource = associated.getDataSource();
482 if (dataSource != null) {
483 dataSourceStr = dataSource.getName();
487 }
catch (TskCoreException ex) {
488 logger.log(Level.WARNING,
"Failed to get image name from {0}", associated.getName());
491 if (dataSourceStr.isEmpty() ==
false) {
494 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.dataSrc.displayName"),
501 if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()) {
505 if (associated instanceof AbstractFile) {
506 AbstractFile af = (AbstractFile) associated;
509 path = af.getUniquePath();
510 }
catch (TskCoreException ex) {
511 path = af.getParentPath();
515 NbBundle.getMessage(
BlackboardArtifactNode.class,
"BlackboardArtifactNode.createSheet.fileSize.displayName"),
537 List<Tag> tags =
new ArrayList<>();
542 logger.log(Level.SEVERE,
"Failed to get tags for artifact " + artifact.getDisplayName(), ex);
555 "BlackboardArtifactNode.createSheet.tags.displayName=Tags"})
557 protected void addTagProperty(Sheet.Set sheetSet)
throws MissingResourceException {
559 List<Tag> tags =
new ArrayList<>();
564 logger.log(Level.SEVERE,
"Failed to get tags for artifact " + artifact.getDisplayName(), ex);
566 sheetSet.put(
new NodeProperty<>(
"Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(),
567 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(
", "))));
581 sheetSet.put(
new NodeProperty<>(
"Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(),
582 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(
", "))));
597 return correlationAttribute;
613 @NbBundle.Messages({
"BlackboardArtifactNode.createSheet.comment.name=C",
614 "BlackboardArtifactNode.createSheet.comment.displayName=C"})
618 sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(),
NO_DESCR,
636 for (Tag tag : tags) {
637 if (!StringUtils.isBlank(tag.getComment())) {
646 if (attribute != null && !StringUtils.isBlank(attribute.
getComment())) {
666 @NbBundle.Messages({
"BlackboardArtifactNode.createSheet.score.name=S",
667 "BlackboardArtifactNode.createSheet.score.displayName=S",
668 "BlackboardArtifactNode.createSheet.notableFile.description=Associated file recognized as notable.",
669 "BlackboardArtifactNode.createSheet.interestingResult.description=Result has an interesting result associated with it.",
670 "BlackboardArtifactNode.createSheet.taggedItem.description=Result or associated file has been tagged.",
671 "BlackboardArtifactNode.createSheet.notableTaggedItem.description=Result or associated file tagged with notable tag.",
672 "BlackboardArtifactNode.createSheet.noScore.description=No score"})
676 sheetSet.put(
new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft()));
689 String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description();
690 if (associated instanceof AbstractFile) {
691 if (((AbstractFile) associated).getKnown() == TskData.FileKnown.BAD) {
693 description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description();
699 BlackboardAttribute attr = content.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME));
702 if (hashDb.getHashSetName().equals(attr.getValueString())) {
704 description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description();
708 }
catch (TskCoreException ex) {
710 logger.log(Level.WARNING,
"Unable to get TSK_SET_NAME attribute for artifact of type TSK_HASHSET_HIT with artifact ID " + content.getArtifactID(), ex);
714 if (score ==
Score.
NO_SCORE && !content.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT).isEmpty()) {
716 description = Bundle.BlackboardArtifactNode_createSheet_interestingResult_description();
718 }
catch (TskCoreException ex) {
719 logger.log(Level.WARNING,
"Error getting artifacts for artifact: " + content.getName(), ex);
723 description = Bundle.BlackboardArtifactNode_createSheet_taggedItem_description();
724 for (Tag tag : tags) {
725 if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
727 description = Bundle.BlackboardArtifactNode_createSheet_notableTaggedItem_description();
733 return Pair.of(score, description);
746 @NbBundle.Messages({
"BlackboardArtifactNode.createSheet.count.name=O",
747 "BlackboardArtifactNode.createSheet.count.displayName=O",
748 "BlackboardArtifactNode.createSheet.count.noCorrelationAttributes.description=No correlation properties found",
749 "BlackboardArtifactNode.createSheet.count.noCorrelationValues.description=Unable to find other occurrences because no value exists for the available correlation property",
750 "# {0} - occurrenceCount",
751 "# {1} - attributeType",
752 "BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}"})
757 new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft()));
774 String description = defaultDescription;
777 if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
779 description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, attributeType.
getDisplayName());
780 }
else if (attributeType != null) {
781 description = Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationValues_description();
784 logger.log(Level.WARNING,
"Error getting count of datasources with correlation attribute", ex);
786 logger.log(Level.WARNING,
"Unable to normalize data to get count of datasources with correlation attribute", ex);
788 return Pair.of(count, description);
796 String parentName = associated.getName();
799 while ((parent = parent.getParent()) != null) {
800 parentName = parent.getName();
802 }
catch (TskCoreException ex) {
803 logger.log(Level.WARNING,
"Failed to get parent name from {0}", associated.getName());
816 if (null == customProperties) {
818 customProperties =
new ArrayList<>();
820 customProperties.add(np);
830 @SuppressWarnings(
"deprecation")
833 for (BlackboardAttribute attribute : artifact.getAttributes()) {
834 final int attributeTypeID = attribute.getAttributeType().getTypeID();
836 if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
837 || attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()
838 || attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
839 || attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()
840 || attributeTypeID == ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()) {
841 }
else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
843 }
else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
845 }
else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
846 && attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
854 String value = attribute.getDisplayString();
855 if (value.length() > 512) {
856 value = value.substring(0, 512);
858 map.put(attribute.getAttributeType().getDisplayName(), value);
860 map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
863 }
catch (TskCoreException ex) {
864 logger.log(Level.SEVERE,
"Getting attributes failed", ex);
877 final int attributeTypeID = attribute.getAttributeType().getTypeID();
880 if (attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
881 || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML.getTypeID()
882 || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF.getTypeID()
883 || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID()
884 || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID()
885 || attributeTypeID == ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()) {
888 }
else if (attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID()) {
890 String value = attribute.getDisplayString();
891 if (value.length() > 160) {
892 value = value.substring(0, 160) +
"...";
894 map.put(attribute.getAttributeType().getDisplayName(), value);
895 }
else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
898 map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
905 return visitor.
visit(
this);
918 final long objectID = artifact.getObjectID();
920 Content content = contentCache.get(objectID, () -> artifact.getSleuthkitCase().getContentById(objectID));
921 if (content == null) {
922 return Lookups.fixed(artifact);
924 return Lookups.fixed(artifact, content);
926 }
catch (ExecutionException ex) {
927 logger.log(Level.WARNING,
"Getting associated content for artifact failed", ex);
928 return Lookups.fixed(artifact);
939 return getClass().getName();
943 public <T> T accept(ContentNodeVisitor<T> visitor) {
944 return visitor.visit(
this);
Pair< DataResultViewerTable.Score, String > getScorePropertyAndDescription(List< Tag > tags)
static final String VALUE_LOADING
final void addTagProperty(Sheet.Set sheetSet, List< Tag > tags)
void addTagProperty(Sheet.Set sheetSet)
void fillPropertyMap(Map< String, Object > map, BlackboardArtifact artifact)
static String getStringTime(long epochSeconds, TimeZone tzone)
static boolean hasSupportedTimeStamp(BlackboardArtifact artifact)
final PropertyChangeListener weakPcl
static Cache< Long, Content > contentCache
void setName(String name)
final PropertyChangeListener pcl
BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath)
static Lookup createLookup(BlackboardArtifact artifact)
Pair< Long, String > getCountPropertyAndDescription(Type attributeType, String attributeValue, String defaultDescription)
static final Integer[] SHOW_FILE_METADATA
String getCorrelationValue()
T visit(DataSourcesNode in)
Action[] getActions(boolean context)
Type getCorrelationType()
static ViewFileInTimelineAction createViewSourceFileAction(AbstractFile file)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
final void addScorePropertyAndDescription(Sheet.Set sheetSet, List< Tag > tags)
TagsManager getTagsManager()
static AbstractFile findLinked(BlackboardArtifact artifact)
synchronized List< HashDb > getKnownBadFileHashSets()
static EamDb getInstance()
List< NodeProperty<?extends Object > > customProperties
static synchronized HashDbManager getInstance()
static CorrelationAttributeInstance getInstanceFromContent(Content content)
final List< Tag > getAllTagsFromDatabase()
String getRootParentName()
final BlackboardArtifact artifact
void addEmailMsgProperty(Map< String, Object > map, BlackboardAttribute attribute)
static boolean getHideSCOColumns()
final void addCommentProperty(Sheet.Set sheetSet, List< Tag > tags, CorrelationAttributeInstance attribute)
final CorrelationAttributeInstance getCorrelationAttributeInstance()
static boolean isEnabled()
SleuthkitCase getSleuthkitCase()
DataResultViewerTable.HasCommentStatus getCommentProperty(List< Tag > tags, CorrelationAttributeInstance attribute)
final void addCountProperty(Sheet.Set sheetSet, CorrelationAttributeInstance attribute)
BLACKBOARD_ARTIFACT_TAG_ADDED
static final Logger logger
static void error(String title, String message)
BlackboardArtifact getArtifact()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
void addNodeProperty(NodeProperty<?> np)
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
BlackboardArtifactNode(BlackboardArtifact artifact)
static final Integer[] SHOW_UNIQUE_PATH
static ViewFileInTimelineAction createViewFileAction(AbstractFile file)
BLACKBOARD_ARTIFACT_TAG_DELETED
static final String NO_DESCR