19 package org.sleuthkit.autopsy.datamodel;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.LinkedHashMap;
30 import java.util.List;
32 import java.util.Observable;
33 import java.util.Observer;
35 import java.util.logging.Level;
36 import org.openide.nodes.ChildFactory;
37 import org.openide.nodes.Children;
38 import org.openide.nodes.Node;
39 import org.openide.nodes.Sheet;
40 import org.openide.util.NbBundle;
41 import org.openide.util.lookup.Lookups;
64 .getMessage(
KeywordHits.class,
"KeywordHits.simpleLiteralSearch.text");
66 .getMessage(
KeywordHits.class,
"KeywordHits.singleRegexSearch.text");
87 private final Map<String, Map<String, Map<String, Set<Long>>>>
topLevelMap =
new LinkedHashMap<>();
96 List<String> getListNames() {
98 List<String> names =
new ArrayList<>(topLevelMap.keySet());
113 List<String> getKeywords(String listName) {
114 List<String> keywords;
116 keywords =
new ArrayList<>(topLevelMap.get(listName).keySet());
118 Collections.sort(keywords);
131 List<String> getKeywordInstances(String listName, String keyword) {
132 List<String> instances;
134 instances =
new ArrayList<>(topLevelMap.get(listName).get(keyword).keySet());
136 Collections.sort(instances);
147 Set<Long> getArtifactIds(String listName, String keyword, String keywordInstance) {
149 return topLevelMap.get(listName).get(keyword).get(keywordInstance);
160 void addRegExpToList(Map<String, Map<String, Set<Long>>> listMap, String regExp, String keywordInstance, Long artifactId) {
161 if (listMap.containsKey(regExp) ==
false) {
162 listMap.put(regExp,
new LinkedHashMap<>());
164 Map<String, Set<Long>> instanceMap = listMap.get(regExp);
167 if (instanceMap.containsKey(keywordInstance) ==
false) {
168 instanceMap.put(keywordInstance,
new HashSet<>());
172 instanceMap.get(keywordInstance).add(artifactId);
182 void addNonRegExpMatchToList(Map<String, Map<String, Set<Long>>> listMap, String keyWord, Long artifactId) {
183 if (listMap.containsKey(keyWord) ==
false) {
184 listMap.put(keyWord,
new LinkedHashMap<>());
186 Map<String, Set<Long>> instanceMap = listMap.get(keyWord);
189 if (instanceMap.containsKey(DEFAULT_INSTANCE_NAME) ==
false) {
190 instanceMap.put(DEFAULT_INSTANCE_NAME,
new HashSet<>());
192 instanceMap.get(DEFAULT_INSTANCE_NAME).add(artifactId);
199 void populateTreeMaps(Map<Long, Map<Long, String>> artifactIds) {
204 Map<String, Map<String, Map<String, Set<Long>>>> listsMap =
new LinkedHashMap<>();
207 Map<String, Map<String, Set<Long>>> literalMap =
new LinkedHashMap<>();
210 Map<String, Map<String, Set<Long>>> regexMap =
new LinkedHashMap<>();
213 topLevelMap.put(SIMPLE_LITERAL_SEARCH, literalMap);
214 topLevelMap.put(SIMPLE_REGEX_SEARCH, regexMap);
216 for (Map.Entry<Long, Map<Long, String>> art : artifactIds.entrySet()) {
217 long id = art.getKey();
218 Map<Long, String> attributes = art.getValue();
221 String listName = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
222 String word = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()));
223 String reg = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()));
225 String kwType = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()));
228 if (listName != null) {
230 if (listsMap.containsKey(listName) ==
false) {
231 listsMap.put(listName,
new LinkedHashMap<>());
233 Map<String, Map<String, Set<Long>>> listMap = listsMap.get(listName);
237 if ((kwType != null) && (kwType.equals(
"1"))) {
240 addNonRegExpMatchToList(listMap, reg,
id);
242 addNonRegExpMatchToList(listMap, word,
id);
245 else if (reg != null) {
246 addRegExpToList(listMap, reg, word,
id);
248 addNonRegExpMatchToList(listMap, word,
id);
251 else if (reg != null) {
253 if ((kwType != null) && (kwType.equals(
"1"))) {
255 addNonRegExpMatchToList(literalMap, reg,
id);
257 addRegExpToList(regexMap, reg, word,
id);
261 addNonRegExpMatchToList(literalMap, word,
id);
264 topLevelMap.putAll(listsMap);
271 @SuppressWarnings(
"deprecation")
274 Map<Long, Map<Long, String>> artifactIds =
new LinkedHashMap<>();
276 if (skCase == null) {
285 String query =
"SELECT blackboard_attributes.value_text,blackboard_attributes.value_int32,"
286 +
"blackboard_attributes.artifact_id,"
287 +
"blackboard_attributes.attribute_type_id FROM blackboard_attributes,blackboard_artifacts WHERE "
288 +
"(blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id AND "
289 +
"blackboard_artifacts.artifact_type_id=" + artId
290 +
") AND (attribute_type_id=" + setId +
" OR "
291 +
"attribute_type_id=" + wordId +
" OR "
293 +
"attribute_type_id=" + regexId +
")";
296 ResultSet resultSet = dbQuery.getResultSet();
297 while (resultSet.next()) {
298 String valueStr = resultSet.getString(
"value_text");
299 long artifactId = resultSet.getLong(
"artifact_id");
300 long typeId = resultSet.getLong(
"attribute_type_id");
301 if (!artifactIds.containsKey(artifactId)) {
302 artifactIds.put(artifactId,
new LinkedHashMap<Long, String>());
304 if (valueStr != null && !valueStr.equals(
"")) {
305 artifactIds.get(artifactId).put(typeId, valueStr);
308 Long valueLong = resultSet.getLong(
"value_int32");
309 artifactIds.get(artifactId).put(typeId, valueLong.toString());
313 logger.log(Level.WARNING,
"SQL Exception occurred: ", ex);
316 populateTreeMaps(artifactIds);
322 return v.
visit(
this);
329 super(Children.create(
new ListFactory(),
true), Lookups.singleton(KEYWORD_HITS));
331 super.setDisplayName(KEYWORD_HITS);
332 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
342 return v.
visit(
this);
347 Sheet s = super.createSheet();
348 Sheet.Set ss = s.get(Sheet.PROPERTIES);
350 ss = Sheet.createPropertiesSet();
354 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.name.name"),
355 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.name.displayName"),
356 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.name.desc"),
364 return getClass().getName();
371 private class ListFactory extends ChildFactory.Detachable<String> implements Observer {
373 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
375 public void propertyChange(PropertyChangeEvent evt) {
376 String eventType = evt.getPropertyName();
396 }
catch (IllegalStateException notUsed) {
412 }
catch (IllegalStateException notUsed) {
419 if (evt.getNewValue() == null) {
433 keywordResults.addObserver(
this);
441 keywordResults.deleteObserver(
this);
446 list.addAll(keywordResults.getListNames());
456 public void update(Observable o, Object arg) {
469 super(Children.create(
new TermFactory(listName),
true), Lookups.singleton(listName));
470 super.setName(listName);
471 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
474 keywordResults.addObserver(
this);
478 int totalDescendants = 0;
479 for (String word : keywordResults.getKeywords(listName)) {
480 for (String instance : keywordResults.getKeywordInstances(listName, word)) {
481 Set<Long> ids = keywordResults.getArtifactIds(listName, word, instance);
482 totalDescendants += ids.size();
485 super.setDisplayName(listName +
" (" + totalDescendants +
")");
490 Sheet s = super.createSheet();
491 Sheet.Set ss = s.get(Sheet.PROPERTIES);
493 ss = Sheet.createPropertiesSet();
497 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.name"),
498 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.displayName"),
499 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.desc"),
502 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.numChildren.name"),
503 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.numChildren.displayName"),
504 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.numChildren.desc"),
505 keywordResults.getKeywords(listName).size()));
517 return v.
visit(
this);
521 public void update(Observable o, Object arg) {
527 return getClass().getName();
534 private class TermFactory extends ChildFactory.Detachable<String> implements Observer {
545 keywordResults.addObserver(
this);
550 keywordResults.deleteObserver(
this);
555 list.addAll(keywordResults.getKeywords(setName));
565 public void update(Observable o, Object arg) {
580 super.setName(keyword);
583 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
585 keywordResults.addObserver(
this);
589 int totalDescendants = 0;
591 for (String instance : keywordResults.getKeywordInstances(setName, keyword)) {
592 Set<Long> ids = keywordResults.getArtifactIds(setName, keyword, instance);
593 totalDescendants += ids.size();
596 super.setDisplayName(keyword +
" (" + totalDescendants +
")");
600 public void update(Observable o, Object arg) {
606 List<String> instances = keywordResults.getKeywordInstances(setName, keyword);
608 if (instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME)) {
618 return v.
visit(
this);
623 Sheet s = super.createSheet();
624 Sheet.Set ss = s.get(Sheet.PROPERTIES);
626 ss = Sheet.createPropertiesSet();
630 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.name"),
631 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.displayName"),
632 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.desc"),
635 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.name"),
636 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.displayName"),
637 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.desc"),
638 keywordResults.getKeywordInstances(setName, keyword).size()));
645 return getClass().getName();
653 class RegExpInstanceKey {
654 private final boolean isRegExp;
655 private String strKey;
656 private Long longKey;
657 public RegExpInstanceKey(String key) {
661 public RegExpInstanceKey(Long key) {
671 String getRegExpKey() {
683 private Map<RegExpInstanceKey, DisplayableItemNode >
nodesMap =
new HashMap<>();
693 keywordResults.addObserver(
this);
698 keywordResults.deleteObserver(
this);
703 List <String>instances = keywordResults.getKeywordInstances(setName, keyword);
707 if ((instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME))) {
708 for (Long
id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME) ) {
709 RegExpInstanceKey key =
new RegExpInstanceKey(
id);
715 for (String instance : instances) {
716 RegExpInstanceKey key =
new RegExpInstanceKey(instance);
727 return nodesMap.get(key);
732 if (key.isRegExp() ==
false) {
740 public void update(Observable o, Object arg) {
756 super(Children.create(
new HitsFactory(setName, keyword, instance),
true), Lookups.singleton(keyword));
757 super.setName(keyword);
761 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
763 keywordResults.addObserver(
this);
767 int totalDescendants = keywordResults.getArtifactIds(setName, keyword, instance).size();
768 super.setDisplayName(instance +
" (" + totalDescendants +
")");
772 public void update(Observable o, Object arg) {
783 return v.
visit(
this);
788 Sheet s = super.createSheet();
789 Sheet.Set ss = s.get(Sheet.PROPERTIES);
791 ss = Sheet.createPropertiesSet();
795 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.name"),
796 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.displayName"),
797 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.desc"),
800 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.name"),
801 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.displayName"),
802 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.desc"),
803 keywordResults.getKeywordInstances(setName, keyword).size()));
810 return getClass().getName();
820 if (skCase == null) {
831 logger.log(Level.SEVERE,
"TskCoreException while constructing BlackboardArtifact Node from KeywordHitsKeywordChildren");
843 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createNodeForKey.modTime.name"),
844 NbBundle.getMessage(
this.getClass(),
845 "KeywordHits.createNodeForKey.modTime.displayName"),
846 NbBundle.getMessage(
this.getClass(),
847 "KeywordHits.createNodeForKey.modTime.desc"),
850 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createNodeForKey.accessTime.name"),
851 NbBundle.getMessage(
this.getClass(),
852 "KeywordHits.createNodeForKey.accessTime.displayName"),
853 NbBundle.getMessage(
this.getClass(),
854 "KeywordHits.createNodeForKey.accessTime.desc"),
857 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createNodeForKey.chgTime.name"),
858 NbBundle.getMessage(
this.getClass(),
859 "KeywordHits.createNodeForKey.chgTime.displayName"),
860 NbBundle.getMessage(
this.getClass(),
861 "KeywordHits.createNodeForKey.chgTime.desc"),
865 logger.log(Level.WARNING,
"TSK Exception occurred", ex);
873 public class HitsFactory extends ChildFactory.Detachable<Long> implements Observer {
879 private Map<Long, BlackboardArtifactNode >
nodesMap =
new HashMap<>();
881 public HitsFactory(String setName, String keyword, String instance) {
890 keywordResults.addObserver(
this);
895 keywordResults.deleteObserver(
this);
900 list.addAll(keywordResults.getArtifactIds(setName, keyword, instance));
901 for (Long
id : keywordResults.getArtifactIds(setName, keyword, instance) ) {
910 return nodesMap.get(artifactId);
914 public void update(Observable o, Object arg) {
final PropertyChangeListener pcl
KeywordHits(SleuthkitCase skCase)
static final String KEYWORD_HITS
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
void update(Observable o, Object arg)
Node createNodeForKey(RegExpInstanceKey key)
static String getStringTime(long epochSeconds, TimeZone tzone)
Node createNodeForKey(String key)
static synchronized IngestManager getInstance()
void update(Observable o, Object arg)
final KeywordResults keywordResults
void update(Observable o, Object arg)
void update(Observable o, Object arg)
static void removePropertyChangeListener(PropertyChangeListener listener)
Map< Long, BlackboardArtifactNode > nodesMap
static final String SIMPLE_REGEX_SEARCH
DisplayableItemNode createNode(RegExpInstanceKey key)
Map< RegExpInstanceKey, DisplayableItemNode > nodesMap
TermFactory(String setName)
BlackboardArtifactNode createBlackboardArtifactNode(Long artifactId)
final Map< String, Map< String, Map< String, Set< Long > > > > topLevelMap
void update(Observable o, Object arg)
BlackboardArtifact getBlackboardArtifact(long artifactID)
T visit(DataSourcesNode in)
AbstractFile getAbstractFileById(long id)
boolean createKeys(List< String > list)
void removeIngestJobEventListener(final PropertyChangeListener listener)
TermNode(String setName, String keyword)
boolean createKeys(List< String > list)
void update(Observable o, Object arg)
boolean createKeys(List< RegExpInstanceKey > list)
RegExpInstancesFactory(String setName, String keyword)
void addIngestJobEventListener(final PropertyChangeListener listener)
final String DEFAULT_INSTANCE_NAME
Node createNodeForKey(Long artifactId)
Node createNodeForKey(String key)
ListNode(String listName)
boolean createKeys(List< Long > list)
static void addPropertyChangeListener(PropertyChangeListener listener)
static final Logger logger
void addIngestModuleEventListener(final PropertyChangeListener listener)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
HitsFactory(String setName, String keyword, String instance)
void addNodeProperty(NodeProperty<?> np)
static final String SIMPLE_LITERAL_SEARCH
void update(Observable o, Object arg)
RegExpInstanceNode(String setName, String keyword, String instance)
CaseDbQuery executeQuery(String query)