90 BaseArtifactNode(Children children, String icon, String name, String displayName) {
91 super(children, Lookups.singleton(name));
93 super.setDisplayName(displayName);
94 this.setIconBaseWithExtension(icon);
104 return visitor.
visit(
this);
108 protected Sheet createSheet() {
109 Sheet sheet = super.createSheet();
110 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
111 if (sheetSet ==
null) {
112 sheetSet = Sheet.createPropertiesSet();
116 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"ExtractedContentNode.createSheet.name.name"),
117 NbBundle.getMessage(
this.getClass(),
"ExtractedContentNode.createSheet.name.displayName"),
118 NbBundle.getMessage(
this.getClass(),
"ExtractedContentNode.createSheet.name.desc"),
119 super.getDisplayName()));
125 return getClass().getName();
132 private static class TypeNodeKey {
145 TypeNodeKey(BlackboardArtifact.Type type,
long dsObjId) {
146 this(
new TypeNode(type, dsObjId), type);
157 this.node = typeNode;
158 this.applicableTypes = Stream.of(types)
159 .filter(t -> t !=
null)
160 .collect(Collectors.toSet());
177 Set<BlackboardArtifact.Type> getApplicableTypes() {
196 if (getClass() != obj.getClass()) {
199 final TypeNodeKey other = (TypeNodeKey) obj;
212 static class TypeFactory
extends ChildFactory.Detachable<TypeNodeKey> implements
RefreshThrottler.Refresher {
219 @SuppressWarnings(
"deprecation")
220 private static final Set<BlackboardArtifact.Type> IGNORED_TYPES = Sets.newHashSet(
222 TSK_DATA_SOURCE_USAGE,
224 new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE),
227 TSK_ASSOCIATED_OBJECT
244 @SuppressWarnings(
"deprecation")
245 private static TypeNodeKey getTypeKey(BlackboardArtifact.Type type, SleuthkitCase skCase,
long dsObjId) {
247 int typeId = type.getTypeID();
248 if (TSK_EMAIL_MSG.getTypeID() == typeId) {
249 EmailExtracted.RootNode emailNode = new EmailExtracted(skCase, dsObjId).new RootNode();
250 return new TypeNodeKey(emailNode, TSK_EMAIL_MSG);
252 }
else if (TSK_ACCOUNT.getTypeID() == typeId) {
253 Accounts.AccountsRootNode accountsNode = new Accounts(dsObjId).new AccountsRootNode();
254 return new TypeNodeKey(accountsNode, TSK_ACCOUNT);
256 }
else if (TSK_KEYWORD_HIT.getTypeID() == typeId) {
257 KeywordHits.RootNode keywordsNode = new KeywordHits(skCase, dsObjId).new RootNode();
258 return new TypeNodeKey(keywordsNode, TSK_KEYWORD_HIT);
260 }
else if (TSK_INTERESTING_ITEM.getTypeID() == typeId) {
261 InterestingHits.RootNode interestingHitsNode = new InterestingHits(skCase, TSK_INTERESTING_ITEM, dsObjId).new RootNode();
262 return new TypeNodeKey(interestingHitsNode, TSK_INTERESTING_ITEM);
263 }
else if (TSK_INTERESTING_ARTIFACT_HIT.getTypeID() == typeId) {
264 InterestingHits.RootNode interestingHitsNode = new InterestingHits(skCase, TSK_INTERESTING_ARTIFACT_HIT, dsObjId).new RootNode();
265 return new TypeNodeKey(interestingHitsNode, TSK_INTERESTING_ARTIFACT_HIT);
266 }
else if (TSK_INTERESTING_FILE_HIT.getTypeID() == typeId) {
267 InterestingHits.RootNode interestingHitsNode = new InterestingHits(skCase, TSK_INTERESTING_FILE_HIT, dsObjId).new RootNode();
268 return new TypeNodeKey(interestingHitsNode, TSK_INTERESTING_FILE_HIT);
269 }
else if (TSK_HASHSET_HIT.getTypeID() == typeId) {
270 HashsetHits.RootNode hashsetHits = new HashsetHits(skCase, dsObjId).new RootNode();
271 return new TypeNodeKey(hashsetHits, TSK_HASHSET_HIT);
272 }
else if (TSK_MALWARE.getTypeID() == typeId) {
273 MalwareHits.RootNode malwareHits = new MalwareHits(skCase, dsObjId).new RootNode();
274 return new TypeNodeKey(malwareHits, TSK_MALWARE);
276 return new TypeNodeKey(type, dsObjId);
281 private final Map<BlackboardArtifact.Type, TypeNodeKey> typeNodeMap =
new HashMap<>();
282 private final long filteringDSObjId;
289 private final RefreshThrottler refreshThrottler =
new RefreshThrottler(
this);
290 private final Category category;
292 private final PropertyChangeListener weakPcl;
302 TypeFactory(Category category,
long filteringDSObjId) {
304 this.filteringDSObjId = filteringDSObjId;
305 this.category = category;
307 PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
308 String eventType = evt.getPropertyName();
309 if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
311 if (evt.getNewValue() ==
null) {
314 }
else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
315 || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
323 Case.getCurrentCaseThrows();
325 }
catch (NoCurrentCaseException notUsed) {
333 weakPcl = WeakListeners.propertyChange(pcl,
null);
337 protected void addNotify() {
339 refreshThrottler.registerForIngestModuleEvents();
341 Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
345 protected void finalize() throws Throwable {
347 refreshThrottler.unregisterEventListener();
348 IngestManager.getInstance().removeIngestJobEventListener(weakPcl);
349 Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), weakPcl);
354 protected boolean createKeys(List<TypeNodeKey> list) {
357 SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
358 List<BlackboardArtifact.Type> types = (this.filteringDSObjId > 0)
359 ? skCase.getBlackboard().getArtifactTypesInUse(this.filteringDSObjId)
360 : skCase.getArtifactTypesInUse();
362 List<TypeNodeKey> allKeysSorted = types.stream()
364 .filter(tp -> category.equals(tp.getCategory()) && !IGNORED_TYPES.contains(tp))
367 if (typeNodeMap.containsKey(tp)) {
368 TypeNodeKey typeKey = typeNodeMap.get(tp);
369 typeKey.getNode().updateDisplayName();
373 TypeNodeKey newTypeKey = getTypeKey(tp, skCase, filteringDSObjId);
374 for (BlackboardArtifact.Type recordType : newTypeKey.getApplicableTypes()) {
375 typeNodeMap.put(recordType, newTypeKey);
381 .filter(record -> record !=
null)
387 String aSafe = (a.getNode() ==
null || a.getNode().getDisplayName() ==
null) ?
"" : a.getNode().getDisplayName();
388 String bSafe = (b.getNode() ==
null || b.getNode().getDisplayName() ==
null) ?
"" : b.getNode().getDisplayName();
389 return aSafe.compareToIgnoreCase(bSafe);
391 .collect(Collectors.toList());
393 list.addAll(allKeysSorted);
395 }
catch (NoCurrentCaseException ex) {
396 logger.log(Level.WARNING,
"Trying to access case when no case is open.", ex);
397 }
catch (TskCoreException ex) {
398 logger.log(Level.SEVERE,
"Error getting list of artifacts in use: " + ex.getLocalizedMessage());
404 protected Node createNodeForKey(TypeNodeKey key) {
405 return key.getNode();
414 public boolean isRefreshRequired(PropertyChangeEvent evt) {
415 String eventType = evt.getPropertyName();
416 if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
423 Case.getCurrentCaseThrows();
429 final ModuleDataEvent
event = (ModuleDataEvent) evt.getOldValue();
430 if (
null != event && category.equals(event.getBlackboardArtifactType().getCategory())
431 && !(IGNORED_TYPES.contains(event.getBlackboardArtifactType()))) {
434 }
catch (NoCurrentCaseException notUsed) {
452 private final Set<BlackboardArtifact.Type>
types;
472 super(children, lookup);
473 this.types = Stream.of(
types).collect(Collectors.toSet());
485 return this.childCount;
499 for (BlackboardArtifact.Type type :
this.types) {
501 count += skCase.getBlackboard().getArtifactsCount(type.getTypeID(),
filteringDSObjId);
503 count += skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
513 void updateDisplayName() {
518 logger.log(Level.WARNING,
"Error fetching data when case closed.", ex);
519 }
catch (TskCoreException ex) {
520 logger.log(Level.WARNING,
"Error getting child count", ex);
522 super.setDisplayName(this.baseName +
" (" + this.childCount +
")");
532 static class TypeNode
extends UpdatableCountTypeNode {
534 private final BlackboardArtifact.Type type;
546 Lookups.singleton(type.getDisplayName()),
547 type.getDisplayName(),
551 super.setName(type.getTypeName());
553 String iconPath = IconsUtil.getIconFilePath(type.getTypeID());
554 setIconBaseWithExtension(iconPath !=
null && iconPath.charAt(0) ==
'/' ? iconPath.substring(1) : iconPath);
558 protected Sheet createSheet() {
559 Sheet sheet = super.createSheet();
560 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
561 if (sheetSet ==
null) {
562 sheetSet = Sheet.createPropertiesSet();
566 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"ArtifactTypeNode.createSheet.artType.name"),
567 NbBundle.getMessage(
this.getClass(),
"ArtifactTypeNode.createSheet.artType.displayName"),
568 NbBundle.getMessage(
this.getClass(),
"ArtifactTypeNode.createSheet.artType.desc"),
569 type.getDisplayName()));
571 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"ArtifactTypeNode.createSheet.childCnt.name"),
572 NbBundle.getMessage(
this.getClass(),
"ArtifactTypeNode.createSheet.childCnt.displayName"),
573 NbBundle.getMessage(
this.getClass(),
"ArtifactTypeNode.createSheet.childCnt.desc"),
580 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
581 return visitor.visit(
this);
591 return getClass().getName() + type.getDisplayName();
601 private final BlackboardArtifact.Type
type;
620 super(
type.getTypeName());
625 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
626 String eventType = evt.getPropertyName();
646 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
670 List<? extends BlackboardArtifact> arts;
672 switch (this.type.getCategory()) {
674 case ANALYSIS_RESULT:
677 : blackboard.getAnalysisResultsByType(
type.getTypeID());
683 : blackboard.getDataArtifacts(
type.getTypeID());
687 for (BlackboardArtifact art : arts) {
693 @SuppressWarnings(
"unchecked")
694 List<BlackboardArtifact> toRet = (List<BlackboardArtifact>) (List<?>) arts;
697 logger.log(Level.WARNING,
"Trying to access case when no case is open.", ex);
698 }
catch (TskCoreException ex) {
699 logger.log(Level.SEVERE,
"Couldn't get blackboard artifacts from database", ex);
701 return Collections.emptyList();
711 String eventType = evt.getPropertyName();
729 if (
null != event && event.getBlackboardArtifactType().equals(
type)) {