Autopsy  4.11.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ThreadChildNodeFactory.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.communications.relationships;
20 
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.logging.Level;
26 import javax.swing.Action;
27 import org.openide.nodes.AbstractNode;
28 import org.openide.nodes.ChildFactory;
29 import org.openide.nodes.Children;
30 import org.openide.nodes.Node;
31 import org.openide.nodes.Sheet;
36 import org.sleuthkit.datamodel.BlackboardArtifact;
37 import org.sleuthkit.datamodel.BlackboardAttribute;
38 import org.sleuthkit.datamodel.CommunicationsManager;
39 import org.sleuthkit.datamodel.Content;
40 import org.sleuthkit.datamodel.TskCoreException;
41 
47 final class ThreadChildNodeFactory extends ChildFactory<BlackboardArtifact> {
48 
49  private static final Logger logger = Logger.getLogger(ThreadChildNodeFactory.class.getName());
50 
51  private SelectionInfo selectionInfo;
52 
53  private final Action preferredAction;
54 
62  ThreadChildNodeFactory(Action preferredAction) {
63  this.preferredAction = preferredAction;
64  }
65 
71  public void refresh(SelectionInfo selectionInfo) {
72  this.selectionInfo = selectionInfo;
73  refresh(true);
74  }
75 
84  @Override
85  protected boolean createKeys(List<BlackboardArtifact> list) {
86  CommunicationsManager communicationManager;
87  try {
88  communicationManager = Case.getCurrentCaseThrows().getSleuthkitCase().getCommunicationsManager();
89  } catch (NoCurrentCaseException | TskCoreException ex) {
90  logger.log(Level.SEVERE, "Failed to get communications manager from case.", ex); //NON-NLS
91  return false;
92  }
93 
94  if(selectionInfo == null) {
95  return true;
96  }
97 
98  final Set<Content> relationshipSources;
99 
100  try {
101  relationshipSources = communicationManager.getRelationshipSources(selectionInfo.getAccountDevicesInstances(), selectionInfo.getCommunicationsFilter());
102 
103  createRootMessageKeys(list, relationshipSources) ;
104  } catch (TskCoreException ex) {
105  logger.log(Level.SEVERE, "Failed to get relationship sources.", ex); //NON-NLS
106  }
107 
108  return true;
109  }
110 
122  private boolean createRootMessageKeys(List<BlackboardArtifact> list, Set<Content> relationshipSources) throws TskCoreException{
123  Map<String, BlackboardArtifact> rootMessageMap = new HashMap<>();
124  for(Content content: relationshipSources) {
125  if(!(content instanceof BlackboardArtifact)) {
126  continue;
127  }
128 
129  BlackboardArtifact bba = (BlackboardArtifact) content;
130  BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(bba.getArtifactTypeID());
131 
132  if (fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG
133  || fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG
134  || fromID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE) {
135 
136  // We want all artifacts that do not have "threadIDs" to appear as one thread in the UI
137  // To achive this assign any artifact that does not have a threadID
138  // the "UNTHREADED_ID"
139  String threadID = MessageNode.UNTHREADED_ID;
140  BlackboardAttribute attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
141 
142  if(attribute != null) {
143  threadID = attribute.getValueString();
144  }
145 
146  BlackboardArtifact tableArtifact = rootMessageMap.get(threadID);
147  if(tableArtifact == null) {
148  rootMessageMap.put(threadID, bba);
149  } else {
150  // Get the date of the message
151  BlackboardAttribute tableAttribute = tableArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
152  attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
153 
154  // put the earliest message into the table
155  if(tableAttribute != null
156  && attribute != null
157  && tableAttribute.getValueLong() > attribute.getValueLong()) {
158  rootMessageMap.put(threadID, bba);
159  }
160  }
161  }
162  }
163 
164  for(BlackboardArtifact bba: rootMessageMap.values()) {
165  list.add(bba);
166  }
167 
168  return true;
169  }
170 
171  @Override
172  protected Node createNodeForKey(BlackboardArtifact bba) {
173  BlackboardAttribute attribute = null;
174  try {
175  attribute = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_THREAD_ID));
176  } catch (TskCoreException ex) {
177  logger.log(Level.WARNING, String.format("Unable to get threadID for artifact: %s", bba.getName()), ex);
178  }
179 
180  if (attribute != null) {
181  return new ThreadNode(bba, attribute.getValueString(), preferredAction);
182  } else {
183  // Only one of these should occur.
184  return new UnthreadedNode();
185  }
186  }
187 
191  final class UnthreadedNode extends AbstractNode {
195  UnthreadedNode() {
196  super(Children.LEAF);
197  setDisplayName("Unthreaded");
198  this.setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/unthreaded.png" );
199  }
200 
201  @Override
202  protected Sheet createSheet() {
203  Sheet sheet = super.createSheet();
204  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
205  if (sheetSet == null) {
206  sheetSet = Sheet.createPropertiesSet();
207  sheet.put(sheetSet);
208  }
209 
210  // Give this node a threadID of "UNTHEADED_ID"
211  sheetSet.put(new NodeProperty<>("ThreadID", "ThreadID","",MessageNode.UNTHREADED_ID));
212 
213  return sheet;
214  }
215  }
216 }

Copyright © 2012-2018 Basis Technology. Generated on: Fri Jun 21 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.