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.HashSet;
28 import java.util.LinkedHashMap;
29 import java.util.List;
31 import java.util.Observable;
32 import java.util.Observer;
34 import java.util.logging.Level;
35 import org.openide.nodes.ChildFactory;
36 import org.openide.nodes.Children;
37 import org.openide.nodes.Node;
38 import org.openide.nodes.Sheet;
39 import org.openide.util.NbBundle;
40 import org.openide.util.lookup.Lookups;
49 import org.
sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
61 public static final String
NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getLabel();
63 .getMessage(
KeywordHits.class,
"KeywordHits.simpleLiteralSearch.text");
65 .getMessage(
KeywordHits.class,
"KeywordHits.singleRegexSearch.text");
76 private final Map<String, Map<String, Set<Long>>>
topLevelMap;
79 topLevelMap =
new LinkedHashMap<>();
83 List<String> getListNames() {
84 List<String> names =
new ArrayList<>(topLevelMap.keySet());
91 List<String> getKeywords(String listName) {
92 List<String> keywords =
new ArrayList<>(topLevelMap.get(listName).keySet());
93 Collections.sort(keywords);
97 Set<Long> getArtifactIds(String listName, String keyword) {
98 return topLevelMap.get(listName).get(keyword);
102 void populateMaps(Map<Long, Map<Long, String>> artifactIds) {
106 Map<String, Map<String, Set<Long>>> listsMap =
new LinkedHashMap<>();
109 Map<String, Set<Long>> literalMap =
new LinkedHashMap<>();
112 Map<String, Set<Long>> regexMap =
new LinkedHashMap<>();
115 topLevelMap.put(SIMPLE_LITERAL_SEARCH, literalMap);
116 topLevelMap.put(SIMPLE_REGEX_SEARCH, regexMap);
118 for (Map.Entry<Long, Map<Long, String>> art : artifactIds.entrySet()) {
119 long id = art.getKey();
120 Map<Long, String> attributes = art.getValue();
123 String listName = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
124 String word = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()));
125 String reg = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()));
128 if (listName != null) {
129 if (listsMap.containsKey(listName) ==
false) {
130 listsMap.put(listName,
new LinkedHashMap<String, Set<Long>>());
133 Map<String, Set<Long>> listMap = listsMap.get(listName);
134 if (listMap.containsKey(word) ==
false) {
135 listMap.put(word,
new HashSet<Long>());
138 listMap.get(word).add(
id);
140 else if (reg != null) {
141 if (regexMap.containsKey(reg) ==
false) {
142 regexMap.put(reg,
new HashSet<Long>());
144 regexMap.get(reg).add(
id);
147 if (literalMap.containsKey(word) ==
false) {
148 literalMap.put(word,
new HashSet<Long>());
150 literalMap.get(word).add(
id);
152 topLevelMap.putAll(listsMap);
159 @SuppressWarnings(
"deprecation")
161 Map<Long, Map<Long, String>> artifactIds =
new LinkedHashMap<>();
163 if (skCase == null) {
167 int setId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID();
168 int wordId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID();
169 int regexId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID();
170 int artId = BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID();
171 String query =
"SELECT blackboard_attributes.value_text,blackboard_attributes.artifact_id,"
172 +
"blackboard_attributes.attribute_type_id FROM blackboard_attributes,blackboard_artifacts WHERE "
173 +
"(blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id AND "
174 +
"blackboard_artifacts.artifact_type_id=" + artId
175 +
") AND (attribute_type_id=" + setId +
" OR "
176 +
"attribute_type_id=" + wordId +
" OR "
177 +
"attribute_type_id=" + regexId +
")";
179 try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
180 ResultSet resultSet = dbQuery.getResultSet();
181 while (resultSet.next()) {
182 String value = resultSet.getString(
"value_text");
183 long artifactId = resultSet.getLong(
"artifact_id");
184 long typeId = resultSet.getLong(
"attribute_type_id");
185 if (!artifactIds.containsKey(artifactId)) {
186 artifactIds.put(artifactId,
new LinkedHashMap<Long, String>());
188 if (!value.equals(
"")) {
189 artifactIds.get(artifactId).put(typeId, value);
192 }
catch (TskCoreException | SQLException ex) {
193 logger.log(Level.WARNING,
"SQL Exception occurred: ", ex);
196 populateMaps(artifactIds);
201 public <T> T accept(AutopsyItemVisitor<T> v) {
202 return v.visit(
this);
209 super(Children.create(
new ListFactory(),
true), Lookups.singleton(KEYWORD_HITS));
211 super.setDisplayName(KEYWORD_HITS);
212 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
222 return v.
visit(
this);
227 Sheet s = super.createSheet();
228 Sheet.Set ss = s.get(Sheet.PROPERTIES);
230 ss = Sheet.createPropertiesSet();
234 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.name.name"),
235 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.name.displayName"),
236 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.name.desc"),
253 private class ListFactory extends ChildFactory.Detachable<String> implements Observer {
255 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
257 public void propertyChange(PropertyChangeEvent evt) {
258 String eventType = evt.getPropertyName();
275 if (null != eventData && eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
278 }
catch (IllegalStateException notUsed) {
294 }
catch (IllegalStateException notUsed) {
301 if (evt.getNewValue() == null) {
315 keywordResults.addObserver(
this);
323 keywordResults.deleteObserver(
this);
328 list.addAll(keywordResults.getListNames());
338 public void update(Observable o, Object arg) {
348 super(Children.create(
new TermFactory(listName),
true), Lookups.singleton(listName));
349 super.setName(listName);
350 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
353 keywordResults.addObserver(
this);
357 int totalDescendants = 0;
358 for (String word : keywordResults.getKeywords(listName)) {
359 Set<Long> ids = keywordResults.getArtifactIds(listName, word);
360 totalDescendants += ids.size();
362 super.setDisplayName(listName +
" (" + totalDescendants +
")");
367 Sheet s = super.createSheet();
368 Sheet.Set ss = s.get(Sheet.PROPERTIES);
370 ss = Sheet.createPropertiesSet();
374 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.name"),
375 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.displayName"),
376 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.desc"),
379 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.numChildren.name"),
380 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.numChildren.displayName"),
381 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.numChildren.desc"),
382 keywordResults.getKeywords(listName).size()));
394 return v.
visit(
this);
398 public void update(Observable o, Object arg) {
413 private class TermFactory extends ChildFactory.Detachable<String> implements Observer {
424 keywordResults.addObserver(
this);
429 keywordResults.deleteObserver(
this);
434 list.addAll(keywordResults.getKeywords(setName));
444 public void update(Observable o, Object arg) {
455 super(Children.create(
new HitsFactory(setName, keyword),
true), Lookups.singleton(keyword));
456 super.setName(keyword);
459 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
461 keywordResults.addObserver(
this);
465 super.setDisplayName(keyword +
" (" + keywordResults.getArtifactIds(setName, keyword).size() +
")");
469 public void update(Observable o, Object arg) {
480 return v.
visit(
this);
485 Sheet s = super.createSheet();
486 Sheet.Set ss = s.get(Sheet.PROPERTIES);
488 ss = Sheet.createPropertiesSet();
492 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.name"),
493 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.displayName"),
494 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.listName.desc"),
497 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.name"),
498 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.displayName"),
499 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createSheet.filesWithHits.desc"),
500 keywordResults.getArtifactIds(setName, keyword).size()));
516 public class HitsFactory extends ChildFactory.Detachable<Long> implements Observer {
529 keywordResults.addObserver(
this);
534 keywordResults.deleteObserver(
this);
539 list.addAll(keywordResults.getArtifactIds(setName, keyword));
545 if (skCase == null) {
550 BlackboardArtifact art = skCase.getBlackboardArtifact(artifactId);
554 file = skCase.getAbstractFileById(art.getObjectID());
555 }
catch (TskCoreException ex) {
556 logger.log(Level.SEVERE,
"TskCoreException while constructing BlackboardArtifact Node from KeywordHitsKeywordChildren");
568 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createNodeForKey.modTime.name"),
569 NbBundle.getMessage(
this.getClass(),
570 "KeywordHits.createNodeForKey.modTime.displayName"),
571 NbBundle.getMessage(
this.getClass(),
572 "KeywordHits.createNodeForKey.modTime.desc"),
575 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createNodeForKey.accessTime.name"),
576 NbBundle.getMessage(
this.getClass(),
577 "KeywordHits.createNodeForKey.accessTime.displayName"),
578 NbBundle.getMessage(
this.getClass(),
579 "KeywordHits.createNodeForKey.accessTime.desc"),
582 NbBundle.getMessage(
this.getClass(),
"KeywordHits.createNodeForKey.chgTime.name"),
583 NbBundle.getMessage(
this.getClass(),
584 "KeywordHits.createNodeForKey.chgTime.displayName"),
585 NbBundle.getMessage(
this.getClass(),
586 "KeywordHits.createNodeForKey.chgTime.desc"),
589 }
catch (TskException ex) {
590 logger.log(Level.WARNING,
"TSK Exception occurred", ex);
596 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)
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)
static final String SIMPLE_REGEX_SEARCH
TermFactory(String setName)
T visit(DataSourcesNode in)
final Map< String, Map< String, Set< Long > > > topLevelMap
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)
void addIngestJobEventListener(final PropertyChangeListener listener)
Node createNodeForKey(Long artifactId)
Node createNodeForKey(String key)
ListNode(String listName)
boolean createKeys(List< Long > list)
static final Logger logger
static synchronized void removePropertyChangeListener(PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized void addPropertyChangeListener(PropertyChangeListener listener)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
static final String SIMPLE_LITERAL_SEARCH
void update(Observable o, Object arg)
HitsFactory(String setName, String keyword)