19 package org.sleuthkit.autopsy.communications.relationships;
21 import java.awt.event.ActionEvent;
22 import java.util.logging.Level;
23 import javax.swing.AbstractAction;
24 import javax.swing.Action;
25 import org.apache.commons.lang3.StringUtils;
26 import org.openide.nodes.Sheet;
27 import org.openide.util.NbBundle.Messages;
31 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
32 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT;
33 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM;
34 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO;
35 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM;
36 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO;
37 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT;
41 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
42 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
44 import org.
sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
45 import org.
sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments;
50 class MessageNode
extends BlackboardArtifactNode {
52 public static final String UNTHREADED_ID =
"<UNTHREADED>";
54 private static final Logger logger = Logger.getLogger(MessageNode.class.getName());
56 private final String threadID;
58 private final Action preferredAction;
60 private final Action defaultNoopAction =
new DefaultMessageAction();
62 MessageNode(BlackboardArtifact artifact, String threadID, Action preferredAction) {
65 this.preferredAction = preferredAction;
67 final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(),
"s");
68 String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd,
"message");
69 setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase);
71 this.threadID = threadID;
75 "MessageNode_Node_Property_Type=Type",
76 "MessageNode_Node_Property_From=From",
77 "MessageNode_Node_Property_To=To",
78 "MessageNode_Node_Property_Date=Date",
79 "MessageNode_Node_Property_Subject=Subject",
80 "MessageNode_Node_Property_Attms=Attachment Count"
84 protected Sheet createSheet() {
85 Sheet sheet = Sheet.createDefault();
86 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
87 if (sheetSet == null) {
88 sheetSet = Sheet.createPropertiesSet();
92 sheetSet.put(
new NodeProperty<>(
"Type", Bundle.MessageNode_Node_Property_Type(),
"", getDisplayName()));
95 BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID());
98 || (fromID != TSK_EMAIL_MSG
99 && fromID != TSK_MESSAGE)) {
102 if (threadID != null) {
103 sheetSet.put(
new NodeProperty<>(
"ThreadID",
"ThreadID",
"", threadID));
105 sheetSet.put(
new NodeProperty<>(
"Subject", Bundle.MessageNode_Node_Property_Subject(),
"",
106 getAttributeDisplayString(artifact, TSK_SUBJECT)));
108 sheetSet.put(
new NodeProperty<>(
"Attms", Bundle.MessageNode_Node_Property_Attms(),
"", getAttachmentsCount()));
109 }
catch (TskCoreException ex) {
110 logger.log(Level.WARNING,
"Error loading attachment count for " + artifact, ex);
113 String msg_from = getAttributeDisplayString(artifact, TSK_EMAIL_FROM);
114 String msg_to = getAttributeDisplayString(artifact, TSK_EMAIL_TO);
115 String date = getAttributeDisplayString(artifact, TSK_DATETIME_SENT);
117 if (msg_from.isEmpty()) {
118 msg_from = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM);
121 if (msg_to.isEmpty()) {
122 msg_to = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO);
124 if (date.isEmpty()) {
125 date = getAttributeDisplayString(artifact, TSK_DATETIME);
128 sheetSet.put(
new NodeProperty<>(
"From", Bundle.MessageNode_Node_Property_From(),
"",
130 sheetSet.put(
new NodeProperty<>(
"To", Bundle.MessageNode_Node_Property_To(),
"",
132 sheetSet.put(
new NodeProperty<>(
"Date", Bundle.MessageNode_Node_Property_Date(),
"",
145 public String getSourceName() {
146 return getDisplayName();
149 String getThreadID() {
154 public Action getPreferredAction() {
155 return preferredAction != null ? preferredAction : defaultNoopAction;
158 private int getAttachmentsCount() throws TskCoreException {
160 int attachmentsCount;
163 BlackboardAttribute attachmentsAttr = artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS));
164 if (attachmentsAttr != null) {
166 MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class);
167 return msgAttachments.getAttachmentsCount();
168 }
catch (BlackboardJsonAttrUtil.InvalidJsonException ex) {
169 logger.log(Level.WARNING, String.format(
"Unable to parse json for MessageAttachments object in artifact: %s", artifact.getName()), ex);
173 attachmentsCount = artifact.getChildrenCount();
176 return attachmentsCount;
void actionPerformed(ActionEvent e)
static final long serialVersionUID
BlackboardArtifact getArtifact()