Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractedContent.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2020 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 java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.EnumSet;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.logging.Level;
31 import org.openide.nodes.ChildFactory;
32 import org.openide.nodes.Children;
33 import org.openide.nodes.Node;
34 import org.openide.nodes.Sheet;
35 import org.openide.util.NbBundle;
36 import org.openide.util.lookup.Lookups;
43 import org.sleuthkit.datamodel.Blackboard;
44 import org.sleuthkit.datamodel.BlackboardArtifact;
45 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
46 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
47 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_TL_EVENT;
48 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE;
49 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
50 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO;
51 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT;
52 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
53 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT;
54 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
55 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE;
56 import org.sleuthkit.datamodel.SleuthkitCase;
57 import org.sleuthkit.datamodel.TskCoreException;
58 
63 public class ExtractedContent implements AutopsyVisitableItem {
64 
67  public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text");
68  private final long filteringDSObjId; // 0 if not filtering/grouping by data source
69  private SleuthkitCase skCase; // set to null after case has been closed
70  private Blackboard blackboard;
71 
77  public ExtractedContent(SleuthkitCase skCase) {
78  this(skCase, 0);
79  }
80 
87  public ExtractedContent(SleuthkitCase skCase, long objId) {
88  this.skCase = skCase;
89  this.filteringDSObjId = objId;
90  this.blackboard = skCase.getBlackboard();
91  }
92 
93  @Override
94  public <T> T accept(AutopsyItemVisitor<T> visitor) {
95  return visitor.visit(this);
96  }
97 
98  public SleuthkitCase getSleuthkitCase() {
99  return skCase;
100  }
101 
102  public class RootNode extends DisplayableItemNode {
103 
104  public RootNode(SleuthkitCase skCase) {
105  super(Children.create(new TypeFactory(), true), Lookups.singleton(NAME));
106  super.setName(NAME);
107  super.setDisplayName(NAME);
108  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/extracted_content.png"); //NON-NLS
109  }
110 
111  @Override
112  public boolean isLeafTypeNode() {
113  return false;
114  }
115 
116  @Override
117  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
118  return visitor.visit(this);
119  }
120 
121  @Override
122  protected Sheet createSheet() {
123  Sheet sheet = super.createSheet();
124  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
125  if (sheetSet == null) {
126  sheetSet = Sheet.createPropertiesSet();
127  sheet.put(sheetSet);
128  }
129 
130  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.name"),
131  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.displayName"),
132  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.desc"),
133  NAME));
134  return sheet;
135  }
136 
137  @Override
138  public String getItemType() {
139  return getClass().getName();
140  }
141  }
142 
148  private class TypeFactory extends ChildFactory.Detachable<BlackboardArtifact.Type> {
149 
150  private final ArrayList<BlackboardArtifact.Type> doNotShow = new ArrayList<>();
151  // maps the artifact type to its child node
152  private final HashMap<BlackboardArtifact.Type, TypeNode> typeNodeList = new HashMap<>();
153 
154  @SuppressWarnings("deprecation")
155  TypeFactory() {
156  super();
157 
158  // these are shown in other parts of the UI
159  doNotShow.add(new BlackboardArtifact.Type(TSK_GEN_INFO));
160  doNotShow.add(new BlackboardArtifact.Type(TSK_EMAIL_MSG));
161  doNotShow.add(new BlackboardArtifact.Type(TSK_HASHSET_HIT));
162  doNotShow.add(new BlackboardArtifact.Type(TSK_KEYWORD_HIT));
163  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_FILE_HIT));
164  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
165  doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
166  doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE));
167  doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE));
168  doNotShow.add(new BlackboardArtifact.Type(TSK_TL_EVENT));
169 
170  //This is not meant to be shown in the UI at all. It is more of a meta artifact.
171  doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT));
172  }
173 
174  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
175  String eventType = evt.getPropertyName();
176  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
182  try {
189  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
190  if (null != event && !(this.doNotShow.contains(event.getBlackboardArtifactType()))) {
191  refresh(true);
192  }
193  } catch (NoCurrentCaseException notUsed) {
197  }
198  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
199  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
205  try {
207  refresh(true);
208  } catch (NoCurrentCaseException notUsed) {
212  }
213  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
214  // case was closed. Remove listeners so that we don't get called with a stale case handle
215  if (evt.getNewValue() == null) {
216  removeNotify();
217  skCase = null;
218  }
219  }
220  };
221 
222  @Override
223  protected void addNotify() {
227  }
228 
229  @Override
230  protected void removeNotify() {
234  typeNodeList.clear();
235  }
236 
237  @Override
238  protected boolean createKeys(List<BlackboardArtifact.Type> list) {
239  if (skCase != null) {
240  try {
241  List<BlackboardArtifact.Type> types = (filteringDSObjId > 0)
242  ? blackboard.getArtifactTypesInUse(filteringDSObjId)
243  : skCase.getArtifactTypesInUse();
244 
245  types.removeAll(doNotShow);
246  Collections.sort(types,
247  new Comparator<BlackboardArtifact.Type>() {
248  @Override
249  public int compare(BlackboardArtifact.Type a, BlackboardArtifact.Type b) {
250  return a.getDisplayName().compareTo(b.getDisplayName());
251  }
252  });
253  list.addAll(types);
254 
255  // the create node method will get called only for new types
256  // refresh the counts if we already created them from a previous update
257  for (BlackboardArtifact.Type art : types) {
258  TypeNode node = typeNodeList.get(art);
259  if (node != null) {
260  node.updateDisplayName();
261  }
262  }
263  } catch (TskCoreException ex) {
264  Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS
265  }
266  }
267  return true;
268  }
269 
270  @Override
271  protected Node createNodeForKey(BlackboardArtifact.Type key) {
272  TypeNode node = new TypeNode(key);
273  typeNodeList.put(key, node);
274  return node;
275  }
276  }
277 
284  public class TypeNode extends DisplayableItemNode {
285 
286  private final BlackboardArtifact.Type type;
287  private long childCount = 0;
288 
289  TypeNode(BlackboardArtifact.Type type) {
290  super(Children.create(new ArtifactFactory(type), true), Lookups.singleton(type.getDisplayName()));
291  super.setName(type.getTypeName());
292  this.type = type;
293  this.setIconBaseWithExtension(IconsUtil.getIconFilePath(type.getTypeID())); //NON-NLS
294  updateDisplayName();
295  }
296 
297  final void updateDisplayName() {
298  if (skCase == null) {
299  return;
300  }
301 
302  // NOTE: This completely destroys our lazy-loading ideal
303  // a performance increase might be had by adding a
304  // "getBlackboardArtifactCount()" method to skCase
305  try {
306  this.childCount = (filteringDSObjId > 0)
307  ? blackboard.getArtifactsCount(type.getTypeID(), filteringDSObjId)
308  : skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
309  } catch (TskCoreException ex) {
310  Logger.getLogger(TypeNode.class.getName())
311  .log(Level.WARNING, "Error getting child count", ex); //NON-NLS
312  }
313  super.setDisplayName(type.getDisplayName() + " \u200E(\u200E" + childCount + ")\u200E");
314  }
315 
316  @Override
317  protected Sheet createSheet() {
318  Sheet sheet = super.createSheet();
319  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
320  if (sheetSet == null) {
321  sheetSet = Sheet.createPropertiesSet();
322  sheet.put(sheetSet);
323  }
324 
325  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.name"),
326  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.displayName"),
327  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.desc"),
328  type.getDisplayName()));
329 
330  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.name"),
331  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.displayName"),
332  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.desc"),
333  childCount));
334 
335  return sheet;
336  }
337 
338  @Override
339  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
340  return visitor.visit(this);
341  }
342 
343  @Override
344  public boolean isLeafTypeNode() {
345  return true;
346  }
347 
348  @Override
349  public String getItemType() {
350  return getClass().getName() + type.getDisplayName();
351  }
352  }
353 
357  private class ArtifactFactory extends BaseChildFactory<BlackboardArtifact> {
358 
359  private BlackboardArtifact.Type type;
360 
361  ArtifactFactory(BlackboardArtifact.Type type) {
362  super(type.getTypeName());
363  this.type = type;
364  }
365 
366  private final PropertyChangeListener pcl = new PropertyChangeListener() {
367  @Override
368  public void propertyChange(PropertyChangeEvent evt) {
369  String eventType = evt.getPropertyName();
370  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
377  try {
385  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
386  if (null != event && event.getBlackboardArtifactType().equals(type)) {
387  refresh(true);
388  }
389  } catch (NoCurrentCaseException notUsed) {
393  }
394  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
395  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
402  try {
404  refresh(true);
405  } catch (NoCurrentCaseException notUsed) {
409  }
410  }
411  }
412  };
413 
414  @Override
415  protected void onAdd() {
418  }
419 
420  @Override
421  protected void onRemove() {
424  }
425 
426  @Override
427  protected Node createNodeForKey(BlackboardArtifact key) {
428  return new BlackboardArtifactNode(key);
429  }
430 
431  @Override
432  protected List<BlackboardArtifact> makeKeys() {
433  if (skCase != null) {
434  try {
435  List<BlackboardArtifact> arts;
436  if (filteringDSObjId > 0) {
437  arts = blackboard.getArtifacts(type.getTypeID(), filteringDSObjId);
438  } else {
439  arts = skCase.getBlackboardArtifacts(type.getTypeID());
440  }
441  for (BlackboardArtifact art : arts) {
442  //Cache attributes while we are off the EDT.
443  //See JIRA-5969
444  art.getAttributes();
445  }
446  return arts;
447  } catch (TskCoreException ex) {
448  Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "Couldn't get blackboard artifacts from database", ex); //NON-NLS
449  }
450  }
451  return Collections.emptyList();
452  }
453  }
454 }
boolean createKeys(List< BlackboardArtifact.Type > list)
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
final ArrayList< BlackboardArtifact.Type > doNotShow
void removeIngestJobEventListener(final PropertyChangeListener listener)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
void addIngestJobEventListener(final PropertyChangeListener listener)
ExtractedContent(SleuthkitCase skCase, long objId)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:486
final HashMap< BlackboardArtifact.Type, TypeNode > typeNodeList
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:531

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.