diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 2dcc532a37..52a2b7fa97 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -364,10 +364,11 @@ public class Case { */ CASE_DETAILS, /** - * The status which a Tag indicates has been changed and the new value - * of the TagNameDefinition is included. + * A tag definition has changed (e.g., description, known status). The + * old value of the PropertyChangeEvent is the display name of the tag + * definition that has changed. */ - TAG_STATUS_CHANGED; + TAG_DEFINITION_CHANGED; }; @@ -1478,9 +1479,18 @@ public class Case { eventPublisher.publish(new ContentTagDeletedEvent(deletedTag)); } - public void notifyTagStatusChanged(String changedTagName) { - eventPublisher.publish(new AutopsyEvent(Events.TAG_STATUS_CHANGED.toString(), changedTagName, changedTagName)); + /** + * Notifies case event subscribers that a tag definition has changed. + * + * This should not be called from the event dispatch thread (EDT) + * + * @param changedTagName the name of the tag definition which was changed + */ + public void notifyTagDefinitionChanged(String changedTagName) { + //leaving new value of changedTagName as null, because we do not currently support changing the display name of a tag. + eventPublisher.publish(new AutopsyEvent(Events.TAG_DEFINITION_CHANGED.toString(), changedTagName, null)); } + /** * Notifies case event subscribers that an artifact tag has been added. * diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java index 712fa6480d..c5458d2f76 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java @@ -423,7 +423,10 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { private void sendStatusChangedEvents() { for (String modifiedTagDisplayName : updatedStatusTags) { - Case.getCurrentCase().notifyTagStatusChanged(modifiedTagDisplayName); + //if user closes their case after options have been changed but before application of them is complete don't notify + if (Case.isCaseOpen()) { + Case.getCurrentCase().notifyTagDefinitionChanged(modifiedTagDisplayName); + } } updatedStatusTags.clear(); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index cc6dbaf142..7252ca53cc 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -98,8 +98,8 @@ final class CaseEventListener implements PropertyChangeListener { jobProcessingExecutor.submit(new DataSourceAddedTask(dbManager, evt)); } break; - case TAG_STATUS_CHANGED: { - jobProcessingExecutor.submit(new TagStatusChangeTask(evt)); + case TAG_DEFINITION_CHANGED: { + jobProcessingExecutor.submit(new TagDefinitionChangeTask(evt)); } break; case CURRENT_CASE: { @@ -298,11 +298,11 @@ final class CaseEventListener implements PropertyChangeListener { } - private final class TagStatusChangeTask implements Runnable { + private final class TagDefinitionChangeTask implements Runnable { private final PropertyChangeEvent event; - private TagStatusChangeTask(PropertyChangeEvent evt) { + private TagDefinitionChangeTask(PropertyChangeEvent evt) { event = evt; } @@ -311,73 +311,93 @@ final class CaseEventListener implements PropertyChangeListener { if (!EamDb.isEnabled()) { return; } - String modifiedTagName = (String) event.getNewValue(); - List notableTags = TagsManager.getNotableTagDisplayNames(); - TskData.FileKnown status = notableTags.contains(modifiedTagName) ? TskData.FileKnown.BAD : TskData.FileKnown.UNKNOWN; - /** + //get the display name of the tag that has had it's definition modified + String modifiedTagName = (String) event.getOldValue(); + + /* * Set knownBad status for all files/artifacts in the given case * that are tagged with the given tag name. */ try { TagName tagName = Case.getCurrentCase().getServices().getTagsManager().getDisplayNamesToTagNamesMap().get(modifiedTagName); - // First find any matching artifacts + //First update the artifacts + //Get all BlackboardArtifactTags with this tag name List artifactTags = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifactTagsByTagName(tagName); for (BlackboardArtifactTag bbTag : artifactTags) { - List convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbTag.getArtifact(), true, true); - for (CorrelationAttribute eamArtifact : convertedArtifacts) { - boolean hasOtherBadTags = false; - //if the new status of the tag is unknown UNKNOWN ensure we are not changing the status of BlackboardArtifact which still have other tags with a non-unknown status - if (status == TskData.FileKnown.UNKNOWN) { - Content content = bbTag.getContent(); - if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) { + //start with assumption that none of the other tags applied to this Correlation Attribute will prevent it's status from being changed + boolean hasTagWithConflictingKnownStatus = false; + // if the status of the tag has been changed to TskData.FileKnown.UNKNOWN + // we need to check the status of all other tags on this correlation attribute before changing + // the status of the correlation attribute in the central repository + if (tagName.getKnownStatus() == TskData.FileKnown.UNKNOWN) { + Content content = bbTag.getContent(); + // If the content which this Blackboard Artifact Tag is linked to is an AbstractFile with KNOWN status then + // it's status in the central reporsitory should not be changed to UNKNOWN + if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) { + continue; + } + //Get the BlackboardArtifact which this BlackboardArtifactTag has been applied to. + BlackboardArtifact bbArtifact = bbTag.getArtifact(); + TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); + List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact); + //get all tags which are on this blackboard artifact + for (BlackboardArtifactTag t : tags) { + //All instances of the modified tag name will be changed, they can not conflict with each other + if (t.getName().equals(tagName)) { + continue; + } + //if any other tags on this artifact are Notable in status then this artifact can not have its status changed + if (TskData.FileKnown.BAD == t.getName().getKnownStatus()) { + //a tag with a conflicting status has been found, the status of this correlation attribute can not be modified + hasTagWithConflictingKnownStatus = true; break; } - BlackboardArtifact bbArtifact = bbTag.getArtifact(); - TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); - List tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact); - for (BlackboardArtifactTag t : tags) { - //avoid the possibility for threading issues if the tag whose status is currently changing is ever still in the tags manager with the old status - if (t.getName().equals(tagName)) { - continue; - } - //if any other tags on this artifact are Notable in status then this artifact can not have its status changed - if (notableTags.contains(t.getName().getDisplayName())) { - hasOtherBadTags = true; - break; - } - } } - if (!hasOtherBadTags) { - EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, status); + } + //if the Correlation Attribute will have no tags with a status which would prevent the current status from being changed + if (!hasTagWithConflictingKnownStatus) { + //Get the correlation atttributes that correspond to the current BlackboardArtifactTag if their status should be changed + //with the initial set of correlation attributes this should be a single correlation attribute + List convertedArtifacts = EamArtifactUtil.getCorrelationAttributeFromBlackboardArtifact(bbTag.getArtifact(), true, true); + for (CorrelationAttribute eamArtifact : convertedArtifacts) { + EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); } } } - // Now search for files + // Next update the files + List fileTags = Case.getCurrentCase().getSleuthkitCase().getContentTagsByTagName(tagName); + //Get all ContentTags with this tag name for (ContentTag contentTag : fileTags) { - boolean hasOtherBadTags = false; - //if the new status of the tag is unknown UNKNOWN ensure we are not changing the status of files which still have other tags with a Notable status - if (status == TskData.FileKnown.UNKNOWN) { + //start with assumption that none of the other tags applied to this ContentTag will prevent it's status from being changed + boolean hasTagWithConflictingKnownStatus = false; + // if the status of the tag has been changed to TskData.FileKnown.UNKNOWN + // we need to check the status of all other tags on this file before changing + // the status of the file in the central repository + if (tagName.getKnownStatus() == TskData.FileKnown.UNKNOWN) { Content content = contentTag.getContent(); TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); List tags = tagsManager.getContentTagsByContent(content); + //get all tags which are on this file for (ContentTag t : tags) { - //avoid the possibility for threading issues if the tag whose status is currently changing is ever still in the tags manager with the old status + //All instances of the modified tag name will be changed, they can not conflict with each other if (t.getName().equals(tagName)) { continue; } //if any other tags on this file are Notable in status then this file can not have its status changed - if (notableTags.contains(t.getName().getDisplayName())) { - hasOtherBadTags = true; + if (TskData.FileKnown.BAD == t.getName().getKnownStatus()) { + //a tag with a conflicting status has been found, the status of this file can not be modified + hasTagWithConflictingKnownStatus = true; break; } } } - if (!hasOtherBadTags) { + //if the file will have no tags with a status which would prevent the current status from being changed + if (!hasTagWithConflictingKnownStatus) { final CorrelationAttribute eamArtifact = EamArtifactUtil.getEamArtifactFromContent(contentTag.getContent(), - status, ""); + tagName.getKnownStatus(), ""); if (eamArtifact != null) { - EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, status); + EamDb.getInstance().setArtifactInstanceKnownStatus(eamArtifact, tagName.getKnownStatus()); } } }