Tag Events

- created new Case.Event enum values for BlackBoard/Content tags added/deleted
- created new PropertyChangeEvent subclasses for  BlackBoard/Content tags added/deleted
- replaced ModuleDataEvent hack  with new Tag Events
- removed [in] from javadocs, other minor cleanup
This commit is contained in:
jmillman 2015-06-19 10:22:18 -04:00
parent f391e32f6b
commit ba81377eb0
11 changed files with 580 additions and 238 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013 Basis Technology Corp. * Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,20 +19,18 @@
package org.sleuthkit.autopsy.actions; package org.sleuthkit.autopsy.actions;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.Presenter; import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.coreutils.Logger;
/** /**
* An abstract base class for Actions that allow users to tag SleuthKit data * An abstract base class for Actions that allow users to tag SleuthKit data
@ -98,12 +96,8 @@ abstract class AddTagAction extends TagAction implements Presenter.Popup {
if (null != tagNames && !tagNames.isEmpty()) { if (null != tagNames && !tagNames.isEmpty()) {
for (final TagName tagName : tagNames) { for (final TagName tagName : tagNames) {
JMenuItem tagNameItem = new JMenuItem(tagName.getDisplayName()); JMenuItem tagNameItem = new JMenuItem(tagName.getDisplayName());
tagNameItem.addActionListener(new ActionListener() { tagNameItem.addActionListener((ActionEvent e) -> {
@Override
public void actionPerformed(ActionEvent e) {
addTag(tagName, NO_COMMENT); addTag(tagName, NO_COMMENT);
refreshDirectoryTree();
}
}); });
quickTagMenu.add(tagNameItem); quickTagMenu.add(tagNameItem);
} }
@ -120,14 +114,10 @@ abstract class AddTagAction extends TagAction implements Presenter.Popup {
// Selecting this item initiates a dialog that can be used to create // Selecting this item initiates a dialog that can be used to create
// or select a tag name and adds a tag with the resulting name. // or select a tag name and adds a tag with the resulting name.
JMenuItem newTagMenuItem = new JMenuItem(NbBundle.getMessage(this.getClass(), "AddTagAction.newTag")); JMenuItem newTagMenuItem = new JMenuItem(NbBundle.getMessage(this.getClass(), "AddTagAction.newTag"));
newTagMenuItem.addActionListener(new ActionListener() { newTagMenuItem.addActionListener((ActionEvent e) -> {
@Override
public void actionPerformed(ActionEvent e) {
TagName tagName = GetTagNameDialog.doDialog(); TagName tagName = GetTagNameDialog.doDialog();
if (tagName != null) { if (null != tagName) {
addTag(tagName, NO_COMMENT); addTag(tagName, NO_COMMENT);
refreshDirectoryTree();
}
} }
}); });
quickTagMenu.add(newTagMenuItem); quickTagMenu.add(newTagMenuItem);
@ -137,14 +127,10 @@ abstract class AddTagAction extends TagAction implements Presenter.Popup {
// optional comment and adds a tag with the resulting name. // optional comment and adds a tag with the resulting name.
JMenuItem tagAndCommentItem = new JMenuItem( JMenuItem tagAndCommentItem = new JMenuItem(
NbBundle.getMessage(this.getClass(), "AddTagAction.tagAndComment")); NbBundle.getMessage(this.getClass(), "AddTagAction.tagAndComment"));
tagAndCommentItem.addActionListener(new ActionListener() { tagAndCommentItem.addActionListener((ActionEvent e) -> {
@Override
public void actionPerformed(ActionEvent e) {
GetTagNameAndCommentDialog.TagNameAndComment tagNameAndComment = GetTagNameAndCommentDialog.doDialog(); GetTagNameAndCommentDialog.TagNameAndComment tagNameAndComment = GetTagNameAndCommentDialog.doDialog();
if (null != tagNameAndComment) { if (null != tagNameAndComment) {
addTag(tagNameAndComment.getTagName(), tagNameAndComment.getComment()); addTag(tagNameAndComment.getTagName(), tagNameAndComment.getComment());
refreshDirectoryTree();
}
} }
}); });
add(tagAndCommentItem); add(tagAndCommentItem);

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013 Basis Technology Corp. * Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -20,14 +20,12 @@ package org.sleuthkit.autopsy.actions;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact;
/** /**
* Abstract base class for Actions involving tags. * Abstract base class for Actions involving tags.
*/ */
abstract class TagAction extends AbstractAction { abstract class TagAction extends AbstractAction {
public TagAction(String menuText) { public TagAction(String menuText) {
super(menuText); super(menuText);
} }
@ -35,26 +33,13 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
@Override @Override
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
doAction(event); doAction(event);
refreshDirectoryTree();
} }
/** /**
* Derived classes must implement this Template Method for actionPerformed(). * Derived classes must implement this Template Method for
* actionPerformed().
*
* @param event ActionEvent object passed to actionPerformed() * @param event ActionEvent object passed to actionPerformed()
*/ */
abstract protected void doAction(ActionEvent event); abstract protected void doAction(ActionEvent event);
/**
* Derived classes should call this method any time a tag is created, updated
* or deleted outside of an actionPerformed() call.
*/
@SuppressWarnings("deprecation")
protected void refreshDirectoryTree() {
/* Note: this is a hack. In an ideal world, TagsManager would fire events so
* that the directory tree would refresh. But, we haven't had a chance to add
* that so, we fire these events and the tree refreshes based on them.
*/
IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent("TagAction", BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE)); //NON-NLS
}
} }

View File

@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.casemodule; package org.sleuthkit.autopsy.casemodule;
import java.awt.Frame; import java.awt.Frame;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeSupport;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@ -49,8 +50,19 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.datamodel.*; import org.sleuthkit.autopsy.events.BlackBoardArtifactTagAddedEvent;
import org.sleuthkit.autopsy.events.BlackBoardArtifactTagDeletedEvent;
import org.sleuthkit.autopsy.events.ContentTagAddedEvent;
import org.sleuthkit.autopsy.events.ContentTagDeletedEvent;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.Image;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess; import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskException;
/** /**
* Stores all information for a given case. Only a single case can currently be * Stores all information for a given case. Only a single case can currently be
@ -126,7 +138,19 @@ public class Case implements SleuthkitCase.ErrorObserver {
* case. The old value supplied by the event object is null and the new * case. The old value supplied by the event object is null and the new
* value is a reference to a Report object representing the new report. * value is a reference to a Report object representing the new report.
*/ */
REPORT_ADDED; REPORT_ADDED,
/** Property name for the event when a new BlackBoardArtifactTag is
* added. The new value is tag added, the old value is empty */
BLACKBOARD_ARTIFACT_TAG_ADDED,
/** Property name for the event when a new BlackBoardArtifactTag is
* deleted. The new value is empty, the old value is the deleted tag */
BLACKBOARD_ARTIFACT_TAG_DELETED,
/** Property name for the event when a new ContentTag is
* added. The new value is tag added, the old value is empty */
CONTENT_TAG_ADDED,
/** Property name for the event when a new ContentTag is
* deleted. The new value is empty, the old value is the deleted tag */
CONTENT_TAG_DELETED;
}; };
private String name; private String name;
@ -267,7 +291,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
/** /**
* Creates a new case (create the XML config file and database) * Creates a new case (create the XML config file and database)
* *
* @param caseDir The directory to store case data in. Will be created if it * @param caseDir The directory to store case data in. Will be created if
* it
* doesn't already exist. If it exists, it should have all of the needed sub * doesn't already exist. If it exists, it should have all of the needed sub
* dirs that createCaseDirectory() will create. * dirs that createCaseDirectory() will create.
* @param caseName the name of case * @param caseName the name of case
@ -476,6 +501,59 @@ public class Case implements SleuthkitCase.ErrorObserver {
CoreComponentControl.openCoreWindows(); CoreComponentControl.openCoreWindows();
} }
/**
* Notifies the UI that a new ContentTag has been added.
*
* @param newTag new ContentTag added
*/
public void notifyContentTagAdded(ContentTag newTag) {
notify(new ContentTagAddedEvent(newTag));
}
/**
* Notifies the UI that a ContentTag has been deleted.
*
* @param deletedTag ContentTag deleted
*/
public void notifyContentTagDeleted(ContentTag deletedTag) {
notify(new ContentTagDeletedEvent(deletedTag));
}
/**
* Notifies the UI that a new BlackboardArtifactTag has been added.
*
* @param newTag new BlackboardArtifactTag added
*/
public void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag) {
notify(new BlackBoardArtifactTagAddedEvent(newTag));
}
/**
* Notifies the UI that a BlackboardArtifactTag has been.
*
* @param deletedTag BlackboardArtifactTag deleted
*/
public void notifyBlackBoardArtifactTagDeleted(BlackboardArtifactTag deletedTag) {
notify(new BlackBoardArtifactTagDeletedEvent(deletedTag));
}
/**
* Notifies the UI about a Case level event.
*
* @param propertyChangeEvent the event to distribute
*/
private void notify(final PropertyChangeEvent propertyChangeEvent) {
try {
pcs.firePropertyChange(propertyChangeEvent);
} catch (Exception e) {
logger.log(Level.SEVERE, "Case threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
NbBundle.getMessage(this.getClass(),
"Case.changeCase.errListenToCaseUpdates.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
/** /**
* @return The Services object for this case. * @return The Services object for this case.
*/ */
@ -801,6 +879,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Get the data model Content objects in the root of this case's hierarchy. * Get the data model Content objects in the root of this case's hierarchy.
* *
* @return a list of the root objects * @return a list of the root objects
*
* @throws org.sleuthkit.datamodel.TskCoreException * @throws org.sleuthkit.datamodel.TskCoreException
*/ */
public List<Content> getDataSources() throws TskCoreException { public List<Content> getDataSources() throws TskCoreException {
@ -1154,12 +1233,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
/** /**
* Adds a report to the case. * Adds a report to the case.
* *
* @param [in] localPath The path of the report file, must be in the case * @param localPath The path of the report file, must be in the case
* directory or one of its subdirectories. * directory or one of its subdirectories.
* @param [in] sourceModuleName The name of the module that created the * @param sourceModuleName The name of the module that created the
* report. * report.
* @param [in] reportName The report name, may be empty. * @param reportName The report name, may be empty.
*
* @return A Report data transfer object (DTO) for the new row. * @return A Report data transfer object (DTO) for the new row.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public void addReport(String localPath, String srcModuleName, String reportName) throws TskCoreException { public void addReport(String localPath, String srcModuleName, String reportName) throws TskCoreException {

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2013 Basis Technology Corp. * Copyright 2013-15 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -24,9 +24,9 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardArtifactTag;
@ -42,23 +42,27 @@ import org.sleuthkit.datamodel.TskCoreException;
* blackboard artifacts by users. * blackboard artifacts by users.
*/ */
public class TagsManager implements Closeable { public class TagsManager implements Closeable {
private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS
private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS
private final SleuthkitCase tskCase; private final SleuthkitCase tskCase;
private final HashMap<String, TagName> uniqueTagNames = new HashMap<>(); private final HashMap<String, TagName> uniqueTagNames = new HashMap<>();
private boolean tagNamesInitialized = false; // @@@ This is part of a work around to be removed when database access on the EDT is correctly synchronized. private boolean tagNamesInitialized = false; // @@@ This is part of a work around to be removed when database access on the EDT is correctly synchronized.
// Use this exception and the member hash map to manage uniqueness of hash /**
// names. This is deemed more proactive and informative than leaving this to * Use this exception and the member hash map to manage uniqueness of hash
// the UNIQUE constraint on the display_name field of the tag_names table in * names. This is deemed more proactive and informative than leaving this to
// the case database. * the UNIQUE constraint on the display_name field of the tag_names table in
public class TagNameAlreadyExistsException extends Exception { * the case database.
*/
public static class TagNameAlreadyExistsException extends Exception {
} }
/** /**
* Package-scope constructor for use of the Services class. An instance of * Package-scope constructor for use of the Services class. An instance of
* TagsManager should be created for each case that is opened. * TagsManager should be created for each case that is opened.
* @param [in] tskCase The SleuthkitCase object for the current case. *
* @param tskCase The SleuthkitCase object for the current case.
*/ */
TagsManager(SleuthkitCase tskCase) { TagsManager(SleuthkitCase tskCase) {
this.tskCase = tskCase; this.tskCase = tskCase;
@ -69,7 +73,9 @@ public class TagsManager implements Closeable {
/** /**
* Gets a list of all tag names currently available for tagging content or * Gets a list of all tag names currently available for tagging content or
* blackboard artifacts. * blackboard artifacts.
*
* @return A list, possibly empty, of TagName data transfer objects (DTOs). * @return A list, possibly empty, of TagName data transfer objects (DTOs).
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized List<TagName> getAllTagNames() throws TskCoreException { public synchronized List<TagName> getAllTagNames() throws TskCoreException {
@ -84,7 +90,9 @@ public class TagsManager implements Closeable {
/** /**
* Gets a list of all tag names currently used for tagging content or * Gets a list of all tag names currently used for tagging content or
* blackboard artifacts. * blackboard artifacts.
*
* @return A list, possibly empty, of TagName data transfer objects (DTOs). * @return A list, possibly empty, of TagName data transfer objects (DTOs).
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized List<TagName> getTagNamesInUse() throws TskCoreException { public synchronized List<TagName> getTagNamesInUse() throws TskCoreException {
@ -98,7 +106,9 @@ public class TagsManager implements Closeable {
/** /**
* Checks whether a tag name with a given display name exists. * Checks whether a tag name with a given display name exists.
* @param [in] tagDisplayName The display name for which to check. *
* @param tagDisplayName The display name for which to check.
*
* @return True if the tag name exists, false otherwise. * @return True if the tag name exists, false otherwise.
*/ */
public synchronized boolean tagNameExists(String tagDisplayName) { public synchronized boolean tagNameExists(String tagDisplayName) {
@ -112,8 +122,12 @@ public class TagsManager implements Closeable {
/** /**
* Adds a new tag name to the current case and to the tags settings. * Adds a new tag name to the current case and to the tags settings.
* @param [in] displayName The display name for the new tag name. *
* @return A TagName data transfer object (DTO) representing the new tag name. * @param displayName The display name for the new tag name.
*
* @return A TagName data transfer object (DTO) representing the new tag
* name.
*
* @throws TagNameAlreadyExistsException, TskCoreException * @throws TagNameAlreadyExistsException, TskCoreException
*/ */
public TagName addTagName(String displayName) throws TagNameAlreadyExistsException, TskCoreException { public TagName addTagName(String displayName) throws TagNameAlreadyExistsException, TskCoreException {
@ -122,9 +136,13 @@ public class TagsManager implements Closeable {
/** /**
* Adds a new tag name to the current case and to the tags settings. * Adds a new tag name to the current case and to the tags settings.
* @param [in] displayName The display name for the new tag name. *
* @param [in] description The description for the new tag name. * @param displayName The display name for the new tag name.
* @return A TagName data transfer object (DTO) representing the new tag name. * @param description The description for the new tag name.
*
* @return A TagName data transfer object (DTO) representing the new tag
* name.
*
* @throws TagNameAlreadyExistsException, TskCoreException * @throws TagNameAlreadyExistsException, TskCoreException
*/ */
public TagName addTagName(String displayName, String description) throws TagNameAlreadyExistsException, TskCoreException { public TagName addTagName(String displayName, String description) throws TagNameAlreadyExistsException, TskCoreException {
@ -133,10 +151,14 @@ public class TagsManager implements Closeable {
/** /**
* Adds a new tag name to the current case and to the tags settings. * Adds a new tag name to the current case and to the tags settings.
* @param [in] displayName The display name for the new tag name. *
* @param [in] description The description for the new tag name. * @param displayName The display name for the new tag name.
* @param [in] color The HTML color to associate with the new tag name. * @param description The description for the new tag name.
* @return A TagName data transfer object (DTO) representing the new tag name. * @param color The HTML color to associate with the new tag name.
*
* @return A TagName data transfer object (DTO) representing the new tag
* name.
*
* @throws TagNameAlreadyExistsException, TskCoreException * @throws TagNameAlreadyExistsException, TskCoreException
*/ */
public synchronized TagName addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException { public synchronized TagName addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException {
@ -161,9 +183,12 @@ public class TagsManager implements Closeable {
/** /**
* Tags a content object. * Tags a content object.
* @param [in] content The content to tag. *
* @param [in] tagName The name to use for the tag. * @param content The content to tag.
* @param tagName The name to use for the tag.
*
* @return A ContentTag data transfer object (DTO) representing the new tag. * @return A ContentTag data transfer object (DTO) representing the new tag.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public ContentTag addContentTag(Content content, TagName tagName) throws TskCoreException { public ContentTag addContentTag(Content content, TagName tagName) throws TskCoreException {
@ -172,10 +197,13 @@ public class TagsManager implements Closeable {
/** /**
* Tags a content object. * Tags a content object.
* @param [in] content The content to tag. *
* @param [in] tagName The name to use for the tag. * @param content The content to tag.
* @param [in] comment A comment to store with the tag. * @param tagName The name to use for the tag.
* @param comment A comment to store with the tag.
*
* @return A ContentTag data transfer object (DTO) representing the new tag. * @return A ContentTag data transfer object (DTO) representing the new tag.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public ContentTag addContentTag(Content content, TagName tagName, String comment) throws TskCoreException { public ContentTag addContentTag(Content content, TagName tagName, String comment) throws TskCoreException {
@ -184,12 +212,15 @@ public class TagsManager implements Closeable {
/** /**
* Tags a content object or a section of a content object. * Tags a content object or a section of a content object.
* @param [in] content The content to tag. *
* @param [in] tagName The name to use for the tag. * @param content The content to tag.
* @param [in] comment A comment to store with the tag. * @param tagName The name to use for the tag.
* @param [in] beginByteOffset Designates the beginning of a tagged section. * @param comment A comment to store with the tag.
* @param [in] endByteOffset Designates the end of a tagged section. * @param beginByteOffset Designates the beginning of a tagged section.
* @param endByteOffset Designates the end of a tagged section.
*
* @return A ContentTag data transfer object (DTO) representing the new tag. * @return A ContentTag data transfer object (DTO) representing the new tag.
*
* @throws IllegalArgumentException, TskCoreException * @throws IllegalArgumentException, TskCoreException
*/ */
public synchronized ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException { public synchronized ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException {
@ -216,13 +247,16 @@ public class TagsManager implements Closeable {
NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg")); NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg"));
} }
} }
final ContentTag newContentTag = tskCase.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset);
return tskCase.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset); Case.getCurrentCase().notifyContentTagAdded(newContentTag);
return newContentTag;
} }
/** /**
* Deletes a content tag. * Deletes a content tag.
* @param [in] tag The tag to delete. *
* @param tag The tag to delete.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized void deleteContentTag(ContentTag tag) throws TskCoreException { public synchronized void deleteContentTag(ContentTag tag) throws TskCoreException {
@ -232,11 +266,14 @@ public class TagsManager implements Closeable {
} }
tskCase.deleteContentTag(tag); tskCase.deleteContentTag(tag);
Case.getCurrentCase().notifyContentTagDeleted(tag);
} }
/** /**
* Gets all content tags for the current case. * Gets all content tags for the current case.
*
* @return A list, possibly empty, of content tags. * @return A list, possibly empty, of content tags.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public List<ContentTag> getAllContentTags() throws TskCoreException { public List<ContentTag> getAllContentTags() throws TskCoreException {
@ -250,8 +287,11 @@ public class TagsManager implements Closeable {
/** /**
* Gets content tags count by tag name. * Gets content tags count by tag name.
* @param [in] tagName The tag name of interest. *
* @param tagName The tag name of interest.
*
* @return A count of the content tags with the specified tag name. * @return A count of the content tags with the specified tag name.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException { public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException {
@ -265,8 +305,12 @@ public class TagsManager implements Closeable {
/** /**
* Gets content tags by tag name. * Gets content tags by tag name.
* @param [in] tagName The tag name of interest. *
* @return A list, possibly empty, of the content tags with the specified tag name. * @param tagName The tag name of interest.
*
* @return A list, possibly empty, of the content tags with the specified
* tag name.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized List<ContentTag> getContentTagsByTagName(TagName tagName) throws TskCoreException { public synchronized List<ContentTag> getContentTagsByTagName(TagName tagName) throws TskCoreException {
@ -280,8 +324,12 @@ public class TagsManager implements Closeable {
/** /**
* Gets content tags count by content. * Gets content tags count by content.
* @param [in] content The content of interest. *
* @return A list, possibly empty, of the tags that have been applied to the artifact. * @param content The content of interest.
*
* @return A list, possibly empty, of the tags that have been applied to the
* artifact.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException { public synchronized List<ContentTag> getContentTagsByContent(Content content) throws TskCoreException {
@ -295,9 +343,13 @@ public class TagsManager implements Closeable {
/** /**
* Tags a blackboard artifact object. * Tags a blackboard artifact object.
* @param [in] artifact The blackboard artifact to tag. *
* @param [in] tagName The name to use for the tag. * @param artifact The blackboard artifact to tag.
* @return A BlackboardArtifactTag data transfer object (DTO) representing the new tag. * @param tagName The name to use for the tag.
*
* @return A BlackboardArtifactTag data transfer object (DTO) representing
* the new tag.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName) throws TskCoreException { public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName) throws TskCoreException {
@ -306,10 +358,14 @@ public class TagsManager implements Closeable {
/** /**
* Tags a blackboard artifact object. * Tags a blackboard artifact object.
* @param [in] artifact The blackboard artifact to tag. *
* @param [in] tagName The name to use for the tag. * @param artifact The blackboard artifact to tag.
* @param [in] comment A comment to store with the tag. * @param tagName The name to use for the tag.
* @return A BlackboardArtifactTag data transfer object (DTO) representing the new tag. * @param comment A comment to store with the tag.
*
* @return A BlackboardArtifactTag data transfer object (DTO) representing
* the new tag.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException { public synchronized BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException {
@ -318,12 +374,16 @@ public class TagsManager implements Closeable {
getExistingTagNames(); getExistingTagNames();
} }
return tskCase.addBlackboardArtifactTag(artifact, tagName, comment); BlackboardArtifactTag addBlackboardArtifactTag = tskCase.addBlackboardArtifactTag(artifact, tagName, comment);
Case.getCurrentCase().notifyBlackBoardArtifactTagAdded(addBlackboardArtifactTag);
return addBlackboardArtifactTag;
} }
/** /**
* Deletes a blackboard artifact tag. * Deletes a blackboard artifact tag.
* @param [in] tag The tag to delete. *
* @param tag The tag to delete.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException { public synchronized void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException {
@ -333,11 +393,14 @@ public class TagsManager implements Closeable {
} }
tskCase.deleteBlackboardArtifactTag(tag); tskCase.deleteBlackboardArtifactTag(tag);
Case.getCurrentCase().notifyBlackBoardArtifactTagDeleted(tag);
} }
/** /**
* Gets all blackboard artifact tags for the current case. * Gets all blackboard artifact tags for the current case.
*
* @return A list, possibly empty, of blackboard artifact tags. * @return A list, possibly empty, of blackboard artifact tags.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException { public List<BlackboardArtifactTag> getAllBlackboardArtifactTags() throws TskCoreException {
@ -351,8 +414,12 @@ public class TagsManager implements Closeable {
/** /**
* Gets blackboard artifact tags count by tag name. * Gets blackboard artifact tags count by tag name.
* @param [in] tagName The tag name of interest. *
* @return A count of the blackboard artifact tags with the specified tag name. * @param tagName The tag name of interest.
*
* @return A count of the blackboard artifact tags with the specified tag
* name.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException { public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException {
@ -366,8 +433,12 @@ public class TagsManager implements Closeable {
/** /**
* Gets blackboard artifact tags by tag name. * Gets blackboard artifact tags by tag name.
* @param [in] tagName The tag name of interest. *
* @return A list, possibly empty, of the blackboard artifact tags with the specified tag name. * @param tagName The tag name of interest.
*
* @return A list, possibly empty, of the blackboard artifact tags with the
* specified tag name.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException { public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException {
@ -381,8 +452,12 @@ public class TagsManager implements Closeable {
/** /**
* Gets blackboard artifact tags for a particular blackboard artifact. * Gets blackboard artifact tags for a particular blackboard artifact.
* @param [in] artifact The blackboard artifact of interest. *
* @return A list, possibly empty, of the tags that have been applied to the artifact. * @param artifact The blackboard artifact of interest.
*
* @return A list, possibly empty, of the tags that have been applied to the
* artifact.
*
* @throws TskCoreException * @throws TskCoreException
*/ */
public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException { public synchronized List<BlackboardArtifactTag> getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException {
@ -413,8 +488,7 @@ public class TagsManager implements Closeable {
for (TagName tagName : currentTagNames) { for (TagName tagName : currentTagNames) {
uniqueTagNames.put(tagName.getDisplayName(), tagName); uniqueTagNames.put(tagName.getDisplayName(), tagName);
} }
} } catch (TskCoreException ex) {
catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag types from the current case", ex); //NON-NLS Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag types from the current case", ex); //NON-NLS
} }
} }
@ -433,8 +507,7 @@ public class TagsManager implements Closeable {
try { try {
TagName tagName = tskCase.addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2])); TagName tagName = tskCase.addTagName(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.getColorByName(tagNameAttributes[2]));
uniqueTagNames.put(tagName.getDisplayName(), tagName); uniqueTagNames.put(tagName.getDisplayName(), tagName);
} } catch (TskCoreException ex) {
catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add saved tag name " + tagNameAttributes[0], ex); //NON-NLS
} }
} }
@ -448,8 +521,7 @@ public class TagsManager implements Closeable {
TagName tagName = tskCase.addTagName( TagName tagName = tskCase.addTagName(
NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), "", TagName.HTML_COLOR.NONE); NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), "", TagName.HTML_COLOR.NONE);
uniqueTagNames.put(tagName.getDisplayName(), tagName); uniqueTagNames.put(tagName.getDisplayName(), tagName);
} } catch (TskCoreException ex) {
catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add predefined 'Bookmark' tag name", ex); //NON-NLS Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add predefined 'Bookmark' tag name", ex); //NON-NLS
} }
} }

View File

@ -35,8 +35,6 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TagName;
@ -119,19 +117,14 @@ public class Tags implements AutopsyVisitableItem {
private final PropertyChangeListener pcl = new PropertyChangeListener() { private final PropertyChangeListener pcl = new PropertyChangeListener() {
@Override @Override
@SuppressWarnings("deprecation")
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName(); String eventType = evt.getPropertyName();
if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) { if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString())
/* Note: this is a hack. In an ideal world, TagsManager || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString())
* would fire events so that the directory tree would || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())
* refresh. But, we haven't had a chance to add that so, we || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) {
* fire these events and the tree refreshes based on them. */
if ((((ModuleDataEvent) evt.getOldValue()).getArtifactType() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT)
|| ((ModuleDataEvent) evt.getOldValue()).getArtifactType() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE) {
refresh(true); refresh(true);
tagResults.update(); tagResults.update();
}
} else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) { } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
refresh(true); refresh(true);
tagResults.update(); tagResults.update();

View File

@ -0,0 +1,33 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.events;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
/**
*
*/
public class BlackBoardArtifactTagAddedEvent extends TagAddedEvent<BlackboardArtifactTag> {
public BlackBoardArtifactTagAddedEvent(BlackboardArtifactTag newTag) {
super(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString(), newTag
);
}
}

View File

@ -0,0 +1,32 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.events;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
/**
*
*/
public class BlackBoardArtifactTagDeletedEvent extends TagDeletedEvent<BlackboardArtifactTag> {
public BlackBoardArtifactTagDeletedEvent(BlackboardArtifactTag oldValue) {
super(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString(), oldValue);
}
}

View File

@ -0,0 +1,35 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.events;
import javax.annotation.concurrent.Immutable;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.ContentTag;
/**
* An event that is fired when a ContentTag is added.
*/
@Immutable
public class ContentTagAddedEvent extends TagAddedEvent<ContentTag> {
public ContentTagAddedEvent(ContentTag newTag) {
super(Case.Events.CONTENT_TAG_ADDED.toString(), newTag);
}
}

View File

@ -0,0 +1,34 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.events;
import javax.annotation.concurrent.Immutable;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.ContentTag;
/**
* An event that is fired when a ContentTag is deleted.
*/
@Immutable
public class ContentTagDeletedEvent extends TagDeletedEvent<ContentTag> {
public ContentTagDeletedEvent(ContentTag deletedTag) {
super(Case.Events.CONTENT_TAG_DELETED.toString(), deletedTag);
}
}

View File

@ -0,0 +1,46 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.events;
import java.beans.PropertyChangeEvent;
import javax.annotation.concurrent.Immutable;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Tag;
/**
* Base Class for events that are fired when a Tag is added
*/
@Immutable
abstract class TagAddedEvent<T extends Tag> extends PropertyChangeEvent {
protected TagAddedEvent(String propertyName, T newValue) {
super(Case.class, propertyName, null, newValue);
}
/**
* get the Tag that was added
*
* @return the tTag
*/
@SuppressWarnings("unchecked")
public T getAddedTag() {
return (T) getNewValue();
}
}

View File

@ -0,0 +1,45 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2015 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.events;
import java.beans.PropertyChangeEvent;
import javax.annotation.concurrent.Immutable;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Tag;
/**
* Base Class for events that are fired when a Tag is deleted
*/
@Immutable
abstract class TagDeletedEvent<T extends Tag> extends PropertyChangeEvent {
protected TagDeletedEvent(String propertyName, T oldValue) {
super(Case.class, propertyName, oldValue, null);
}
/**
* get the Tag that was deleted
*
* @return the Tag
*/
@SuppressWarnings("unchecked")
public T getDeletedTag() {
return (T) getOldValue();
}
}