19package org.sleuthkit.autopsy.communications.relationships;
21import java.util.Comparator;
22import java.util.HashMap;
26import java.util.logging.Level;
27import javax.swing.Action;
28import org.openide.nodes.AbstractNode;
29import org.openide.nodes.ChildFactory;
30import org.openide.nodes.Children;
31import org.openide.nodes.Node;
32import org.openide.nodes.Sheet;
33import org.sleuthkit.autopsy.coreutils.Logger;
34import org.sleuthkit.autopsy.datamodel.NodeProperty;
35import org.sleuthkit.datamodel.BlackboardArtifact;
36import org.sleuthkit.datamodel.BlackboardAttribute;
37import org.sleuthkit.datamodel.Content;
38import org.sleuthkit.datamodel.TskCoreException;
45final class ThreadChildNodeFactory
extends ChildFactory<BlackboardArtifact> {
47 private static final Logger logger = Logger.getLogger(ThreadChildNodeFactory.class.getName());
49 private SelectionInfo selectionInfo;
51 private final Action preferredAction;
60 ThreadChildNodeFactory(Action preferredAction) {
61 this.preferredAction = preferredAction;
69 public void refresh(SelectionInfo selectionInfo) {
70 this.selectionInfo = selectionInfo;
83 protected boolean createKeys(List<BlackboardArtifact> list) {
84 if(selectionInfo ==
null) {
89 final Set<Content> relationshipSources = selectionInfo.getRelationshipSources();
90 createRootMessageKeys(list, relationshipSources) ;
91 }
catch (TskCoreException ex) {
92 logger.log(Level.SEVERE,
"Failed to load relationship sources.", ex);
110 private boolean createRootMessageKeys(List<BlackboardArtifact> list, Set<Content> relationshipSources)
throws TskCoreException{
111 Map<String, BlackboardArtifact> rootMessageMap =
new HashMap<>();
112 for(Content content: relationshipSources) {
113 if(!(content instanceof BlackboardArtifact)) {
117 BlackboardArtifact bba = (BlackboardArtifact) content;
118 BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
120 if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG
121 || fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) {
126 String threadID = MessageNode.UNTHREADED_ID;
128 BlackboardAttribute attribute = bba.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
130 if(attribute !=
null) {
131 threadID = attribute.getValueString();
134 BlackboardArtifact tableArtifact = rootMessageMap.get(threadID);
135 if(tableArtifact ==
null) {
136 rootMessageMap.put(threadID, bba);
139 BlackboardAttribute tableAttribute =
null;
142 tableAttribute = tableArtifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
143 attribute = bba.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
145 if(tableAttribute !=
null
147 && tableAttribute.getValueLong() > attribute.getValueLong()) {
148 rootMessageMap.put(threadID, bba);
152 tableAttribute = tableArtifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
153 attribute = bba.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
155 if(tableAttribute !=
null
157 && tableAttribute.getValueLong() < attribute.getValueLong()) {
158 rootMessageMap.put(threadID, bba);
162 tableAttribute = tableArtifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START));
163 attribute = bba.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START));
165 if(tableAttribute !=
null
167 && tableAttribute.getValueLong() > attribute.getValueLong()) {
168 rootMessageMap.put(threadID, bba);
178 for(BlackboardArtifact bba: rootMessageMap.values()) {
182 list.sort(
new ThreadDateComparator());
188 protected Node createNodeForKey(BlackboardArtifact bba) {
189 BlackboardAttribute attribute =
null;
191 attribute = bba.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
192 }
catch (TskCoreException ex) {
193 logger.log(Level.WARNING, String.format(
"Unable to get threadID for artifact: %s", bba.getName()), ex);
196 if (attribute !=
null) {
197 return new ThreadNode(bba, attribute.getValueString(), preferredAction);
200 return new UnthreadedNode();
207 final class UnthreadedNode
extends AbstractNode {
212 super(Children.LEAF);
213 setDisplayName(
"Unthreaded");
214 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/communications/images/unthreaded.png" );
218 protected Sheet createSheet() {
219 Sheet sheet = super.createSheet();
220 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
221 if (sheetSet ==
null) {
222 sheetSet = Sheet.createPropertiesSet();
227 sheetSet.put(
new NodeProperty<>(
"ThreadID",
"ThreadID",
"",MessageNode.UNTHREADED_ID));
240 class ThreadDateComparator
implements Comparator<BlackboardArtifact> {
243 public int compare(BlackboardArtifact bba1, BlackboardArtifact bba2) {
244 BlackboardAttribute attribute1 =
null;
245 BlackboardAttribute attribute2 =
null;
249 long dateTime1 = Long.MAX_VALUE;
250 long dateTime2 = Long.MAX_VALUE;
253 BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba1.getArtifactTypeID());
254 if (fromID !=
null) {
258 attribute1 = bba1.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
262 attribute1 = bba1.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
266 attribute1 = bba1.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START));
270 }
catch (TskCoreException ex) {
271 logger.log(Level.WARNING, String.format(
"Unable to compare attributes for artifact %d", bba1.getArtifactID()), ex);
277 BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba2.getArtifactTypeID());
278 if (fromID !=
null) {
282 attribute2 = bba2.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
285 attribute2 = bba2.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
288 attribute2 = bba2.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START));
291 }
catch (TskCoreException ex) {
292 logger.log(Level.WARNING, String.format(
"Unable to compare attributes for artifact %d", bba2.getArtifactID()), ex);
297 if (attribute1 !=
null) {
298 dateTime1 = attribute1.getValueLong();
301 if (attribute2 !=
null) {
302 dateTime2 = attribute2.getValueLong();
305 return Long.compare(dateTime1, dateTime2) * -1;