Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
Tags.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-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.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.EnumSet;
26 import java.util.List;
27 import java.util.Observable;
28 import java.util.Observer;
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;
44 import org.sleuthkit.datamodel.BlackboardArtifactTag;
45 import org.sleuthkit.datamodel.ContentTag;
46 import org.sleuthkit.datamodel.TagName;
47 import org.sleuthkit.datamodel.TskCoreException;
48 
54 public class Tags implements AutopsyVisitableItem {
55  // Creation of a RootNode object corresponding to a Tags object is done
56  // by a CreateAutopsyNodeVisitor dispatched from the AbstractContentChildren
57  // override of Children.Keys<T>.createNodes().
58 
59  private final static String DISPLAY_NAME = NbBundle.getMessage(RootNode.class, "TagsNode.displayName.text");
61  private static final String USER_NAME_PROPERTY = "user.name"; //NON-NLS
62  private final TagResults tagResults = new TagResults();
63  private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
64 
65  private final long filteringDSObjId; // 0 if not filtering/grouping by data source
66 
67  Tags() {
68  this(0);
69  }
70 
71  Tags(long dsObjId) {
72  this.filteringDSObjId = dsObjId;
73  }
74 
80  public static String getTagsDisplayName() {
81  return DISPLAY_NAME;
82  }
83 
84  long filteringDataSourceObjId() {
85  return this.filteringDSObjId;
86  }
87 
88  @Override
89  public <T> T accept(AutopsyItemVisitor<T> visitor) {
90  return visitor.visit(this);
91  }
92 
98  private class TagResults extends Observable {
99 
100  public void update() {
101  setChanged();
102  notifyObservers();
103  }
104  }
105 
112  public class RootNode extends DisplayableItemNode {
113 
114  public RootNode(long objId) {
115  super(Children.create(new TagNameNodeFactory(objId), true), Lookups.singleton(DISPLAY_NAME));
116  super.setName(DISPLAY_NAME);
117  super.setDisplayName(DISPLAY_NAME);
118  this.setIconBaseWithExtension(ICON_PATH);
119  }
120 
121  @Override
122  public boolean isLeafTypeNode() {
123  return false;
124  }
125 
126  @Override
127  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
128  return visitor.visit(this);
129  }
130 
131  @Override
132  protected Sheet createSheet() {
133  Sheet propertySheet = super.createSheet();
134  Sheet.Set properties = propertySheet.get(Sheet.PROPERTIES);
135  if (properties == null) {
136  properties = Sheet.createPropertiesSet();
137  propertySheet.put(properties);
138  }
139  properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "TagsNode.createSheet.name.name"),
140  NbBundle.getMessage(this.getClass(), "TagsNode.createSheet.name.displayName"), "", getName()));
141  return propertySheet;
142  }
143 
144  @Override
145  public String getItemType() {
146  return getClass().getName();
147  }
148 
152  public void refresh() {
153  tagResults.update();
154  }
155 
156  }
157 
158  private class TagNameNodeFactory extends ChildFactory.Detachable<TagName> implements Observer {
159 
160  private final long filteringDSObjId; // 0 if not filtering/grouping by data source
161 
167 
168  private final PropertyChangeListener pcl = new PropertyChangeListener() {
169  @Override
170  public void propertyChange(PropertyChangeEvent evt) {
171  String eventType = evt.getPropertyName();
172  if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString())
173  || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString())
174  || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())
175  || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) {
182  try {
184  refresh(true);
185  tagResults.update();
186  } catch (NoCurrentCaseException notUsed) {
190  }
191  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
192  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
199  try {
201  refresh(true);
202  tagResults.update();
203  } catch (NoCurrentCaseException notUsed) {
207  }
208  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
209  // case was closed. Remove listeners so that this can be garbage collected
210  if (evt.getNewValue() == null) {
211  removeNotify();
212  }
213  }
214  }
215  };
216 
222  TagNameNodeFactory(long objId) {
223  this.filteringDSObjId = objId;
224 
225  }
226 
227  @Override
228  protected void addNotify() {
231  tagResults.update();
232  tagResults.addObserver(this);
233  }
234 
235  @Override
236  protected void removeNotify() {
239  tagResults.deleteObserver(this);
240  }
241 
242  @Override
243  protected boolean createKeys(List<TagName> keys) {
244  try {
245  List<TagName> tagNamesInUse;
247  String userName = System.getProperty(USER_NAME_PROPERTY);
248  tagNamesInUse = (filteringDSObjId > 0)
251  } else {
252  tagNamesInUse = (filteringDSObjId > 0)
255  }
256  Collections.sort(tagNamesInUse, new Comparator<TagName>() {
257  @Override
258  public int compare(TagName o1, TagName o2) {
260  }
261  });
262  keys.addAll(tagNamesInUse);
263  } catch (TskCoreException | NoCurrentCaseException ex) {
264  Logger.getLogger(TagNameNodeFactory.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
265  }
266  return true;
267  }
268 
269  @Override
270  protected Node createNodeForKey(TagName key) {
271  return new TagNameNode(key);
272  }
273 
274  @Override
275  public void update(Observable o, Object arg) {
276  refresh(true);
277  }
278  }
279 
285  public class TagNameNode extends DisplayableItemNode implements Observer {
286 
287  private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
288  private final String BOOKMARK_TAG_ICON_PATH = "org/sleuthkit/autopsy/images/star-bookmark-icon-16.png"; //NON-NLS
289  private final TagName tagName;
290 
291  public TagNameNode(TagName tagName) {
292  super(Children.create(new TagTypeNodeFactory(tagName), true), Lookups.singleton(NbBundle.getMessage(TagNameNode.class, "TagNameNode.namePlusTags.text", tagName.getDisplayName())));
293  this.tagName = tagName;
294  setName(TagUtils.getDecoratedTagDisplayName(tagName));
296  if (tagName.getDisplayName().equals(TagsManager.getBookmarkTagDisplayName())) {
297  setIconBaseWithExtension(BOOKMARK_TAG_ICON_PATH);
298  } else {
299  setIconBaseWithExtension(ICON_PATH);
300  }
301  tagResults.addObserver(this);
302  }
303 
304  private void updateDisplayName() {
305  long tagsCount = 0;
306  try {
309  String userName = System.getProperty(USER_NAME_PROPERTY);
310  if (filteringDSObjId > 0) {
311  tagsCount = tm.getContentTagsCountByTagNameForUser(tagName, filteringDSObjId, userName);
312  tagsCount += tm.getBlackboardArtifactTagsCountByTagNameForUser(tagName, filteringDSObjId, userName);
313  } else {
314  tagsCount = tm.getContentTagsCountByTagNameForUser(tagName, userName);
315  tagsCount += tm.getBlackboardArtifactTagsCountByTagNameForUser(tagName, userName);
316  }
317  } else {
318  if (filteringDSObjId > 0) {
319  tagsCount = tm.getContentTagsCountByTagName(tagName, filteringDSObjId);
320  tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName, filteringDSObjId);
321  } else {
322  tagsCount = tm.getContentTagsCountByTagName(tagName);
323  tagsCount += tm.getBlackboardArtifactTagsCountByTagName(tagName);
324  }
325  }
326  } catch (TskCoreException | NoCurrentCaseException ex) {
327  Logger.getLogger(TagNameNode.class.getName()).log(Level.SEVERE, "Failed to get tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
328  }
329  setDisplayName(TagUtils.getDecoratedTagDisplayName(tagName) + " \u200E(\u200E" + tagsCount + ")\u200E");
330  }
331 
332  @Override
333  protected Sheet createSheet() {
334  Sheet propertySheet = super.createSheet();
335  Sheet.Set properties = propertySheet.get(Sheet.PROPERTIES);
336  if (properties == null) {
337  properties = Sheet.createPropertiesSet();
338  propertySheet.put(properties);
339  }
340  properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "TagNameNode.createSheet.name.name"),
341  NbBundle.getMessage(this.getClass(), "TagNameNode.createSheet.name.displayName"), tagName.getDescription(), getName()));
342  return propertySheet;
343  }
344 
345  @Override
346  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
347  // See classes derived from DisplayableItemNodeVisitor<AbstractNode>
348  // for behavior added using the Visitor pattern.
349  return visitor.visit(this);
350  }
351 
352  @Override
353  public boolean isLeafTypeNode() {
354  return false;
355  }
356 
357  @Override
358  public void update(Observable o, Object arg) {
360  }
361 
362  @Override
363  public String getItemType() {
364  return getClass().getName();
365  }
366  }
367 
372  private class TagTypeNodeFactory extends ChildFactory<String> {
373 
374  private final TagName tagName;
375  private final String CONTENT_TAG_TYPE_NODE_KEY = NbBundle.getMessage(TagNameNode.class, "TagNameNode.contentTagTypeNodeKey.text");
376  private final String BLACKBOARD_ARTIFACT_TAG_TYPE_NODE_KEY = NbBundle.getMessage(TagNameNode.class, "TagNameNode.bbArtTagTypeNodeKey.text");
377 
378  TagTypeNodeFactory(TagName tagName) {
379  super();
380  this.tagName = tagName;
381  }
382 
383  @Override
384  protected boolean createKeys(List<String> keys) {
385  keys.add(CONTENT_TAG_TYPE_NODE_KEY);
386  keys.add(BLACKBOARD_ARTIFACT_TAG_TYPE_NODE_KEY);
387  return true;
388  }
389 
390  @Override
391  protected Node createNodeForKey(String key) {
392  if (CONTENT_TAG_TYPE_NODE_KEY.equals(key)) {
393  return new ContentTagTypeNode(tagName);
394  } else if (BLACKBOARD_ARTIFACT_TAG_TYPE_NODE_KEY.equals(key)) {
395  return new BlackboardArtifactTagTypeNode(tagName);
396  } else {
397  Logger.getLogger(TagNameNode.class.getName()).log(Level.SEVERE, "{0} not a recognized key", key); //NON-NLS
398  return null;
399  }
400  }
401  }
402 
403  private final String CONTENT_DISPLAY_NAME = NbBundle.getMessage(ContentTagTypeNode.class, "ContentTagTypeNode.displayName.text");
404 
411  public class ContentTagTypeNode extends DisplayableItemNode implements Observer {
412 
413  private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
414  private final TagName tagName;
415 
416  public ContentTagTypeNode(TagName tagName) {
417  super(Children.create(new ContentTagNodeFactory(tagName), true), Lookups.singleton(tagName.getDisplayName() + " " + CONTENT_DISPLAY_NAME));
418  this.tagName = tagName;
419  super.setName(CONTENT_DISPLAY_NAME);
421  this.setIconBaseWithExtension(ICON_PATH);
422  tagResults.addObserver(this);
423  }
424 
425  private void updateDisplayName() {
426  long tagsCount = 0;
427  try {
428 
430  String userName = System.getProperty(USER_NAME_PROPERTY);
431  tagsCount = (filteringDSObjId > 0)
432  ? Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsCountByTagNameForUser(tagName, filteringDSObjId, userName)
434  } else {
435  tagsCount = (filteringDSObjId > 0)
438  }
439  } catch (TskCoreException | NoCurrentCaseException ex) {
440  Logger.getLogger(ContentTagTypeNode.class.getName()).log(Level.SEVERE, "Failed to get content tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
441  }
442  super.setDisplayName(CONTENT_DISPLAY_NAME + " (" + tagsCount + ")");
443  }
444 
445  @Override
446  protected Sheet createSheet() {
447  Sheet propertySheet = super.createSheet();
448  Sheet.Set properties = propertySheet.get(Sheet.PROPERTIES);
449  if (properties == null) {
450  properties = Sheet.createPropertiesSet();
451  propertySheet.put(properties);
452  }
453  properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagTypeNode.createSheet.name.name"),
454  NbBundle.getMessage(this.getClass(), "ContentTagTypeNode.createSheet.name.displayName"), "", getName()));
455  return propertySheet;
456  }
457 
458  @Override
459  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
460  return visitor.visit(this);
461  }
462 
463  @Override
464  public boolean isLeafTypeNode() {
465  return true;
466  }
467 
468  @Override
469  public void update(Observable o, Object arg) {
471  }
472 
473  @Override
474  public String getItemType() {
475  return getClass().getName();
476  }
477  }
478 
479  private class ContentTagNodeFactory extends ChildFactory<ContentTag> implements Observer {
480 
481  private final TagName tagName;
482 
483  ContentTagNodeFactory(TagName tagName) {
484  super();
485  this.tagName = tagName;
486  tagResults.addObserver(this);
487  }
488 
489  @Override
490  protected boolean createKeys(List<ContentTag> keys) {
491  // Use the content tags bearing the specified tag name as the keys.
492  try {
493  List<ContentTag> contentTags = (filteringDSObjId > 0)
497  String userName = System.getProperty(USER_NAME_PROPERTY);
498  for (ContentTag tag : contentTags) {
499  if (userName.equals(tag.getUserName())) {
500  keys.add(tag);
501  }
502  }
503  } else {
504  keys.addAll(contentTags);
505  }
506  } catch (TskCoreException | NoCurrentCaseException ex) {
507  Logger.getLogger(ContentTagNodeFactory.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
508  }
509  return true;
510  }
511 
512  @Override
513  protected Node createNodeForKey(ContentTag key) {
514  // The content tags to be wrapped are used as the keys.
515  return new ContentTagNode(key);
516  }
517 
518  @Override
519  public void update(Observable o, Object arg) {
520  refresh(true);
521  }
522  }
523 
524  private final String ARTIFACT_DISPLAY_NAME = NbBundle.getMessage(BlackboardArtifactTagTypeNode.class, "BlackboardArtifactTagTypeNode.displayName.text");
525 
532  public class BlackboardArtifactTagTypeNode extends DisplayableItemNode implements Observer {
533 
534  private final TagName tagName;
535  private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
536 
537  public BlackboardArtifactTagTypeNode(TagName tagName) {
538  super(Children.create(new BlackboardArtifactTagNodeFactory(tagName), true), Lookups.singleton(tagName.getDisplayName() + " " + ARTIFACT_DISPLAY_NAME));
539  this.tagName = tagName;
540  super.setName(ARTIFACT_DISPLAY_NAME);
541  this.setIconBaseWithExtension(ICON_PATH);
543  tagResults.addObserver(this);
544  }
545 
546  private void updateDisplayName() {
547  long tagsCount = 0;
548  try {
550  String userName = System.getProperty(USER_NAME_PROPERTY);
551  tagsCount = (filteringDSObjId > 0)
554  } else {
555  tagsCount = (filteringDSObjId > 0)
558  }
559  } catch (TskCoreException | NoCurrentCaseException ex) {
560  Logger.getLogger(BlackboardArtifactTagTypeNode.class.getName()).log(Level.SEVERE, "Failed to get blackboard artifact tags count for " + tagName.getDisplayName() + " tag name", ex); //NON-NLS
561  }
562  super.setDisplayName(ARTIFACT_DISPLAY_NAME + " (" + tagsCount + ")");
563  }
564 
565  @Override
566  protected Sheet createSheet() {
567  Sheet propertySheet = super.createSheet();
568  Sheet.Set properties = propertySheet.get(Sheet.PROPERTIES);
569  if (properties == null) {
570  properties = Sheet.createPropertiesSet();
571  propertySheet.put(properties);
572  }
573  properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagTypeNode.createSheet.name.name"),
574  NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagTypeNode.createSheet.name.displayName"), "", getName()));
575  return propertySheet;
576  }
577 
578  @Override
579  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
580  return visitor.visit(this);
581  }
582 
583  @Override
584  public boolean isLeafTypeNode() {
585  return true;
586  }
587 
588  @Override
589  public void update(Observable o, Object arg) {
591  }
592 
593  @Override
594  public String getItemType() {
595  return getClass().getName();
596  }
597  }
598 
599  private class BlackboardArtifactTagNodeFactory extends ChildFactory<BlackboardArtifactTag> implements Observer {
600 
601  private final TagName tagName;
602 
603  BlackboardArtifactTagNodeFactory(TagName tagName) {
604  super();
605  this.tagName = tagName;
606  tagResults.addObserver(this);
607  }
608 
609  @Override
610  protected boolean createKeys(List<BlackboardArtifactTag> keys) {
611  try {
612  // Use the blackboard artifact tags bearing the specified tag name as the keys.
613  List<BlackboardArtifactTag> artifactTags = (filteringDSObjId > 0)
617  String userName = System.getProperty(USER_NAME_PROPERTY);
618  for (BlackboardArtifactTag tag : artifactTags) {
619  if (userName.equals(tag.getUserName())) {
620  keys.add(tag);
621  }
622  }
623  } else {
624  keys.addAll(artifactTags);
625  }
626  } catch (TskCoreException | NoCurrentCaseException ex) {
627  Logger.getLogger(BlackboardArtifactTagNodeFactory.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
628  }
629  return true;
630  }
631 
632  @Override
633  protected Node createNodeForKey(BlackboardArtifactTag key) {
634  // The blackboard artifact tags to be wrapped are used as the keys.
635  return new BlackboardArtifactTagNode(key);
636  }
637 
638  @Override
639  public void update(Observable o, Object arg) {
640  refresh(true);
641  }
642  }
643 }
static synchronized IngestManager getInstance()
void update(Observable o, Object arg)
Definition: Tags.java:358
List< TagName > getTagNamesInUseForUser(String userName)
static String getTagsDisplayName()
Definition: Tags.java:80
void removeIngestJobEventListener(final PropertyChangeListener listener)
boolean createKeys(List< ContentTag > keys)
Definition: Tags.java:490
void addIngestJobEventListener(final PropertyChangeListener listener)
static final String DISPLAY_NAME
Definition: Tags.java:59
boolean createKeys(List< BlackboardArtifactTag > keys)
Definition: Tags.java:610
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
Definition: Tags.java:60
List< BlackboardArtifactTag > getBlackboardArtifactTagsByTagName(TagName tagName)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static String getDecoratedTagDisplayName(TagName tagName)
Definition: TagUtils.java:55
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:491
List< ContentTag > getContentTagsByTagName(TagName tagName)
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:536
long getContentTagsCountByTagNameForUser(TagName tagName, String userName)
long getBlackboardArtifactTagsCountByTagNameForUser(TagName tagName, String userName)
static final String USER_NAME_PROPERTY
Definition: Tags.java:61

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.