counts in special artifact nodes

This commit is contained in:
Greg DiCristofaro 2021-04-30 11:01:09 -04:00
parent e2f83a897a
commit eadb3a8c6b
6 changed files with 125 additions and 84 deletions

View File

@ -32,7 +32,6 @@ import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.commons.lang3.tuple.Pair;
import org.openide.nodes.ChildFactory; import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
@ -45,10 +44,12 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.ExtractedContent.UpdatableTypeCountNode;
/** /**
* Support for TSK_EMAIL_MSG nodes and displaying emails in the directory tree. * Support for TSK_EMAIL_MSG nodes and displaying emails in the directory tree.
@ -59,7 +60,6 @@ import org.sleuthkit.datamodel.TskCoreException;
public class EmailExtracted implements AutopsyVisitableItem { public class EmailExtracted implements AutopsyVisitableItem {
private static final String LABEL_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getLabel(); private static final String LABEL_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getLabel();
private static final String DISPLAY_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getDisplayName();
private static final Logger logger = Logger.getLogger(EmailExtracted.class.getName()); private static final Logger logger = Logger.getLogger(EmailExtracted.class.getName());
private static final String MAIL_ACCOUNT = NbBundle.getMessage(EmailExtracted.class, "EmailExtracted.mailAccount.text"); private static final String MAIL_ACCOUNT = NbBundle.getMessage(EmailExtracted.class, "EmailExtracted.mailAccount.text");
private static final String MAIL_FOLDER = NbBundle.getMessage(EmailExtracted.class, "EmailExtracted.mailFolder.text"); private static final String MAIL_FOLDER = NbBundle.getMessage(EmailExtracted.class, "EmailExtracted.mailFolder.text");
@ -91,14 +91,6 @@ public class EmailExtracted implements AutopsyVisitableItem {
private SleuthkitCase skCase; private SleuthkitCase skCase;
private final EmailResults emailResults; private final EmailResults emailResults;
private final long filteringDSObjId; // 0 if not filtering/grouping by data source private final long filteringDSObjId; // 0 if not filtering/grouping by data source
/**
* Returns the display name for this module.
* @return The display name for this module.
*/
static String getDisplayName() {
return DISPLAY_NAME;
}
/** /**
* Constructor * Constructor
@ -213,12 +205,16 @@ public class EmailExtracted implements AutopsyVisitableItem {
* Mail root node grouping all mail accounts, supports account-> folder * Mail root node grouping all mail accounts, supports account-> folder
* structure * structure
*/ */
public class RootNode extends DisplayableItemNode { public class RootNode extends UpdatableTypeCountNode {
public RootNode() { public RootNode() {
super(Children.create(new AccountFactory(), true), Lookups.singleton(DISPLAY_NAME)); super(Children.create(new AccountFactory(), true),
Lookups.singleton(TSK_EMAIL_MSG.getDisplayName()),
TSK_EMAIL_MSG.getDisplayName(),
filteringDSObjId,
new BlackboardArtifact.Type(TSK_EMAIL_MSG));
//super(Children.create(new AccountFactory(), true), Lookups.singleton(DISPLAY_NAME));
super.setName(LABEL_NAME); super.setName(LABEL_NAME);
super.setDisplayName(DISPLAY_NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/mail-icon-16.png"); //NON-NLS this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/mail-icon-16.png"); //NON-NLS
emailResults.update(); emailResults.update();
} }

View File

@ -20,9 +20,11 @@ package org.sleuthkit.autopsy.datamodel;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
@ -32,6 +34,7 @@ import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.nodes.Sheet; import org.openide.nodes.Sheet;
import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.Lookups; import org.openide.util.lookup.Lookups;
@ -185,12 +188,14 @@ public class ExtractedContent implements AutopsyVisitableItem {
} }
private static class AnalysisResultsTypeFactory extends TypeFactory { private static class AnalysisResultsTypeFactory extends TypeFactory {
AnalysisResultsTypeFactory(long filteringDSObjId) { AnalysisResultsTypeFactory(long filteringDSObjId) {
super(Category.ANALYSIS_RESULT, filteringDSObjId); super(Category.ANALYSIS_RESULT, filteringDSObjId);
} }
} }
private static class DataArtifactsTypeFactory extends TypeFactory { private static class DataArtifactsTypeFactory extends TypeFactory {
DataArtifactsTypeFactory(long filteringDSObjId) { DataArtifactsTypeFactory(long filteringDSObjId) {
super(Category.DATA_ARTIFACT, filteringDSObjId); super(Category.DATA_ARTIFACT, filteringDSObjId);
} }
@ -274,7 +279,9 @@ public class ExtractedContent implements AutopsyVisitableItem {
null, null,
Sets.newHashSet(new BlackboardArtifact.Type(TSK_KEYWORD_HIT))); Sets.newHashSet(new BlackboardArtifact.Type(TSK_KEYWORD_HIT)));
} else if (TSK_EMAIL_MSG.getTypeID() == typeId) { } else if (TSK_INTERESTING_ARTIFACT_HIT.getTypeID() == typeId ||
TSK_INTERESTING_FILE_HIT.getTypeID() == typeId) {
InterestingHits.RootNode interestingHitsNode = new InterestingHits(skCase, dsObjId).new RootNode(); InterestingHits.RootNode interestingHitsNode = new InterestingHits(skCase, dsObjId).new RootNode();
return new TypeNodeRecord( return new TypeNodeRecord(
interestingHitsNode, interestingHitsNode,
@ -351,13 +358,11 @@ public class ExtractedContent implements AutopsyVisitableItem {
protected boolean createKeys(List<TypeNodeRecord> list) { protected boolean createKeys(List<TypeNodeRecord> list) {
try { try {
// Potentially can reuse
List<BlackboardArtifact.Type> types = (this.filteringDSObjId > 0)
? Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().getArtifactTypesInUse(this.filteringDSObjId)
: Case.getCurrentCaseThrows().getSleuthkitCase().getArtifactTypesInUse();
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
List<BlackboardArtifact.Type> types = (this.filteringDSObjId > 0)
? skCase.getBlackboard().getArtifactTypesInUse(this.filteringDSObjId)
: skCase.getArtifactTypesInUse();
List<TypeNodeRecord> allKeysSorted = types.stream() List<TypeNodeRecord> allKeysSorted = types.stream()
.filter(tp -> category.equals(tp.getCategory()) && !IGNORED_TYPES.contains(tp)) .filter(tp -> category.equals(tp.getCategory()) && !IGNORED_TYPES.contains(tp))
.map(tp -> { .map(tp -> {
@ -435,41 +440,84 @@ public class ExtractedContent implements AutopsyVisitableItem {
} }
} }
public static abstract class UpdatableTypeCountNode extends DisplayableItemNode {
private static final Logger logger = Logger.getLogger(UpdatableTypeCountNode.class.getName());
private final Set<BlackboardArtifact.Type> types;
private final long filteringDSObjId;
private long childCount = 0;
private final String baseName;
/**
* Constructs a node that is eligible for display in the tree view or
* results view. Capabilitites include accepting a
* DisplayableItemNodeVisitor, indicating whether or not the node is a
* leaf node, providing an item type string suitable for use as a key,
* and storing information about a child node that is to be selected if
* the node is selected in the tree view.
*
* @param children The Children object for the node.
* @param lookup The Lookup object for the node.
*/
public UpdatableTypeCountNode(Children children, Lookup lookup, String baseName, long filteringDSObjId, BlackboardArtifact.Type... types) {
super(children, lookup);
this.types = Stream.of(types).collect(Collectors.toSet());
this.filteringDSObjId = filteringDSObjId;
this.baseName = baseName;
updateDisplayName();
}
protected long getChildCount() {
return this.childCount;
}
void updateDisplayName() {
try {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
int count = 0;
for (BlackboardArtifact.Type type : this.types) {
if (filteringDSObjId > 0) {
count += skCase.getBlackboard().getArtifactsCount(type.getTypeID(), filteringDSObjId);
} else {
count += skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
}
}
this.childCount = count;
} catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Error fetching data when case closed.", ex);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error getting child count", ex); //NON-NLS
}
super.setDisplayName(this.baseName + " \u200E(\u200E" + this.childCount + ")\u200E");
}
}
/** /**
* Node encapsulating blackboard artifact type. This is used on the * Node encapsulating blackboard artifact type. This is used on the
* left-hand navigation side of the Autopsy UI as the parent node for all of * left-hand navigation side of the Autopsy UI as the parent node for all of
* the artifacts of a given type. Its children will be * the artifacts of a given type. Its children will be
* BlackboardArtifactNode objects. * BlackboardArtifactNode objects.
*/ */
public static class TypeNode extends DisplayableItemNode { public static class TypeNode extends UpdatableTypeCountNode {
private static final Logger logger = Logger.getLogger(TypeNode.class.getName()); private static final Logger logger = Logger.getLogger(TypeNode.class.getName());
private final BlackboardArtifact.Type type; private final BlackboardArtifact.Type type;
private long childCount = 0;
private final long filteringDSObjId;
TypeNode(BlackboardArtifact.Type type, long filteringDSObjId) { TypeNode(BlackboardArtifact.Type type, long filteringDSObjId) {
super(Children.create(new ArtifactFactory(type, filteringDSObjId), true), Lookups.singleton(type.getDisplayName())); super(Children.create(new ArtifactFactory(type, filteringDSObjId), true),
Lookups.singleton(type.getDisplayName()),
type.getDisplayName(),
filteringDSObjId,
type);
super.setName(type.getTypeName()); super.setName(type.getTypeName());
this.type = type; this.type = type;
this.filteringDSObjId = filteringDSObjId;
String iconPath = IconsUtil.getIconFilePath(type.getTypeID()); String iconPath = IconsUtil.getIconFilePath(type.getTypeID());
setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) == '/' ? iconPath.substring(1) : iconPath); setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) == '/' ? iconPath.substring(1) : iconPath);
updateDisplayName();
}
final void updateDisplayName() {
try {
this.childCount = (filteringDSObjId > 0)
? Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard().getArtifactsCount(type.getTypeID(), filteringDSObjId)
: Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifactsTypeCount(type.getTypeID());
} catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Error fetching data when case closed.", ex);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error getting child count", ex); //NON-NLS
}
super.setDisplayName(type.getDisplayName() + " \u200E(\u200E" + childCount + ")\u200E");
} }
@Override @Override
@ -489,7 +537,7 @@ public class ExtractedContent implements AutopsyVisitableItem {
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.name"), sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.name"),
NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.displayName"), NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.displayName"),
NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.desc"), NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.desc"),
childCount)); getChildCount()));
return sheet; return sheet;
} }

View File

@ -47,10 +47,14 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.ExtractedContent.UpdatableTypeCountNode;
/** /**
* Hash set hits node support. Inner classes have all of the nodes in the tree. * Hash set hits node support. Inner classes have all of the nodes in the tree.
@ -66,13 +70,6 @@ public class HashsetHits implements AutopsyVisitableItem {
private final HashsetResults hashsetResults; private final HashsetResults hashsetResults;
private final long filteringDSObjId; // 0 if not filtering/grouping by data source private final long filteringDSObjId; // 0 if not filtering/grouping by data source
/**
* Returns the display name for this module.
* @return The display name for this module.
*/
static String getDisplayName() {
return DISPLAY_NAME;
}
/** /**
* Constructor * Constructor
@ -176,10 +173,15 @@ public class HashsetHits implements AutopsyVisitableItem {
/** /**
* Top-level node for all hash sets * Top-level node for all hash sets
*/ */
public class RootNode extends DisplayableItemNode { public class RootNode extends UpdatableTypeCountNode {
public RootNode() { public RootNode() {
super(Children.create(new HashsetNameFactory(), true), Lookups.singleton(DISPLAY_NAME)); super(Children.create(new HashsetNameFactory(), true),
Lookups.singleton(DISPLAY_NAME),
DISPLAY_NAME,
filteringDSObjId,
new BlackboardArtifact.Type(TSK_HASHSET_HIT));
super.setName(HASHSET_HITS); super.setName(HASHSET_HITS);
super.setDisplayName(DISPLAY_NAME); super.setDisplayName(DISPLAY_NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hashset_hits.png"); //NON-NLS this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hashset_hits.png"); //NON-NLS

View File

@ -50,6 +50,9 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.datamodel.ExtractedContent.UpdatableTypeCountNode;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
public class InterestingHits implements AutopsyVisitableItem { public class InterestingHits implements AutopsyVisitableItem {
@ -63,14 +66,6 @@ public class InterestingHits implements AutopsyVisitableItem {
private final InterestingResults interestingResults = new InterestingResults(); private final InterestingResults interestingResults = new InterestingResults();
private final long filteringDSObjId; // 0 if not filtering/grouping by data source private final long filteringDSObjId; // 0 if not filtering/grouping by data source
/**
* Returns the display name for this module.
* @return The display name for this module.
*/
static String getDisplayName() {
return DISPLAY_NAME;
}
/** /**
* Constructor * Constructor
* *
@ -173,12 +168,16 @@ public class InterestingHits implements AutopsyVisitableItem {
/** /**
* Node for the interesting items * Node for the interesting items
*/ */
public class RootNode extends DisplayableItemNode { public class RootNode extends UpdatableTypeCountNode {
public RootNode() { public RootNode() {
super(Children.create(new SetNameFactory(), true), Lookups.singleton(DISPLAY_NAME)); super(Children.create(new SetNameFactory(), true),
Lookups.singleton(DISPLAY_NAME),
DISPLAY_NAME,
filteringDSObjId,
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT),
new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT));
super.setName(INTERESTING_ITEMS); super.setName(INTERESTING_ITEMS);
super.setDisplayName(DISPLAY_NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/interesting_item.png"); //NON-NLS this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/interesting_item.png"); //NON-NLS
} }

View File

@ -55,6 +55,8 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
import org.sleuthkit.autopsy.datamodel.ExtractedContent.UpdatableTypeCountNode;
/** /**
* Keyword hits node support * Keyword hits node support
@ -104,15 +106,6 @@ public class KeywordHits implements AutopsyVisitableItem {
return (instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME)); return (instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME));
} }
/**
* Returns the display name for KeywordHits.
* @return The display name for KeywordHits.
*/
static String getDisplayName() {
return KEYWORD_HITS;
}
/** /**
* Constructor * Constructor
* *
@ -384,12 +377,16 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
// Created by CreateAutopsyNodeVisitor // Created by CreateAutopsyNodeVisitor
public class RootNode extends DisplayableItemNode { public class RootNode extends UpdatableTypeCountNode {
public RootNode() { public RootNode() {
super(Children.create(new ListFactory(), true), Lookups.singleton(KEYWORD_HITS)); super(Children.create(new ListFactory(), true),
Lookups.singleton(KEYWORD_HITS),
KEYWORD_HITS,
filteringDSObjId,
new BlackboardArtifact.Type(TSK_KEYWORD_HIT));
super.setName(NAME); super.setName(NAME);
super.setDisplayName(KEYWORD_HITS);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/keyword_hits.png"); //NON-NLS this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/keyword_hits.png"); //NON-NLS
} }

View File

@ -69,6 +69,8 @@ import org.sleuthkit.autopsy.datamodel.CreditCards;
import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory; import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory;
import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.DisplayableItemNode;
import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor; import org.sleuthkit.autopsy.datamodel.DisplayableItemNodeVisitor;
import org.sleuthkit.autopsy.datamodel.ExtractedContent;
import org.sleuthkit.autopsy.datamodel.ExtractedContent.UpdatableTypeCountNode;
import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.datamodel.NodeProperty;
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
@ -77,6 +79,7 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
@ -115,14 +118,6 @@ final public class Accounts implements AutopsyVisitableItem {
private final AccountTypeResults accountTypeResults; private final AccountTypeResults accountTypeResults;
/**
* Returns the display name for this module.
* @return The display name for this module.
*/
public static String getDisplayName() {
return DISPLAY_NAME;
}
/** /**
* Constructor * Constructor
* *
@ -241,12 +236,16 @@ final public class Accounts implements AutopsyVisitableItem {
* Top-level node for the accounts tree * Top-level node for the accounts tree
*/ */
@NbBundle.Messages({"Accounts.RootNode.displayName=Accounts"}) @NbBundle.Messages({"Accounts.RootNode.displayName=Accounts"})
final public class AccountsRootNode extends DisplayableItemNode { final public class AccountsRootNode extends UpdatableTypeCountNode {
public AccountsRootNode() { public AccountsRootNode() {
super(Children.create(new AccountTypeFactory(), true), Lookups.singleton(Accounts.this)); super(Children.create(new AccountTypeFactory(), true),
Lookups.singleton(Accounts.this),
DISPLAY_NAME,
filteringDSObjId,
new BlackboardArtifact.Type(TSK_ACCOUNT));
setName(Accounts.NAME); setName(Accounts.NAME);
setDisplayName(DISPLAY_NAME);
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/accounts.png"); //NON-NLS this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/accounts.png"); //NON-NLS
} }
@ -303,7 +302,7 @@ final public class Accounts implements AutopsyVisitableItem {
= "SELECT blackboard_attributes.value_text as account_type, COUNT(*) as count " = "SELECT blackboard_attributes.value_text as account_type, COUNT(*) as count "
+ " FROM blackboard_artifacts " //NON-NLS + " FROM blackboard_artifacts " //NON-NLS
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS + " WHERE blackboard_artifacts.artifact_type_id = " + TSK_ACCOUNT.getTypeID() //NON-NLS
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS + " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS
+ getFilterByDataSourceClause() + getFilterByDataSourceClause()
+ " GROUP BY blackboard_attributes.value_text "; + " GROUP BY blackboard_attributes.value_text ";