19 package org.sleuthkit.autopsy.communications.relationships;
21 import java.util.Comparator;
22 import java.util.HashMap;
23 import java.util.List;
26 import java.util.logging.Level;
27 import javax.swing.Action;
28 import org.openide.nodes.AbstractNode;
29 import org.openide.nodes.ChildFactory;
30 import org.openide.nodes.Children;
31 import org.openide.nodes.Node;
32 import org.openide.nodes.Sheet;
45 final 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;