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)