72 @NbBundle.Messages(
"KeywordHits.kwHits.text=Keyword Hits")
73 private static final String
KEYWORD_HITS = KeywordHits_kwHits_text();
74 @NbBundle.Messages(
"KeywordHits.simpleLiteralSearch.text=Single Literal Keyword Search")
76 @NbBundle.Messages(
"KeywordHits.singleRegexSearch.text=Single Regular Expression Search")
79 public static final String
NAME = BlackboardArtifact.Type.TSK_KEYWORD_HIT.getTypeName();
96 +
"blackboard_attributes.value_int32, "
97 +
"blackboard_artifacts.artifact_obj_id, "
98 +
"blackboard_attributes.attribute_type_id "
99 +
"FROM blackboard_attributes, blackboard_artifacts "
100 +
"WHERE blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id "
101 +
" AND blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.Type.TSK_KEYWORD_HIT.getTypeID()
102 +
" AND (attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()
103 +
" OR attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()
104 +
" OR attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()
105 +
" OR attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()
130 this.filteringDSObjId = objId;
140 private final class KeywordResults
extends Observable {
144 private final Map<String, Map<String, Map<String, Set<Long>>>>
topLevelMap =
new LinkedHashMap<>();
155 List<String> getListNames() {
157 List<String> names =
new ArrayList<>(
topLevelMap.keySet());
161 Collections.sort(names,
new Comparator<String>() {
164 public int compare(String o1, String o2) {
167 if (o1.startsWith(
"Single Literal Keyword Search")) {
169 }
else if (o2.startsWith(
"Single Literal Keyword Search")) {
171 }
else if (o1.startsWith(
"Single Regular Expression Search")) {
173 }
else if (o2.startsWith(
"Single Regular Expression Search")) {
176 return o1.compareTo(o2);
192 List<String> getKeywords(String listName) {
193 List<String> keywords;
195 keywords =
new ArrayList<>(
topLevelMap.get(listName).keySet());
197 Collections.sort(keywords);
211 List<String> getKeywordInstances(String listName, String keyword) {
212 List<String> instances;
214 instances =
new ArrayList<>(
topLevelMap.get(listName).get(keyword).keySet());
216 Collections.sort(instances);
231 Set<Long> getArtifactIds(String listName, String keyword, String keywordInstance) {
233 return topLevelMap.get(listName).get(keyword).get(keywordInstance);
246 void addRegExpToList(Map<String, Map<String, Set<Long>>> listMap, String regExp, String keywordInstance, Long artifactId) {
247 Map<String, Set<Long>> instanceMap = listMap.computeIfAbsent(regExp, r ->
new LinkedHashMap<>());
249 instanceMap.computeIfAbsent(keywordInstance, ki ->
new HashSet<>()).add(artifactId);
260 void addNonRegExpMatchToList(Map<String, Map<String, Set<Long>>> listMap, String keyWord, Long artifactId) {
261 Map<String, Set<Long>> instanceMap = listMap.computeIfAbsent(keyWord, k ->
new LinkedHashMap<>());
274 void populateTreeMaps(Map<Long, Map<Long, String>> artifactIds) {
279 Map<String, Map<String, Map<String, Set<Long>>>> listsMap =
new LinkedHashMap<>();
282 Map<String, Map<String, Set<Long>>> literalMap =
new LinkedHashMap<>();
285 Map<String, Map<String, Set<Long>>> regexMap =
new LinkedHashMap<>();
291 for (Map.Entry<Long, Map<Long, String>> art : artifactIds.entrySet()) {
292 long id = art.getKey();
293 Map<Long, String> attributes = art.getValue();
296 String listName = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
297 String word = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()));
298 String reg = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()));
299 String kwType = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()));
301 if (listName !=
null) {
303 Map<String, Map<String, Set<Long>>> listMap = listsMap.computeIfAbsent(listName, ln ->
new LinkedHashMap<>());
305 if (
"1".equals(kwType) || reg ==
null) {
312 word = (reg !=
null) ? reg : word;
313 addNonRegExpMatchToList(listMap, word,
id);
315 addRegExpToList(listMap, reg, word,
id);
318 if (
"1".equals(kwType) || reg ==
null) {
325 word = (reg !=
null) ? reg : word;
326 addNonRegExpMatchToList(literalMap, word,
id);
328 addRegExpToList(regexMap, reg, word,
id);
341 Map<Long, Map<Long, String>> artifactIds =
new LinkedHashMap<>();
349 queryStr +=
" AND blackboard_artifacts.data_source_obj_id = " +
filteringDSObjId;
352 try (CaseDbQuery dbQuery =
skCase.executeQuery(queryStr)) {
353 ResultSet resultSet = dbQuery.getResultSet();
354 while (resultSet.next()) {
355 long artifactObjId = resultSet.getLong(
"artifact_obj_id");
356 long typeId = resultSet.getLong(
"attribute_type_id");
357 String valueStr = resultSet.getString(
"value_text");
360 Map<Long, String> attributesByTypeMap = artifactIds.computeIfAbsent(artifactObjId, ai ->
new LinkedHashMap<>());
361 if (StringUtils.isNotEmpty(valueStr)) {
362 attributesByTypeMap.put(typeId, valueStr);
365 Long valueLong = resultSet.getLong(
"value_int32");
366 attributesByTypeMap.put(typeId, valueLong.toString());
369 }
catch (TskCoreException | SQLException ex) {
370 logger.log(Level.WARNING,
"SQL Exception occurred: ", ex);
373 populateTreeMaps(artifactIds);
379 return visitor.
visit(
this);
393 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
403 return visitor.
visit(
this);
407 @NbBundle.Messages({
"KeywordHits.createSheet.name.name=Name",
408 "KeywordHits.createSheet.name.displayName=Name",
409 "KeywordHits.createSheet.name.desc=no description"})
411 Sheet sheet = super.createSheet();
412 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
413 if (sheetSet ==
null) {
414 sheetSet = Sheet.createPropertiesSet();
419 KeywordHits_createSheet_name_name(),
420 KeywordHits_createSheet_name_displayName(),
421 KeywordHits_createSheet_name_desc(),
429 return getClass().getName();
447 public void update(Observable o, Object arg) {
457 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
459 public void propertyChange(PropertyChangeEvent evt) {
460 String eventType = evt.getPropertyName();
477 if (
null != eventData && eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.Type.TSK_KEYWORD_HIT.getTypeID()) {
498 && evt.getNewValue() ==
null) {
510 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(
pcl,
null);
537 return new ListNode(key);
546 super(children, lookup);
556 return getClass().getName();
560 public void update(Observable o, Object arg) {
564 final void updateDisplayName() {
565 super.setDisplayName(
displayName +
" (" + countTotalDescendants() +
")");
568 abstract int countTotalDescendants();
575 class ListNode
extends KWHitsNodeBase {
577 private final String listName;
579 private ListNode(String listName) {
580 super(Children.create(
new TermFactory(listName),
true), Lookups.singleton(listName), listName);
581 super.setName(listName);
582 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
583 this.listName = listName;
589 public int countTotalDescendants() {
590 int totalDescendants = 0;
593 for (String instance :
keywordResults.getKeywordInstances(listName, word)) {
594 Set<Long> ids =
keywordResults.getArtifactIds(listName, word, instance);
595 totalDescendants += ids.size();
598 return totalDescendants;
602 @NbBundle.Messages({
"KeywordHits.createSheet.listName.name=List Name",
603 "KeywordHits.createSheet.listName.displayName=List Name",
604 "KeywordHits.createSheet.listName.desc=no description",
605 "KeywordHits.createSheet.numChildren.name=Number of Children",
606 "KeywordHits.createSheet.numChildren.displayName=Number of Children",
607 "KeywordHits.createSheet.numChildren.desc=no description"})
608 protected Sheet createSheet() {
609 Sheet sheet = super.createSheet();
610 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
611 if (sheetSet ==
null) {
612 sheetSet = Sheet.createPropertiesSet();
616 sheetSet.put(
new NodeProperty<>(
617 KeywordHits_createSheet_listName_name(),
618 KeywordHits_createSheet_listName_displayName(),
619 KeywordHits_createSheet_listName_desc(),
622 sheetSet.put(
new NodeProperty<>(
623 KeywordHits_createSheet_numChildren_name(),
624 KeywordHits_createSheet_numChildren_displayName(),
625 KeywordHits_createSheet_numChildren_desc(),
637 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
638 return visitor.visit(
this);
662 return new TermNode(
setName, key);
676 ChildFactory<?> createChildFactory(String setName, String keyword) {
680 return new RegExpInstancesFactory(setName, keyword);
687 class TermNode
extends KWHitsNodeBase {
689 private final String setName;
690 private final String keyword;
692 private TermNode(String setName, String keyword) {
693 super(Children.create(createChildFactory(setName, keyword),
true), Lookups.singleton(keyword), keyword);
702 super.setName(setName +
"_" + keyword);
703 this.setName = setName;
704 this.keyword = keyword;
705 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
711 int countTotalDescendants() {
712 return keywordResults.getKeywordInstances(setName, keyword).stream()
713 .mapToInt(instance ->
keywordResults.getArtifactIds(setName, keyword, instance).size())
724 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
725 return visitor.visit(
this);
729 @NbBundle.Messages({
"KeywordHits.createSheet.filesWithHits.name=Files with Hits",
730 "KeywordHits.createSheet.filesWithHits.displayName=Files with Hits",
731 "KeywordHits.createSheet.filesWithHits.desc=no description"})
732 protected Sheet createSheet() {
733 Sheet sheet = super.createSheet();
734 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
735 if (sheetSet ==
null) {
736 sheetSet = Sheet.createPropertiesSet();
739 sheetSet.put(
new NodeProperty<>(
740 KeywordHits_createSheet_listName_name(),
741 KeywordHits_createSheet_listName_displayName(),
742 KeywordHits_createSheet_listName_desc(),
745 sheetSet.put(
new NodeProperty<>(
746 KeywordHits_createSheet_filesWithHits_name(),
747 KeywordHits_createSheet_filesWithHits_displayName(),
748 KeywordHits_createSheet_filesWithHits_desc(),
749 countTotalDescendants()));
785 class RegExpInstanceNode
extends KWHitsNodeBase {
787 private final String setName;
788 private final String keyword;
789 private final String instance;
791 private RegExpInstanceNode(String setName, String keyword, String instance) {
792 super(Children.create(
new HitsFactory(setName, keyword, instance),
true), Lookups.singleton(instance), instance);
801 super.setName(setName +
"_" + keyword +
"_" + instance);
802 this.setName = setName;
803 this.keyword = keyword;
804 this.instance = instance;
805 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/keyword_hits.png");
811 int countTotalDescendants() {
812 return keywordResults.getArtifactIds(setName, keyword, instance).size();
821 public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
822 return visitor.visit(
this);
826 protected Sheet createSheet() {
827 Sheet sheet = super.createSheet();
828 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
829 if (sheetSet ==
null) {
830 sheetSet = Sheet.createPropertiesSet();
834 sheetSet.put(
new NodeProperty<>(
835 KeywordHits_createSheet_listName_name(),
836 KeywordHits_createSheet_listName_displayName(),
837 KeywordHits_createSheet_listName_desc(),
840 sheetSet.put(
new NodeProperty<>(
841 KeywordHits_createSheet_filesWithHits_name(),
842 KeywordHits_createSheet_filesWithHits_displayName(),
843 KeywordHits_createSheet_filesWithHits_desc(),
844 keywordResults.getArtifactIds(setName, keyword, instance).size()));
858 @NbBundle.Messages({
"KeywordHits.createNodeForKey.modTime.name=ModifiedTime",
859 "KeywordHits.createNodeForKey.modTime.displayName=Modified Time",
860 "KeywordHits.createNodeForKey.modTime.desc=Modified Time",
861 "KeywordHits.createNodeForKey.accessTime.name=AccessTime",
862 "KeywordHits.createNodeForKey.accessTime.displayName=Access Time",
863 "KeywordHits.createNodeForKey.accessTime.desc=Access Time",
864 "KeywordHits.createNodeForKey.chgTime.name=ChangeTime",
865 "KeywordHits.createNodeForKey.chgTime.displayName=Change Time",
866 "KeywordHits.createNodeForKey.chgTime.desc=Change Time"})
876 AbstractFile file = n.getLookup().lookup(AbstractFile.class);
879 file =
skCase.getAbstractFileById(art.getObjectID());
880 }
catch (TskCoreException ex) {
881 logger.log(Level.SEVERE,
"TskCoreException while constructing BlackboardArtifact Node from KeywordHitsKeywordChildren", ex);
894 KeywordHits_createNodeForKey_modTime_name(),
895 KeywordHits_createNodeForKey_modTime_displayName(),
896 KeywordHits_createNodeForKey_modTime_desc(),
899 KeywordHits_createNodeForKey_accessTime_name(),
900 KeywordHits_createNodeForKey_accessTime_displayName(),
901 KeywordHits_createNodeForKey_accessTime_desc(),
904 KeywordHits_createNodeForKey_chgTime_name(),
905 KeywordHits_createNodeForKey_chgTime_displayName(),
906 KeywordHits_createNodeForKey_chgTime_desc(),
919 private final Map<Long, AnalysisResult>
artifactHits =
new HashMap<>();
940 AnalysisResult art =
skCase.getBlackboard().getAnalysisResultById(
id);
946 }
catch (TskCoreException ex) {
947 logger.log(Level.SEVERE,
"TSK Exception occurred", ex);
953 return Collections.emptyList();
972 public void update(Observable o, Object arg) {