Autopsy  4.7.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
BlackboardArtifactNode.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 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.datamodel;
20 
21 import com.google.common.cache.Cache;
22 import com.google.common.cache.CacheBuilder;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 import java.text.MessageFormat;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.EnumSet;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.MissingResourceException;
33 import java.util.Set;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.TimeUnit;
36 import java.util.logging.Level;
37 import java.util.stream.Collectors;
38 import javax.swing.Action;
39 import org.apache.commons.lang3.StringUtils;
40 import org.openide.nodes.Sheet;
41 import org.openide.util.Lookup;
42 import org.openide.util.NbBundle;
43 import org.openide.util.WeakListeners;
44 import org.openide.util.lookup.Lookups;
55 import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked;
58 import org.sleuthkit.datamodel.AbstractFile;
59 import org.sleuthkit.datamodel.BlackboardArtifact;
60 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
61 import org.sleuthkit.datamodel.BlackboardAttribute;
62 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
63 import org.sleuthkit.datamodel.Content;
64 import org.sleuthkit.datamodel.Tag;
65 import org.sleuthkit.datamodel.TskCoreException;
66 
71 public class BlackboardArtifactNode extends AbstractContentNode<BlackboardArtifact> {
72 
73  private static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName());
79 
80  private static Cache<Long, Content> contentCache = CacheBuilder.newBuilder()
81  .expireAfterWrite(1, TimeUnit.MINUTES).
82  build();
83 
84  private final BlackboardArtifact artifact;
85  private Content associated = null;
86 
87  private List<NodeProperty<? extends Object>> customProperties;
88 
89  private final static String NO_DESCR = NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.noDesc.text");
90 
91 
92  /*
93  * Artifact types which should have the full unique path of the associated
94  * content as a property.
95  */
96  private static final Integer[] SHOW_UNIQUE_PATH = new Integer[]{
97  BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(),
98  BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(),
99  BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),
100  BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(),};
101 
102  // TODO (RC): This is an unattractive alternative to subclassing BlackboardArtifactNode,
103  // cut from the same cloth as the equally unattractive SHOW_UNIQUE_PATH array
104  // above. It should be removed when and if the subclassing is implemented.
105  private static final Integer[] SHOW_FILE_METADATA = new Integer[]{
106  BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),};
107 
108  private final PropertyChangeListener pcl = new PropertyChangeListener() {
109  @Override
110  public void propertyChange(PropertyChangeEvent evt) {
111  String eventType = evt.getPropertyName();
112  if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString())) {
114  if (event.getAddedTag().getArtifact().equals(artifact)) {
115  updateSheet();
116  }
117  } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString())) {
119  if (event.getDeletedTagInfo().getArtifactID() == artifact.getArtifactID()) {
120  updateSheet();
121  }
122  } else if (eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) {
124  if (event.getAddedTag().getContent().equals(associated)) {
125  updateSheet();
126  }
127  } else if (eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) {
129  if (event.getDeletedTagInfo().getContentID() == associated.getId()) {
130  updateSheet();
131  }
132  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
133  if (evt.getNewValue() == null) {
134  // case was closed. Remove listeners so that we don't get called with a stale case handle
135  removeListeners();
136  contentCache.invalidateAll();
137  }
138  }
139  }
140  };
141 
150  private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
151 
160  public BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath) {
161  super(artifact, createLookup(artifact));
162 
163  this.artifact = artifact;
164 
165  // Look for associated Content i.e. the source file for the artifact
166  for (Content lookupContent : this.getLookup().lookupAll(Content.class)) {
167  if ((lookupContent != null) && (!(lookupContent instanceof BlackboardArtifact))) {
168  this.associated = lookupContent;
169  break;
170  }
171  }
172 
173  this.setName(Long.toString(artifact.getArtifactID()));
174  this.setDisplayName();
175  this.setIconBaseWithExtension(iconPath);
177  }
178 
185  public BlackboardArtifactNode(BlackboardArtifact artifact) {
186  this(artifact, ExtractedContent.getIconFilePath(artifact.getArtifactTypeID()));
187  }
188 
198  @Override
199  protected void finalize() throws Throwable {
200  super.finalize();
201  removeListeners();
202  }
203 
204  private void removeListeners() {
206  }
207 
208  public BlackboardArtifact getArtifact() {
209  return this.artifact;
210  }
211 
212  @Override
213  @NbBundle.Messages({
214  "BlackboardArtifactNode.getAction.errorTitle=Error getting actions",
215  "BlackboardArtifactNode.getAction.resultErrorMessage=There was a problem getting actions for the selected result."
216  + " The 'View Result in Timeline' action will not be available.",
217  "BlackboardArtifactNode.getAction.linkedFileMessage=There was a problem getting actions for the selected result. "
218  + " The 'View File in Timeline' action will not be available."})
219  public Action[] getActions(boolean context) {
220  List<Action> actionsList = new ArrayList<>();
221  actionsList.addAll(Arrays.asList(super.getActions(context)));
222  AbstractFile file = getLookup().lookup(AbstractFile.class);
223 
224  // Create the "Add/Edit Central Repository Comment" menu item if the enabled.
225  if (file != null && file.isFile() && EamDbUtil.useCentralRepo()) {
227  }
228 
229  //if this artifact has a time stamp add the action to view it in the timeline
230  try {
232  actionsList.add(new ViewArtifactInTimelineAction(artifact));
233  }
234  } catch (TskCoreException ex) {
235  logger.log(Level.SEVERE, MessageFormat.format("Error getting arttribute(s) from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS
236  MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_resultErrorMessage());
237  }
238 
239  // if the artifact links to another file, add an action to go to that file
240  try {
241  AbstractFile c = findLinked(artifact);
242  if (c != null) {
244  }
245  } catch (TskCoreException ex) {
246  logger.log(Level.SEVERE, MessageFormat.format("Error getting linked file from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS
247  MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_linkedFileMessage());
248  }
249 
250  //if the artifact has associated content, add the action to view the content in the timeline
251  if (null != file) {
253  }
254 
255  return actionsList.toArray(new Action[actionsList.size()]);
256  }
257 
258  @NbBundle.Messages({"# {0} - artifactDisplayName", "BlackboardArtifactNode.displayName.artifact={0} Artifact"})
264  private void setDisplayName() {
265  String displayName = ""; //NON-NLS
266 
267  // If this is a node for a keyword hit on an artifact, we set the
268  // display name to be the artifact type name followed by " Artifact"
269  // e.g. "Messages Artifact".
270  if (artifact != null
271  && (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()
272  || artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID())) {
273  try {
274  for (BlackboardAttribute attribute : artifact.getAttributes()) {
275  if (attribute.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
276  BlackboardArtifact associatedArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(attribute.getValueLong());
277  if (associatedArtifact != null) {
278  if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
279  artifact.getDisplayName();
280  } else {
281  displayName = NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.displayName.artifact", associatedArtifact.getDisplayName());
282  }
283  }
284  }
285  }
286  } catch (TskCoreException | NoCurrentCaseException ex) {
287  // Do nothing since the display name will be set to the file name.
288  }
289  }
290 
291  if (displayName.isEmpty() && artifact != null) {
292  displayName = artifact.getName();
293  }
294 
295  this.setDisplayName(displayName);
296 
297  }
298 
304  public String getSourceName() {
305 
306  String srcName = "";
307  if (associated != null) {
308  srcName = associated.getName();
309  }
310  return srcName;
311  }
312 
313  @NbBundle.Messages({
314  "BlackboardArtifactNode.createSheet.artifactType.displayName=Artifact Type",
315  "BlackboardArtifactNode.createSheet.artifactType.name=Artifact Type",
316  "BlackboardArtifactNode.createSheet.artifactDetails.displayName=Artifact Details",
317  "BlackboardArtifactNode.createSheet.artifactDetails.name=Artifact Details",
318  "BlackboardArtifactNode.artifact.displayName=Artifact",
319  "BlackboardArtifactNode.createSheet.artifactMD5.displayName=MD5 Hash",
320  "BlackboardArtifactNode.createSheet.artifactMD5.name=MD5 Hash"})
321 
322  @Override
323  protected Sheet createSheet() {
324  Sheet sheet = super.createSheet();
325  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
326  if (sheetSet == null) {
327  sheetSet = Sheet.createPropertiesSet();
328  sheet.put(sheetSet);
329  }
330 
331  Map<String, Object> map = new LinkedHashMap<>();
332  fillPropertyMap(map, artifact);
333 
334  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"),
335  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"),
336  NO_DESCR,
337  this.getSourceName()));
338  if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) {
339  try {
340  BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
341  if (attribute != null) {
342  BlackboardArtifact associatedArtifact = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifact(attribute.getValueLong());
343  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"),
344  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"),
345  NO_DESCR,
346  associatedArtifact.getDisplayName() + " " + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.artifact.displayName")));
347  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"),
348  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"),
349  NO_DESCR,
350  associatedArtifact.getShortDescription()));
351  }
352  } catch (TskCoreException | NoCurrentCaseException ex) {
353  // Do nothing since the display name will be set to the file name.
354  }
355  }
356 
357  for (Map.Entry<String, Object> entry : map.entrySet()) {
358  sheetSet.put(new NodeProperty<>(entry.getKey(),
359  entry.getKey(),
360  NO_DESCR,
361  entry.getValue()));
362  }
363 
364  //append custom node properties
365  if (customProperties != null) {
366  for (NodeProperty<? extends Object> np : customProperties) {
367  sheetSet.put(np);
368  }
369  }
370 
371  final int artifactTypeId = artifact.getArtifactTypeID();
372 
373  // If mismatch, add props for extension and file type
374  if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) {
375  String ext = ""; //NON-NLS
376  String actualMimeType = ""; //NON-NLS
377  if (associated instanceof AbstractFile) {
378  AbstractFile af = (AbstractFile) associated;
379  ext = af.getNameExtension();
380  actualMimeType = af.getMIMEType();
381  if (actualMimeType == null) {
382  actualMimeType = ""; //NON-NLS
383  }
384  }
385  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"),
386  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"),
387  NO_DESCR,
388  ext));
389  sheetSet.put(new NodeProperty<>(
390  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"),
391  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"),
392  NO_DESCR,
393  actualMimeType));
394  }
395 
396  if (Arrays.asList(SHOW_UNIQUE_PATH).contains(artifactTypeId)) {
397  String sourcePath = ""; //NON-NLS
398  try {
399  sourcePath = associated.getUniquePath();
400  } catch (TskCoreException ex) {
401  logger.log(Level.WARNING, "Failed to get unique path from: {0}", associated.getName()); //NON-NLS
402  }
403 
404  if (sourcePath.isEmpty() == false) {
405  sheetSet.put(new NodeProperty<>(
406  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"),
407  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"),
408  NO_DESCR,
409  sourcePath));
410  }
411 
412  if (Arrays.asList(SHOW_FILE_METADATA).contains(artifactTypeId)) {
413  AbstractFile file = associated instanceof AbstractFile ? (AbstractFile) associated : null;
414  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"),
415  NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"),
416  "",
417  file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file)));
418  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"),
419  NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"),
420  "",
421  file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file)));
422  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"),
423  NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"),
424  "",
425  file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file)));
426  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"),
427  NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"),
428  "",
429  file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file)));
430  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"),
431  NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"),
432  "",
433  associated.getSize()));
434  sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(),
435  Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(),
436  "",
437  file == null ? "" : StringUtils.defaultString(file.getMd5Hash())));
438  }
439  } else {
440  String dataSourceStr = "";
441  try {
442  Content dataSource = associated.getDataSource();
443  if (dataSource != null) {
444  dataSourceStr = dataSource.getName();
445  } else {
446  dataSourceStr = getRootParentName();
447  }
448  } catch (TskCoreException ex) {
449  logger.log(Level.WARNING, "Failed to get image name from {0}", associated.getName()); //NON-NLS
450  }
451 
452  if (dataSourceStr.isEmpty() == false) {
453  sheetSet.put(new NodeProperty<>(
454  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"),
455  NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"),
456  NO_DESCR,
457  dataSourceStr));
458  }
459  }
460 
461  addTagProperty(sheetSet);
462 
463  return sheet;
464  }
465 
473  @NbBundle.Messages({
474  "BlackboardArtifactNode.createSheet.tags.displayName=Tags"})
475  protected void addTagProperty(Sheet.Set sheetSet) throws MissingResourceException {
476  // add properties for tags
477  List<Tag> tags = new ArrayList<>();
478  try {
481  } catch (TskCoreException | NoCurrentCaseException ex) {
482  logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex);
483  }
484  sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(),
485  NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", "))));
486  }
487 
488  private void updateSheet() {
489  this.setSheet(createSheet());
490  }
491 
492  private String getRootParentName() {
493  String parentName = associated.getName();
494  Content parent = associated;
495  try {
496  while ((parent = parent.getParent()) != null) {
497  parentName = parent.getName();
498  }
499  } catch (TskCoreException ex) {
500  logger.log(Level.WARNING, "Failed to get parent name from {0}", associated.getName()); //NON-NLS
501  return "";
502  }
503  return parentName;
504  }
505 
513  if (null == customProperties) {
514  //lazy create the list
515  customProperties = new ArrayList<>();
516  }
517  customProperties.add(np);
518  }
519 
527  @SuppressWarnings("deprecation")
528  private void fillPropertyMap(Map<String, Object> map, BlackboardArtifact artifact) {
529  try {
530  for (BlackboardAttribute attribute : artifact.getAttributes()) {
531  final int attributeTypeID = attribute.getAttributeType().getTypeID();
532  //skip some internal attributes that user shouldn't see
533  if (attributeTypeID == ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID()
534  || attributeTypeID == ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID()
535  || attributeTypeID == ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()
536  || attributeTypeID == ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()
537  || attributeTypeID == ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()) {
538  } else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
539  addEmailMsgProperty(map, attribute);
540  } else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
541  map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
542  } else if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_TOOL_OUTPUT.getTypeID()
543  && attributeTypeID == ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()) {
544  /*
545  * This was added because the RegRipper output would often
546  * cause the UI to get a black line accross it and hang if
547  * you hovered over large output or selected it. This
548  * reduces the amount of data in the table. Could consider
549  * doing this for all fields in the UI.
550  */
551  String value = attribute.getDisplayString();
552  if (value.length() > 512) {
553  value = value.substring(0, 512);
554  }
555  map.put(attribute.getAttributeType().getDisplayName(), value);
556  } else {
557  map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
558  }
559  }
560  } catch (TskCoreException ex) {
561  logger.log(Level.SEVERE, "Getting attributes failed", ex); //NON-NLS
562  }
563  }
564 
572  private void addEmailMsgProperty(Map<String, Object> map, BlackboardAttribute attribute) {
573 
574  final int attributeTypeID = attribute.getAttributeType().getTypeID();
575 
576  // Skip certain Email msg attributes
577  if (attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID()
578  || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML.getTypeID()
579  || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF.getTypeID()
580  || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID()
581  || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID()
582  || attributeTypeID == ATTRIBUTE_TYPE.TSK_HEADERS.getTypeID()) {
583 
584  // do nothing
585  } else if (attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID()) {
586 
587  String value = attribute.getDisplayString();
588  if (value.length() > 160) {
589  value = value.substring(0, 160) + "...";
590  }
591  map.put(attribute.getAttributeType().getDisplayName(), value);
592  } else if (attribute.getAttributeType().getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME) {
593  map.put(attribute.getAttributeType().getDisplayName(), ContentUtils.getStringTime(attribute.getValueLong(), associated));
594  } else {
595  map.put(attribute.getAttributeType().getDisplayName(), attribute.getDisplayString());
596  }
597 
598  }
599 
600  @Override
601  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
602  return visitor.visit(this);
603  }
604 
613  private static Lookup createLookup(BlackboardArtifact artifact) {
614  // Add the content the artifact is associated with
615  final long objectID = artifact.getObjectID();
616  try {
617  Content content = contentCache.get(objectID, () -> artifact.getSleuthkitCase().getContentById(objectID));
618  if (content == null) {
619  return Lookups.fixed(artifact);
620  } else {
621  return Lookups.fixed(artifact, content);
622  }
623  } catch (ExecutionException ex) {
624  logger.log(Level.WARNING, "Getting associated content for artifact failed", ex); //NON-NLS
625  return Lookups.fixed(artifact);
626  }
627  }
628 
629  @Override
630  public boolean isLeafTypeNode() {
631  return true;
632  }
633 
634  @Override
635  public String getItemType() {
636  return getClass().getName();
637  }
638 
639  @Override
640  public <T> T accept(ContentNodeVisitor<T> visitor) {
641  return visitor.visit(this);
642  }
643 }
void fillPropertyMap(Map< String, Object > map, BlackboardArtifact artifact)
static String getStringTime(long epochSeconds, TimeZone tzone)
BlackboardArtifactNode(BlackboardArtifact artifact, String iconPath)
List< ContentTag > getContentTagsByContent(Content content)
static Lookup createLookup(BlackboardArtifact artifact)
static ViewFileInTimelineAction createViewSourceFileAction(AbstractFile file)
static AddEditCentralRepoCommentAction createAddEditCentralRepoCommentAction(AbstractFile file)
void addEmailMsgProperty(Map< String, Object > map, BlackboardAttribute attribute)
static void error(String title, String message)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:420
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:465
static ViewFileInTimelineAction createViewFileAction(AbstractFile file)
List< BlackboardArtifactTag > getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact)

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