19 package org.sleuthkit.autopsy.casemodule.services;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.io.Closeable;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.EnumSet;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
33 import java.util.logging.Level;
34 import org.openide.util.NbBundle;
35 import org.openide.util.WeakListeners;
68 private static final Object
lock =
new Object();
70 private final Map<String, TagName>
allTagNameMap = Collections.synchronizedMap(
new HashMap<>());
72 private final PropertyChangeListener
listener =
new PropertyChangeListener() {
74 public void propertyChange(PropertyChangeEvent evt) {
79 for (TagName tag : addTagNames) {
80 allTagNameMap.put(tag.getDisplayName(), tag);
85 List<String> keysToRemove =
new ArrayList<>();
87 if (deletedIds.contains(tagName.getId())) {
88 keysToRemove.add(tagName.getDisplayName());
92 for (String key : keysToRemove) {
93 allTagNameMap.remove(key);
99 private final PropertyChangeListener
weakListener = WeakListeners.propertyChange(listener, null);
106 if (evt.getNewValue() != null) {
107 Case currentCase = (
Case) evt.getNewValue();
109 CaseDbAccessManager caseDb = currentCase.
getSleuthkitCase().getCaseDbAccessManager();
114 if (currentCase.
getSleuthkitCase().getDatabaseType().equals(DbType.SQLITE)) {
116 }
else if (currentCase.
getSleuthkitCase().getDatabaseType().equals(DbType.POSTGRESQL)) {
119 }
catch (TskCoreException ex) {
120 LOGGER.log(Level.SEVERE,
121 String.format(
"Unable to create the %s table for image tag storage.",
137 return (tagDisplayName.contains(
"\\")
138 || tagDisplayName.contains(
":")
139 || tagDisplayName.contains(
"*")
140 || tagDisplayName.contains(
"?")
141 || tagDisplayName.contains(
"\"")
142 || tagDisplayName.contains(
"<")
143 || tagDisplayName.contains(
">")
144 || tagDisplayName.contains(
"|")
145 || tagDisplayName.contains(
",")
146 || tagDisplayName.contains(
";"));
150 @NbBundle.Messages({
"TagsManager.notableTagEnding.text= (Notable)"})
157 return Bundle.TagsManager_notableTagEnding_text();
172 Set<String> tagDisplayNames =
new HashSet<>();
174 customNames.forEach((tagType) -> {
175 tagDisplayNames.add(tagType.getDisplayName());
180 tagDisplayNames.add(tagName.getDisplayName());
187 return tagDisplayNames;
198 List<String> tagDisplayNames =
new ArrayList<>();
200 if (tagDef.getKnownStatus() == TskData.FileKnown.BAD) {
201 tagDisplayNames.add(tagDef.getDisplayName());
208 if (tagName.getKnownStatus() == TskData.FileKnown.BAD
209 && !tagDisplayNames.contains(tagName.getDisplayName())) {
210 tagDisplayNames.add(tagName.getDisplayName());
218 return tagDisplayNames;
227 List<String> tagList =
new ArrayList<>();
230 tagList.add(tagNameDef.getDisplayName());
235 for (TagSet tagSet : tagSetList) {
236 if (tagSet.getName().equals(PROJECT_VIC_TAG_SET_NAME)) {
237 for (TagName tagName : tagSet.getTagNames()) {
238 tagList.add(tagName.getDisplayName());
243 LOGGER.log(Level.SEVERE,
"Failed to get Project VIC tags from the database.", ex);
284 synchronized (
lock) {
299 TaggingManager taggingMgr = caseDb.getTaggingManager();
301 List<TagSet> tagSetsInCase = taggingMgr.getTagSets();
302 if (tagSetsInCase.isEmpty()) {
306 taggingMgr.addOrUpdateTagName(def.getDisplayName(), def.getDescription(), def.getColor(), def.getKnownStatus());
310 for (TagSetDefinition setDef : TagSetDefinition.readTagSetDefinitions()) {
311 List<TagName> tagNamesInSet =
new ArrayList<>();
312 for (TagNameDefinition tagNameDef : setDef.getTagNameDefinitions()) {
313 tagNamesInSet.add(taggingMgr.addOrUpdateTagName(tagNameDef.getDisplayName(), tagNameDef.getDescription(), tagNameDef.getColor(), tagNameDef.getKnownStatus()));
316 if (!tagNamesInSet.isEmpty()) {
317 taggingMgr.addTagSet(setDef.getName(), tagNamesInSet);
322 for(TagName tagName: caseDb.getAllTagNames()) {
323 allTagNameMap.put(tagName.getDisplayName(), tagName);
326 }
catch (TskCoreException ex) {
327 LOGGER.log(Level.SEVERE,
"Error updating standard tag name and tag set definitions", ex);
328 }
catch (IOException ex) {
329 LOGGER.log(Level.SEVERE,
"Error loading tag set JSON files", ex);
332 for (TagNameDefinition tagName : TagNameDefinition.getTagNameDefinitions()) {
333 tagName.saveToCase(caseDb);
336 Case.addEventTypeSubscriber(Collections.singleton(Case.Events.TAG_NAMES_UPDATED),
weakListener);
337 Case.addEventTypeSubscriber(Collections.singleton(Case.Events.TAG_NAMES_ADDED),
weakListener);
338 Case.addEventTypeSubscriber(Collections.singleton(Case.Events.TAG_NAMES_DELETED),
weakListener);
349 return caseDb.getTaggingManager().getTagSets();
361 public TagSet
getTagSet(TagName tagName)
throws TskCoreException {
362 return caseDb.getTaggingManager().getTagSet(tagName);
376 public TagSet
addTagSet(String name, List<TagName> tagNameList)
throws TskCoreException {
377 return caseDb.getTaggingManager().addTagSet(name, tagNameList);
387 List<TagName> tagNames =
new ArrayList<>();
388 tagNames.addAll(allTagNameMap.values());
401 return caseDb.getTagNamesInUse();
415 Set<TagName> tagNameSet =
new HashSet<>();
416 List<BlackboardArtifactTag> artifactTags = caseDb.getAllBlackboardArtifactTags();
417 for (BlackboardArtifactTag tag : artifactTags) {
418 if (tag.getUserName().equals(userName)) {
419 tagNameSet.add(tag.getName());
422 List<ContentTag> contentTags = caseDb.getAllContentTags();
423 for (ContentTag tag : contentTags) {
424 if (tag.getUserName().equals(userName)) {
425 tagNameSet.add(tag.getName());
428 return new ArrayList<>(tagNameSet);
444 return caseDb.getTagNamesInUse(dsObjId);
462 Set<TagName> tagNameSet =
new HashSet<>();
463 List<BlackboardArtifactTag> artifactTags = caseDb.getAllBlackboardArtifactTags();
464 for (BlackboardArtifactTag tag : artifactTags) {
465 if (tag.getUserName().equals(userName) && tag.getArtifact().getDataSource().getId() == dsObjId) {
466 tagNameSet.add(tag.getName());
469 List<ContentTag> contentTags = caseDb.getAllContentTags();
470 for (ContentTag tag : contentTags) {
471 if (tag.getUserName().equals(userName) && tag.getContent().getDataSource().getId() == dsObjId) {
472 tagNameSet.add(tag.getName());
475 return new ArrayList<>(tagNameSet);
486 Map<String, TagName> tagNames =
new HashMap<>();
488 tagNames.put(tagName.getDisplayName(), tagName);
508 return addTagName(displayName,
"", TagName.HTML_COLOR.NONE, TskData.FileKnown.UNKNOWN);
526 public TagName
addTagName(String displayName, String description)
throws TagNameAlreadyExistsException, TskCoreException {
527 return addTagName(displayName, description, TagName.HTML_COLOR.NONE, TskData.FileKnown.UNKNOWN);
545 public TagName
addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException {
546 return addTagName(displayName, description, color, TskData.FileKnown.UNKNOWN);
566 public TagName
addTagName(String displayName, String description, TagName.HTML_COLOR color, TskData.FileKnown knownStatus) throws TagNameAlreadyExistsException, TskCoreException {
567 synchronized (
lock) {
569 TagName tagName = caseDb.getTaggingManager().addOrUpdateTagName(displayName, description, color, knownStatus);
571 customTypes.add(
new TagNameDefinition(displayName, description, color, knownStatus));
574 }
catch (TskCoreException ex) {
576 for (TagName tagName : existingTagNames) {
577 if (tagName.getDisplayName().equals(displayName)) {
578 throw new TagNameAlreadyExistsException();
599 public ContentTag
addContentTag(Content content, TagName tagName)
throws TskCoreException {
617 public ContentTag
addContentTag(Content content, TagName tagName, String comment)
throws TskCoreException {
637 public ContentTag
addContentTag(Content content, TagName tagName, String comment,
long beginByteOffset,
long endByteOffset)
throws TskCoreException {
638 TaggingManager.ContentTagChange tagChange = caseDb.getTaggingManager().addContentTag(content, tagName, comment, beginByteOffset, endByteOffset);
642 currentCase.
notifyContentTagAdded(tagChange.getAddedTag(), tagChange.getRemovedTags().isEmpty() ? null : tagChange.getRemovedTags());
645 throw new TskCoreException(
"Added a tag to a closed case", ex);
647 return tagChange.getAddedTag();
659 caseDb.deleteContentTag(tag);
663 throw new TskCoreException(
"Deleted a tag from a closed case", ex);
676 return caseDb.getAllContentTags();
692 return caseDb.getContentTagsCountByTagName(tagName);
712 for (ContentTag tag : contentTags) {
713 if (userName.equals(tag.getUserName())) {
736 return caseDb.getContentTagsCountByTagName(tagName, dsObjId);
758 for (ContentTag tag : contentTags) {
759 if (userName.equals(tag.getUserName())) {
777 return caseDb.getContentTagByID(tagId);
792 return caseDb.getContentTagsByTagName(tagName);
809 return caseDb.getContentTagsByTagName(tagName, dsObjId);
824 return caseDb.getContentTagsByContent(content);
858 public BlackboardArtifactTag
addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment)
throws TskCoreException {
859 TaggingManager.BlackboardArtifactTagChange tagChange = caseDb.getTaggingManager().addArtifactTag(artifact, tagName, comment);
864 throw new TskCoreException(
"Added a tag to a closed case", ex);
866 return tagChange.getAddedTag();
878 caseDb.deleteBlackboardArtifactTag(tag);
882 throw new TskCoreException(
"Deleted a tag from a closed case", ex);
895 return caseDb.getAllBlackboardArtifactTags();
911 return caseDb.getBlackboardArtifactTagsCountByTagName(tagName);
931 for (BlackboardArtifactTag tag : artifactTags) {
932 if (userName.equals(tag.getUserName())) {
954 return caseDb.getBlackboardArtifactTagsCountByTagName(tagName, dsObjId);
976 for (BlackboardArtifactTag tag : artifactTags) {
977 if (userName.equals(tag.getUserName())) {
995 return caseDb.getBlackboardArtifactTagByID(tagId);
1012 return caseDb.getBlackboardArtifactTagsByTagName(tagName);
1030 return caseDb.getBlackboardArtifactTagsByTagName(tagName, dsObjId);
1045 return caseDb.getBlackboardArtifactTagsByArtifact(artifact);
1051 public static class TagNameAlreadyExistsException
extends Exception {
1070 return tagNames.containsKey(tagDisplayName) && (tagNames.get(tagDisplayName) != null);
1071 }
catch (TskCoreException ex) {
1072 LOGGER.log(Level.SEVERE,
"Error querying case database for tag names", ex);
1085 public void close() throws IOException {
void notifyContentTagDeleted(ContentTag deletedTag)
void notifyBlackBoardArtifactTagDeleted(BlackboardArtifactTag deletedTag)
TagsManager getTagsManager()
static final String TABLE_SCHEMA_SQLITE
List< Long > getTagNameIds()
static final String TABLE_NAME
SleuthkitCase getSleuthkitCase()
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
void notifyContentTagAdded(ContentTag newTag)
static final String TABLE_SCHEMA_POSTGRESQL
List< TagName > getTagNames()