Filled out new tags API for data, DTOs

This commit is contained in:
Richard Cordovano 2013-09-25 16:44:56 -04:00
parent e3940da25b
commit a40481f5f8
4 changed files with 273 additions and 17 deletions

View File

@ -48,6 +48,7 @@ public class Services implements Closeable {
//create and initialize FileManager as early as possibly in the new/opened Case
fileManager = new FileManager(tskCase);
services.add(fileManager);
tagsManager = new TagsManager(tskCase);
services.add(tagsManager);
}

View File

@ -20,21 +20,228 @@ package org.sleuthkit.autopsy.casemodule.services;
import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagType;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A instance of this class functions as an Autopsy service that manages the
* creation, updating, and deletion of tags applied to files and artifacts by
* users.
* A singleton instance of this class functions as an Autopsy service that
* manages the creation, updating, and deletion of tags applied to Content and
* BlackboardArtifacts objects by users.
*/
public class TagsManager implements Closeable {
private final SleuthkitCase database;
private static final String TAGS_SETTINGS_FILE_NAME = "tags";
private static final String TAG_TYPES_SETTING_KEY = "tagTypes";
private final SleuthkitCase tskCase;
private final HashMap<String, TagType> tagTypes = new HashMap<>();
TagsManager(SleuthkitCase database) {
this.database = database;
TagsManager(SleuthkitCase tskCase) {
this.tskCase = tskCase;
loadTagTypesFromTagSettings();
}
private void loadTagTypesFromTagSettings() {
// Get any tag types already added to the current case.
try {
List<TagType> currentTagTypes = tskCase.getTagTypes();
for (TagType tagType : currentTagTypes) {
tagTypes.put(tagType.getDisplayName(), tagType);
}
}
catch (TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag types from the current case", ex);
}
// Read the saved tag types, if any, from the tags settings file and
// add them to the current case if they haven't already been added, e.g,
// when the case was last opened.
String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_FILE_NAME, TAG_TYPES_SETTING_KEY);
if (null != setting && !setting.isEmpty()) {
// Read the tag types setting and break in into tag type tuples.
List<String> tagTypeTuples = Arrays.asList(setting.split(";"));
// Parse each tuple and add the tag types to the current case, one
// at a time to gracefully discard any duplicates or corrupt tuples.
for (String tagTypeTuple : tagTypeTuples) {
String[] tagTypeAttributes = tagTypeTuple.split(",");
if (!tagTypes.containsKey(tagTypeAttributes[0])) {
TagType tagType = new TagType(tagTypeAttributes[0], tagTypeAttributes[1], TagType.HTML_COLOR.getColorByName(tagTypeAttributes[2]));
try {
tskCase.addTagType(tagType);
tagTypes.put(tagType.getDisplayName(),tagType);
}
catch(TskCoreException ex) {
Logger.getLogger(TagsManager.class.getName()).log(Level.WARNING, "Failed to add saved " + tagType.getDisplayName() + " tag type to the current case", ex);
}
}
}
saveTagTypesToTagsSettings();
}
}
private void saveTagTypesToTagsSettings() {
if (!tagTypes.isEmpty()) {
StringBuilder setting = new StringBuilder();
for (TagType tagType : tagTypes.values()) {
if (setting.length() != 0) {
setting.append(";");
}
setting.append(tagType.getDisplayName()).append(",");
setting.append(tagType.getDescription()).append(",");
setting.append(tagType.getColor().name());
}
ModuleSettings.setConfigSetting(TAGS_SETTINGS_FILE_NAME, TAG_TYPES_SETTING_KEY, setting.toString());
}
}
/**
* Gets a list of all tag types currently available for tagging content or
* blackboard artifacts.
* @return A list, possibly empty, of TagType data transfer objects (DTOs).
* @throws TskCoreException
*/
public List<TagType> getTagTypes() throws TskCoreException {
return tskCase.getTagTypes();
}
/**
* Adds a new tag type to the current case and to the tags settings file.
* @param displayName The display name for the new tag type.
* @return A TagType object representing the new type on success, null on failure.
* @throws TskCoreException
*/
public TagType addTagType(String displayName) throws TagTypeAlreadyExistsException, TskCoreException {
return addTagType(displayName, "", TagType.HTML_COLOR.NONE);
}
/**
* Adds a new tag type to the current case and to the tags settings file.
* @param displayName The display name for the new tag type.
* @param description The description for the new tag type.
* @return A TagType object representing the new type on success, null on failure.
* @throws TskCoreException
*/
public TagType addTagType(String displayName, String description) throws TagTypeAlreadyExistsException, TskCoreException {
return addTagType(displayName, description, TagType.HTML_COLOR.NONE);
}
/**
* Adds a new tag type to the current case and to the tags settings file.
* @param displayName The display name for the new tag type.
* @param description The description for the new tag type.
* @param color The HTML color to associate with the new tag type.
* @return A TagType object representing the new type.
* @throws TskCoreException
*/
public synchronized TagType addTagType(String displayName, String description, TagType.HTML_COLOR color) throws TagTypeAlreadyExistsException, TskCoreException {
if (tagTypes.containsKey(displayName)) {
throw new TagTypeAlreadyExistsException();
}
TagType newTagType = new TagType(displayName, description, color);
tskCase.addTagType(newTagType);
tagTypes.put(newTagType.getDisplayName(), newTagType);
saveTagTypesToTagsSettings();
return newTagType;
}
public class TagTypeAlreadyExistsException extends Exception {
}
/**
* Tags a Content object.
* @param content The Content to tag.
* @param tagType The type of tag to add.
* @throws TskCoreException
*/
public void addContentTag(Content content, TagType tagType) throws TskCoreException {
addContentTag(content, tagType, "", 0, content.getSize());
}
/**
* Tags a Content object.
* @param content The Content to tag.
* @param tagType The type of tag to add.
* @param comment A comment to store with the tag.
* @throws TskCoreException
*/
public void addContentTag(Content content, TagType tagType, String comment) throws TskCoreException {
addContentTag(content, tagType, comment, 0, content.getSize() - 1);
}
/**
* Tags a Content object or a portion of a content object.
* @param content The Content to tag.
* @param tagType The type of tag to add.
* @param comment A comment to store with the tag.
* @param beginByteOffset Designates the beginning of a tagged extent.
* @param endByteOffset Designates the end of a tagged extent.
* @throws TskCoreException
*/
public void addContentTag(Content content, TagType tagType, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException {
if (beginByteOffset < 0) {
throw new IllegalArgumentException("Content extent incorrect: beginByteOffset < 0");
}
if (endByteOffset <= beginByteOffset) {
throw new IllegalArgumentException("Content extent incorrect: endByteOffset <= beginByteOffset");
}
if (endByteOffset > content.getSize() - 1) {
throw new IllegalArgumentException("Content extent incorrect: endByteOffset exceeds content size");
}
tskCase.addContentTag(new ContentTag(content, tagType, comment, beginByteOffset, endByteOffset));
}
/**
* Deletes a content tag.
* @param tag The tag to delete.
* @throws TskCoreException
*/
public void deleteContentTag(ContentTag tag) throws TskCoreException {
tskCase.deleteContentTag(tag);
}
/**
* Tags a BlackboardArtifact object.
* @param artifact The BlackboardArtifact to tag.
* @param tagType The type of tag to add.
* @throws TskCoreException
*/
public void addBlackboardArtifactTag(BlackboardArtifact artifact, TagType tagType) throws TskCoreException {
addBlackboardArtifactTag(artifact, tagType, "");
}
/**
* Tags a BlackboardArtifact object.
* @param artifact The BlackboardArtifact to tag.
* @param tagType The type of tag to add.
* @param comment A comment to store with the tag.
* @throws TskCoreException
*/
public void addBlackboardArtifactTag(BlackboardArtifact artifact, TagType tagType, String comment) throws TskCoreException {
tskCase.addBlackboardArtifactTag(new BlackboardArtifactTag(artifact, tagType, comment));
}
void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException {
tskCase.deleteBlackboardArtifactTag(tag);
}
@Override
public void close() throws IOException {
saveTagTypesToTagsSettings();
}
}

View File

@ -20,12 +20,19 @@ package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent;
import java.util.Collection;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import org.openide.util.Utilities;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TagType;
import org.sleuthkit.datamodel.TskCoreException;
public class TagAbstractFileAction extends AbstractAction implements Presenter.Popup {
// This class is a singleton to support multi-selection of nodes, since
@ -60,10 +67,27 @@ public class TagAbstractFileAction extends AbstractAction implements Presenter.P
}
@Override
protected void applyTag(String tagName, String comment) {
protected void applyTag(String tagDisplayName, String comment) {
try {
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
TagType tagType = tagsManager.addTagType(tagDisplayName);
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
for (AbstractFile file : selectedFiles) {
Tags.createTag(file, tagName, comment);
Tags.createTag(file, tagDisplayName, comment);
try {
tagsManager.addContentTag(file, tagType);
}
catch (TskCoreException ex) {
Logger.getLogger(TagAbstractFileMenu.class.getName()).log(Level.SEVERE, "Error tagging content", ex);
}
}
}
catch (TagsManager.TagTypeAlreadyExistsException ex) {
JOptionPane.showMessageDialog(null, "A " + tagDisplayName + " tag type has already been defined.", "Duplicate Tag Type", JOptionPane.ERROR_MESSAGE);
}
catch (TskCoreException ex) {
Logger.getLogger(TagAbstractFileMenu.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag type", ex);
}
}
}

View File

@ -20,12 +20,19 @@ package org.sleuthkit.autopsy.directorytree;
import java.awt.event.ActionEvent;
import java.util.Collection;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import org.openide.util.Utilities;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TagType;
import org.sleuthkit.datamodel.TskCoreException;
public class TagBlackboardArtifactAction extends AbstractAction implements Presenter.Popup {
// This class is a singleton to support multi-selection of nodes, since
@ -61,10 +68,27 @@ public class TagBlackboardArtifactAction extends AbstractAction implements Prese
}
@Override
protected void applyTag(String tagName, String comment) {
protected void applyTag(String tagDisplayName, String comment) {
try {
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
TagType tagType = tagsManager.addTagType(tagDisplayName);
Collection<? extends BlackboardArtifact> selectedArtifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
for (BlackboardArtifact artifact : selectedArtifacts) {
Tags.createTag(artifact, tagName, comment);
Tags.createTag(artifact, tagDisplayName, comment);
try {
tagsManager.addBlackboardArtifactTag(artifact, tagType);
}
catch (TskCoreException ex) {
Logger.getLogger(TagBlackboardArtifactMenu.class.getName()).log(Level.SEVERE, "Error tagging result", ex);
}
}
}
catch (TagsManager.TagTypeAlreadyExistsException ex) {
JOptionPane.showMessageDialog(null, "A " + tagDisplayName + " tag type has already been defined.", "Duplicate Tag Type", JOptionPane.ERROR_MESSAGE);
}
catch (TskCoreException ex) {
Logger.getLogger(TagBlackboardArtifactMenu.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag type", ex);
}
}
}