diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index eb3571e0f1..2283e9d14f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -93,20 +93,16 @@ public class BlackboardArtifactNode extends AbstractContentNode contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); /* - * Case application events that affect the property sheets of - * BlackboardArtifactNodes. - * - * NOTE: CURRENT_CASE (closed) events trigger content cache invalidation and - * unregistering of the PropertyChangeListener subscribed to the application - * events. + * Case events that indicate an update to the node's property sheet may be + * required. */ private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, - Case.Events.CURRENT_CASE, - Case.Events.CR_COMMENT_CHANGED); + Case.Events.CR_COMMENT_CHANGED, + Case.Events.CURRENT_CASE); /* * Artifact types for which the unique path of the artifact's source content @@ -120,20 +116,23 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; + private Content srcContent; // May be null. /* - * The node's application event listener. + * A method has been provided to allow the injection of properties into this + * node for display in the node's property sheet, independent of the + * artifact the node represents. */ + private List> customProperties; + private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -149,19 +148,25 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", @@ -581,7 +570,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), "", - sourceContent.getSize())); + file == null ? "" : file.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -589,15 +578,17 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + if (srcContent != null) { + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); + } } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0})", artifact.getId()), ex); } return tags; } @@ -668,28 +661,34 @@ public class BlackboardArtifactNode extends AbstractContentNode tags, CorrelationAttributeInstance attribute) { + /* + * Has a tag with a comment been applied to the artifact or its source + * content? + */ HasCommentStatus status = tags.size() > 0 ? HasCommentStatus.TAG_NO_COMMENT : HasCommentStatus.NO_COMMENT; for (Tag tag : tags) { if (!StringUtils.isBlank(tag.getComment())) { @@ -698,6 +697,10 @@ public class BlackboardArtifactNode extends AbstractContentNode getScorePropertyAndDescription(List tags) { + /* + * Is the artifact's source content marked as notable? + */ Score score = Score.NO_SCORE; String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description(); - if (sourceContent instanceof AbstractFile) { - if (((AbstractFile) sourceContent).getKnown() == TskData.FileKnown.BAD) { + if (srcContent != null && srcContent instanceof AbstractFile) { + if (((AbstractFile) srcContent).getKnown() == TskData.FileKnown.BAD) { score = Score.NOTABLE_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description(); } } - //if the artifact being viewed is a hashhit check if the hashset is notable - if ((score == Score.NO_SCORE || score == Score.INTERESTING_SCORE) && content.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { + + /* + * If the artifact is a hash set hit, is the hash set a notable hashes + * hash set? + */ + if (score == Score.NO_SCORE && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { try { - BlackboardAttribute attr = content.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME)); + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME)); List notableHashsets = HashDbManager.getInstance().getKnownBadFileHashSets(); for (HashDbManager.HashDb hashDb : notableHashsets) { if (hashDb.getHashSetName().equals(attr.getValueString())) { @@ -748,18 +762,29 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 && (score == Score.NO_SCORE || score == Score.INTERESTING_SCORE)) { score = Score.INTERESTING_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_taggedItem_description(); @@ -798,7 +823,6 @@ public class BlackboardArtifactNode extends AbstractContentNode map, BlackboardAttribute attribute) { - final int attributeTypeID = attribute.getAttributeType().getTypeID(); - - // Skip certain Email msg attributes if (attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID() || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML.getTypeID() || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF.getTypeID() @@ -933,11 +954,10 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0})", artifact.getId()), ex); } sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } @@ -1019,8 +1038,7 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { @@ -1036,8 +1054,8 @@ public class BlackboardArtifactNode extends AbstractContentNode