From 6e60f9a9788c5a1c2c0a2362a53196c54d3ddccd Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Sun, 2 Oct 2016 23:31:56 -0400 Subject: [PATCH] Changes to tags management (partial) --- .../autopsy/actions/AddTagAction.java | 9 +- .../actions/GetTagNameAndCommentDialog.java | 4 +- .../autopsy/actions/GetTagNameDialog.java | 4 +- .../services/TagNamesSettingsPanel.form | 5 +- .../services/TagNamesSettingsPanel.java | 153 ++--- .../autopsy/casemodule/services/TagType.java | 177 +++++ .../casemodule/services/TagsManager.java | 639 ++++++------------ .../casemodule/services/UserTagName.java | 86 --- 8 files changed, 453 insertions(+), 624 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java delete mode 100755 Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 3d394e9215..5a9d371b50 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-15 Basis Technology Corp. + * Copyright 2011-2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -82,6 +82,8 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { // to be reworked. private class TagMenu extends JMenu { + private static final long serialVersionUID = 1L; + TagMenu() { super(getActionDisplayName()); @@ -89,10 +91,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); Map tagNamesMap = null; try { - tagNamesMap = new TreeMap<>(); - tagNamesMap.putAll(tagsManager.getUserTagNamesMap()); - tagNamesMap.putAll(tagsManager.getPredefinedTagNamesMap()); - tagNamesMap.putAll(tagsManager.getTagNamesInUseMap()); + tagNamesMap = new TreeMap<>(tagsManager.getDisplayNamesToTagNamesMap()); } catch (TskCoreException ex) { Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java index fa2b1b1593..5a30a49c72 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java @@ -118,9 +118,7 @@ public class GetTagNameAndCommentDialog extends JDialog { // not exist in the database). TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); try { - tagNamesMap.putAll(tagsManager.getUserTagNamesMap()); - tagNamesMap.putAll(tagsManager.getPredefinedTagNamesMap()); - tagNamesMap.putAll(tagsManager.getTagNamesInUseMap()); + tagNamesMap.putAll(tagsManager.getDisplayNamesToTagNamesMap()); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameAndCommentDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java index 5386af785a..268512898e 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java @@ -98,9 +98,7 @@ public class GetTagNameDialog extends JDialog { // case the user chooses an existing tag name from the tag names table. TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager(); try { - tagNamesMap.putAll(tagsManager.getUserTagNamesMap()); - tagNamesMap.putAll(tagsManager.getPredefinedTagNamesMap()); - tagNamesMap.putAll(tagsManager.getTagNamesInUseMap()); + tagNamesMap.putAll(tagsManager.getDisplayNamesToTagNamesMap()); } catch (TskCoreException ex) { Logger.getLogger(GetTagNameDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form index 4412f20274..5b896fdd36 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form @@ -138,8 +138,11 @@ - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java index 91a24e7ad2..1a74acc4ae 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java @@ -1,39 +1,35 @@ /* -* Autopsy Forensic Browser -* -* Copyright 2011-2016 Basis Technology Corp. -* Contact: carrier sleuthkit 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. -*/ + * Autopsy Forensic Browser + * + * Copyright 2011-2016 Basis Technology Corp. + * Contact: carrier sleuthkit 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.casemodule.services; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Set; +import java.util.TreeSet; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.ModuleSettings; /** * A panel to allow the user to create new tag names or to delete tag names that @@ -43,34 +39,26 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; */ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsPanel { - private static final Logger logger = Logger.getLogger(TagNamesSettingsPanel.class.getName()); - - private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS - private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS - + private static final long serialVersionUID = 1L; private static final String DEFAULT_DESCRIPTION = ""; private static final String DEFAULT_COLOR_STRING = "NONE"; - - private DefaultListModel tagNamesListModel; - private List tagNames; + private final DefaultListModel tagTypesListModel; + private final Set tagTypes; /** * Creates new form TagsManagerOptionsPanel */ TagNamesSettingsPanel() { + tagTypesListModel = new DefaultListModel<>(); + tagTypes = new TreeSet<>(TagType.getCustomTagTypes()); initComponents(); customizeComponents(); } - + private void customizeComponents() { - tagNamesListModel = new DefaultListModel<>(); - tagNamesList.setModel(tagNamesListModel); - tagNames = new ArrayList<>(); - tagNamesList.addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - enableButtons(); - } + tagNamesList.setModel(tagTypesListModel); + tagNamesList.addListSelectionListener((ListSelectionEvent event) -> { + enableButtons(); }); } @@ -103,6 +91,12 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.tagNamesListLabel.text")); // NOI18N + tagNamesList.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "TagType" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + tagNamesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane1.setViewportView(tagNamesList); newTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N @@ -200,38 +194,38 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP .addGap(0, 0, Short.MAX_VALUE)) ); }// //GEN-END:initComponents - + private void newTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagNameButtonActionPerformed NewUserTagNameDialog dialog = new NewUserTagNameDialog(); NewUserTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); if (result == NewUserTagNameDialog.BUTTON_PRESSED.OK) { String newTagDisplayName = dialog.getTagName(); - UserTagName newTagName = new UserTagName(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + TagType newTagType = new TagType(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); /* * If tag name already exists, don't add the tag name. */ - if (tagNames.contains(newTagName)) { + if (tagTypes.contains(newTagType)) { JOptionPane.showMessageDialog(null, NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message"), NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title"), JOptionPane.INFORMATION_MESSAGE); } else { - tagNames.add(newTagName); + tagTypes.add(newTagType); updateTagNamesListModel(); /* * Set the selection to the tag name that was just added. */ - int index = tagNames.indexOf(newTagName); + int index = tagTypes.indexOf(newTagType); tagNamesList.setSelectedIndex(index); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); } } }//GEN-LAST:event_newTagNameButtonActionPerformed - + private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed - UserTagName tagName = tagNamesList.getSelectedValue(); - tagNames.remove(tagName); + TagType tagName = tagNamesList.getSelectedValue(); + tagTypes.remove(tagName); updateTagNamesListModel(); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); @@ -254,17 +248,28 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP * Updates the tag names model for the tag names list component. */ private void updateTagNamesListModel() { - tagNamesListModel.clear(); - Set tagNameSet = new HashSet<>(); - tagNameSet.addAll(tagNames); - tagNames.clear(); - tagNames.addAll(tagNameSet); - Collections.sort(tagNames); - for (UserTagName tagName : tagNames) { - tagNamesListModel.addElement(tagName); + tagTypesListModel.clear(); + Set tagNameSet = new HashSet<>(); + tagNameSet.addAll(tagTypes); + tagTypes.clear(); + tagTypes.addAll(tagNameSet); + Collections.sort(tagTypes); + for (TagType tagName : tagTypes) { + tagTypesListModel.addElement(tagName); } } + /** + * Updates the tag names list component with tag names from the properties + * file. + */ + @Override + public void load() { + tagTypes = TagType.getCustomTagTypes(); + updateTagNamesListModel(); + enableButtons(); + } + /** * Stores tag name changes in the properties file, called when OK or Apply * is selected in the options panel. @@ -274,43 +279,15 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP */ @Override public void store() { - StringBuilder setting = new StringBuilder(); - for (UserTagName tagName : tagNames) { - if (setting.length() != 0) { - setting.append(";"); - } - setting.append(tagName.toSettingsFormat()); - } - ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString()); - if (Case.isCaseOpen()) { - Case.getCurrentCase().getServices().getTagsManager().storeNewUserTagNames(tagNames); - } + TagType.setCustomTagTypes(tagTypes); } /** - * Updates the tag names list component with tag names from the properties - * file. - */ - @Override - public void load() { - String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); - tagNames.clear(); - if (null != setting && !setting.isEmpty()) { - List tagNameTuples = Arrays.asList(setting.split(";")); - for (String tagNameTuple : tagNameTuples) { - String[] tagNameAttributes = tagNameTuple.split(","); - tagNames.add(new UserTagName(tagNameAttributes[0], tagNameAttributes[1], tagNameAttributes[2])); - } - } - updateTagNamesListModel(); - enableButtons(); - } - - /** - * Only enable delete button when there is a tag name selected in the list. + * Only enable the delete button when there is a tag type selected in the + * tag types JList. */ private void enableButtons() { - boolean ruleIsSelected = tagNamesList.getSelectedIndex() != -1; - deleteTagNameButton.setEnabled(ruleIsSelected); + deleteTagNameButton.setEnabled(tagNamesList.getSelectedIndex() != -1); } + } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java new file mode 100644 index 0000000000..71415cb615 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java @@ -0,0 +1,177 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2016 Basis Technology Corp. + * Contact: carrier sleuthkit 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.casemodule.services; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import javax.annotation.concurrent.Immutable; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; +import org.sleuthkit.datamodel.TagName; + +/** + * A tag type definition consisting of a display name, description and color. + */ +@Immutable +final class TagType implements Comparable { + + private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS + private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS + private final String displayName; + private final String description; + private final TagName.HTML_COLOR color; + + /** + * Constructs a tag type definition consisting of a display name, + * description and color. + * + * @param displayName The display name for the tag type. + * @param description The dcescription of the tag type. + * @param color The color to associate with the tag type. + */ + TagType(String displayName, String description, TagName.HTML_COLOR color) { + this.displayName = displayName; + this.description = description; + this.color = color; + } + + /** + * Gets the display name for a tag type. + * + * @return The display name. + */ + String getDisplayName() { + return displayName; + } + + /** + * Gets the description of a tag type. + * + * @return The description. + */ + String getDescription() { + return description; + } + + /** + * Gets the color associated with the tag type. + * + * @return The color. + */ + TagName.HTML_COLOR getColor() { + return color; + } + + /** + * Compares this tag type with the specified tag type for order. + * + * @param other The tag type to which to compare this tag type. + * + * @return Negative integer, zero, or a positive integer to indicate that + * this tag type is less than, equal to, or greater than the + * specified tag type. + */ + @Override + public int compareTo(TagType other) { + return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); + } + + /** + * Returns a hash code value for this tag type. + * + * @return The has code. + */ + @Override + public int hashCode() { + int hash = 7; + hash = 83 * hash + Objects.hashCode(this.displayName); + return hash; + } + + /** + * Indicates whether some other object is "equal to" this tag type. + * + * @param obj The object to test for equality. + * + * @return True or false. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TagType)) { + return false; + } + TagType thatTagName = (TagType) obj; + return this.getDisplayName().equals(thatTagName.getDisplayName()); + } + + /** + * A string representation of this tag type. + * + * @return The display name of the tag type. + */ + @Override + public String toString() { + return displayName; + } + + /** + * @return A string representation of the tag name in the format that is + * used by the properties file. + */ + private String toSettingsFormat() { + return displayName + "," + description + "," + color.name(); + } + + /** + * Gets the custom tag types for the current user. + * + * @return A set of tag type objects. + */ + static synchronized Set getCustomTagTypes() { + Set tagTypes = new HashSet<>(); + String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); + if (null != setting && !setting.isEmpty()) { + List tagNameTuples = Arrays.asList(setting.split(";")); + for (String tagNameTuple : tagNameTuples) { + String[] tagNameAttributes = tagNameTuple.split(","); + tagTypes.add(new TagType(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.valueOf(tagNameAttributes[2]))); + } + } + return tagTypes; + } + + /** + * Sets the custom tag types for the current user. + * + * @param tagTypes A set of tag type objects. + */ + static synchronized void setCustomTagTypes(Set tagTypes) { + StringBuilder setting = new StringBuilder(); + for (TagType tagType : tagTypes) { + if (setting.length() != 0) { + setting.append(";"); + } + setting.append(tagType.toSettingsFormat()); + } + ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString()); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 7798d3cf3a..9b7a62bc9c 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -1,37 +1,32 @@ /* -* Autopsy Forensic Browser -* -* Copyright 2011-2016 Basis Technology Corp. -* Contact: carrier sleuthkit 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. + * Autopsy Forensic Browser + * + * Copyright 2011-2016 Basis Technology Corp. + * Contact: carrier sleuthkit 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.casemodule.services; import java.io.Closeable; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; -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.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.Content; @@ -41,22 +36,17 @@ import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TskCoreException; /** - * A per case Autopsy service that manages the creation, updating, and deletion - * of tags applied to content and blackboard artifacts by users. + * A per case Autopsy service that manages the addition of content and artifact + * tags to the case database. */ public class TagsManager implements Closeable { - private static final Logger logger = Logger.getLogger(TagsManager.class.getName()); - private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS - private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS - private SleuthkitCase caseDb; - private final HashMap uniqueTagNames = new HashMap<>(); - private boolean tagNamesLoaded = false; + private static final Logger LOGGER = Logger.getLogger(TagsManager.class.getName()); + private final SleuthkitCase caseDb; /** - * Constructs a per case Autopsy service that manages the creation, - * updating, and deletion of tags applied to content and blackboard - * artifacts by users. + * Constructs a per case Autopsy service that manages the addition of + * content and artifact tags to the case database. * * @param caseDb The case database. */ @@ -67,205 +57,148 @@ public class TagsManager implements Closeable { /** * Gets a list of all tag names currently in the case database. * - * @return A list, possibly empty, of TagName data transfer objects (DTOs). + * @return A list, possibly empty, of TagName objects. * - * @throws TskCoreException If there is an error reading from the case - * database. + * @throws TskCoreException If there is an error querying the case database. */ - public synchronized List getAllTagNames() throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); + public List getAllTagNames() throws TskCoreException { return caseDb.getAllTagNames(); } /** - * Gets a mapping of user tag name display names to TagName DTOs if they - * have been added to the database. Otherwise, the display name maps to - * null. + * Gets a list of all tag names currently in use in the case database for + * tagging content or artifacts. * - * @return A map of String display name to TagName DTO, TagName may be null - */ - public synchronized Map getUserTagNamesMap() { - lazyLoadExistingTagNames(); - Map tagNamesMap = new HashMap<>(); - String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); - if (null != setting && !setting.isEmpty()) { - List tagNameTuples = Arrays.asList(setting.split(";")); - for (String tagNameTuple : tagNameTuples) { - String[] tagNameAttributes = tagNameTuple.split(","); - tagNamesMap.put(tagNameAttributes[0], uniqueTagNames.get(tagNameAttributes[0])); - } - } - return tagNamesMap; - } - - /** - * Gets a mapping of predefined tag names to their TagName DTOs. Currently - * only for the bookmark tag. - * - * @return A map of String display name to TagName DTO - */ - public synchronized Map getPredefinedTagNamesMap() { - Map tagNamesMap = new HashMap<>(); - TagName bookmarkTagName = uniqueTagNames.get(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text")); - tagNamesMap.put(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), bookmarkTagName); - return tagNamesMap; - } - - /** - * Gets a mapping of the display names of predefined tag names and tag names - * that are in use to their TagName DTOs. - * - * @return A map of String display name to TagName DTO - * - * @throws TskCoreException If there is an error reading from the case - * database. - */ - public synchronized Map getTagNamesInUseMap() throws TskCoreException { - List tagNames = getTagNamesInUse(); - Map tagNamesMap = new HashMap<>(); - for (TagName tagName : tagNames) { - tagNamesMap.put(tagName.getDisplayName(), tagName); - } - return tagNamesMap; - } - - /** - * Gets a list of all tag names currently in use for tagging content or - * artifacts. + * @return A list, possibly empty, of TagName objects. * - * @return A list, possibly empty, of TagName data transfer objects (DTOs). - * - * @throws TskCoreException If there is an error reading from the case - * database. + * @throws TskCoreException If there is an error querying the case database. */ - public synchronized List getTagNamesInUse() throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); + public List getTagNamesInUse() throws TskCoreException { return caseDb.getTagNamesInUse(); } /** - * Checks whether a tag name with a given display name exists. + * Gets a map of tag display names to tag name entries in the case database. + * It has keys for the display names of the standard tag types, the current + * user's custom tag types, and the tags in the case database. The value for + * a given key will be null if the corresponding tag type is defined, but a + * tag name entry has not yet added to the case database. In that case, + * addTagName may be called to add the tag name entry. * - * @param tagDisplayName The display name to check. + * @return A map of tag display names to possibly null TagName object + * references. * - * @return True or false. + * @throws TskCoreException if there is an error querying the case database. */ - public synchronized boolean tagNameExists(String tagDisplayName) { - lazyLoadExistingTagNames(); - return uniqueTagNames.containsKey(tagDisplayName) && - (uniqueTagNames.get(tagDisplayName) != null); + public synchronized Map getDisplayNamesToTagNamesMap() throws TskCoreException { + /** + * Order is important here. The keys (display names) for the standard + * tag types and current user's custom tag types are added to the map + * first, with null TagName values. If tag name entries exist for those + * keys, loading of the tag names from the database supplies the missing + * values. + * + * Note that creating the map on demand increases the probability that + * the display names of newly added custom tag types and the display + * names of tags added to a multi-user case by other users appear in the + * map. + */ + Map tagNames = new HashMap<>(); + tagNames.put("TagsManager.predefTagNames.bookmark.text", null); + Set customTypes = TagType.getCustomTagTypes(); + for (TagType tagType : customTypes) { + tagNames.put(tagType.getDisplayName(), null); + } + for (TagName tagName : caseDb.getAllTagNames()) { + tagNames.put(tagName.getDisplayName(), tagName); + } + return new HashMap<>(tagNames); } /** - * Adds a new tag name to the current case and to the tags settings. + * Adds a tag name entry to the case database and adds a corresponding + * tag type to the current user's custom tag types. * - * @param displayName The display name for the new tag name. + * @param displayName The display name for the new tag type. * - * @return A TagName data transfer object (DTO) representing the new tag - * name. + * @return A TagName representing the tag name database entry that can be + * used to add instances of the tag type to the case database. * - * @throws TagNameAlreadyExistsException If the tag name would be a - * duplicate. + * @throws TagNameAlreadyExistsException If the tag name already exists in + * the case database. * @throws TskCoreException If there is an error adding the tag - * to the case database. + * name to the case database. */ - public TagName addTagName(String displayName) throws TagNameAlreadyExistsException, TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } + public synchronized TagName addTagName(String displayName) throws TagNameAlreadyExistsException, TskCoreException { return addTagName(displayName, "", TagName.HTML_COLOR.NONE); } /** - * Adds a new tag name to the current case and to the tags settings. + * Adds a tag name entry to the case database and adds a corresponding + * tag type to the current user's custom tag types. * - * @param displayName The display name for the new tag name. - * @param description The description for the new tag name. + * @param displayName The display name for the new tag type. + * @param description The description for the new tag type. * - * @return A TagName data transfer object (DTO) representing the new tag - * name. + * @return A TagName object that can be used to add instances of the tag + * type to the case database. * - * @throws TagNameAlreadyExistsException If the tag name would be a - * duplicate. + * @throws TagNameAlreadyExistsException If the tag name already exists in + * the case database. * @throws TskCoreException If there is an error adding the tag - * to the case database. + * name to the case database. */ - public TagName addTagName(String displayName, String description) throws TagNameAlreadyExistsException, TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } + public synchronized TagName addTagName(String displayName, String description) throws TagNameAlreadyExistsException, TskCoreException { return addTagName(displayName, description, TagName.HTML_COLOR.NONE); } /** - * Adds a new tag name to the current case and to the tags settings. + * Adds a tag name entry to the case database and adds a corresponding + * tag type to the current user's custom tag types. * - * @param displayName The display name for the new tag name. - * @param description The description for the new tag name. - * @param color The HTML color to associate with the new tag name. + * @param displayName The display name for the new tag type. + * @param description The description for the new tag type. + * @param color The color to associate with the new tag type. * - * @return A TagName data transfer object (DTO) representing the new tag - * name. + * @return A TagName object that can be used to add instances of the tag + * type to the case database. * - * @throws TagNameAlreadyExistsException If the tag name would be a - * duplicate. + * @throws TagNameAlreadyExistsException If the tag name already exists. * @throws TskCoreException If there is an error adding the tag - * to the case database. + * name to the case database. */ public synchronized TagName addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - - lazyLoadExistingTagNames(); - - /* - * It is possible user is trying to add back a tag after having deleted - * it. It is also possible a user tag name was never added to the - * database. - */ - if (uniqueTagNames.containsKey(displayName)) { - if (uniqueTagNames.get(displayName) != null) { - TagName existingTagName = uniqueTagNames.get(displayName); - long count = getContentTagsCountByTagName(existingTagName) + getBlackboardArtifactTagsCountByTagName(existingTagName); - if (count == 0) { - addNewTagNameToTagsSettings(existingTagName); - return existingTagName; - } else { + try { + TagName tagName = caseDb.addTagName(displayName, description, color); + Set customTypes = TagType.getCustomTagTypes(); + customTypes.add(new TagType(displayName, description, color)); + TagType.setCustomTagTypes(customTypes); + return tagName; + } catch (TskCoreException ex) { + List existingTagNames = caseDb.getAllTagNames(); + for (TagName tagName : existingTagNames) { + if (tagName.getDisplayName().equals(displayName)) { throw new TagNameAlreadyExistsException(); } } + throw ex; } - - TagName newTagName = caseDb.addTagName(displayName, description, color); - uniqueTagNames.put(newTagName.getDisplayName(), newTagName); - - addNewTagNameToTagsSettings(newTagName); - - return newTagName; } /** * Tags a content object. * * @param content The content to tag. - * @param tagName The name to use for the tag. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * - * @return A ContentTag data transfer object (DTO) representing the new tag. + * @return A ContentTag object representing the new tag. * * @throws TskCoreException If there is an error adding the tag to the case * database. */ public ContentTag addContentTag(Content content, TagName tagName) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } return addContentTag(content, tagName, "", -1, -1); } @@ -273,18 +206,17 @@ public class TagsManager implements Closeable { * Tags a content object. * * @param content The content to tag. - * @param tagName The name to use for the tag. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * @param comment A comment to store with the tag. * - * @return A ContentTag data transfer object (DTO) representing the new tag. + * @return A ContentTag object representing the new tag. * * @throws TskCoreException If there is an error adding the tag to the case * database. */ public ContentTag addContentTag(Content content, TagName tagName, String comment) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } return addContentTag(content, tagName, comment, -1, -1); } @@ -292,56 +224,25 @@ public class TagsManager implements Closeable { * Tags a content object or a section of a content object. * * @param content The content to tag. - * @param tagName The name to use for the tag. + * @param tagName The representation of the desired tag type in the + * case database, which can be obtained by calling + * getTagNames and/or addTagName. * @param comment A comment to store with the tag. * @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 object representing the new tag. * - * @throws IllegalArgumentException If a requested byte offset is out of - * range. - * @throws TskCoreException If there is an error adding the tag to - * the case database. + * @throws TskCoreException If there is an error adding the tag to the case + * database. */ - public ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws IllegalArgumentException, TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } + public ContentTag addContentTag(Content content, TagName tagName, String comment, long beginByteOffset, long endByteOffset) throws TskCoreException { ContentTag tag; - synchronized (this) { - lazyLoadExistingTagNames(); - - if (null == comment) { - throw new IllegalArgumentException("Passed null comment argument"); - } - - if (beginByteOffset >= 0 && endByteOffset >= 1) { - if (beginByteOffset > content.getSize() - 1) { - throw new IllegalArgumentException(NbBundle.getMessage(this.getClass(), - "TagsManager.addContentTag.exception.beginByteOffsetOOR.msg", - beginByteOffset, content.getSize() - 1)); - } - - if (endByteOffset > content.getSize() - 1) { - throw new IllegalArgumentException( - NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endByteOffsetOOR.msg", - endByteOffset, content.getSize() - 1)); - } - - if (endByteOffset < beginByteOffset) { - throw new IllegalArgumentException( - NbBundle.getMessage(this.getClass(), "TagsManager.addContentTag.exception.endLTbegin.msg")); - } - } - - tag = caseDb.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset); - } - + tag = caseDb.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset); try { Case.getCurrentCase().notifyContentTagAdded(tag); } catch (IllegalStateException ex) { - logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.addContentTag.noCaseWarning"), ex); + LOGGER.log(Level.SEVERE, "Added a tag to a closed case", ex); } return tag; } @@ -355,18 +256,11 @@ public class TagsManager implements Closeable { * case database. */ public void deleteContentTag(ContentTag tag) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - synchronized (this) { - lazyLoadExistingTagNames(); - caseDb.deleteContentTag(tag); - } - + caseDb.deleteContentTag(tag); try { Case.getCurrentCase().notifyContentTagDeleted(tag); } catch (IllegalStateException ex) { - logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteContentTag.noCaseWarning"), ex); + LOGGER.log(Level.SEVERE, "Deleted a tag from a closed case", ex); } } @@ -379,17 +273,15 @@ public class TagsManager implements Closeable { * case database. */ public synchronized List getAllContentTags() throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getAllContentTags(); } /** * Gets content tags count by tag name. * - * @param tagName The tag name of interest. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * * @return A count of the content tags with the specified tag name. * @@ -397,29 +289,21 @@ public class TagsManager implements Closeable { * the case database. */ public synchronized long getContentTagsCountByTagName(TagName tagName) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getContentTagsCountByTagName(tagName); } /** * Gets a content tag by tag id. * - * @param tagID The tag id of interest. + * @param tagId The tag id of interest. * * @return The content tag with the specified tag id. * * @throws TskCoreException If there is an error getting the tag from the * case database. */ - public synchronized ContentTag getContentTagByTagID(long tagID) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); - return caseDb.getContentTagByID(tagID); + public synchronized ContentTag getContentTagByTagID(long tagId) throws TskCoreException { + return caseDb.getContentTagByID(tagId); } /** @@ -434,10 +318,6 @@ public class TagsManager implements Closeable { * case database. */ public synchronized List getContentTagsByTagName(TagName tagName) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getContentTagsByTagName(tagName); } @@ -447,172 +327,136 @@ public class TagsManager implements Closeable { * @param content The content of interest. * * @return A list, possibly empty, of the tags that have been applied to the - * artifact. + * content. * * @throws TskCoreException If there is an error getting the tags from the * case database. */ public synchronized List getContentTagsByContent(Content content) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getContentTagsByContent(content); } /** - * Tags a blackboard artifact object. + * Tags an artifact. * - * @param artifact The blackboard artifact to tag. - * @param tagName The name to use for the tag. + * @param artifact The artifact to tag. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * - * @return A BlackboardArtifactTag data transfer object (DTO) representing - * the new tag. + * @return A BlackboardArtifactTag object representing the new tag. * * @throws TskCoreException If there is an error adding the tag to the case * database. */ - public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } + public synchronized BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName) throws TskCoreException { return addBlackboardArtifactTag(artifact, tagName, ""); } /** - * Tags a blackboard artifact object. + * Tags an artifact. * - * @param artifact The blackboard artifact to tag. - * @param tagName The name to use for the tag. + * @param artifact The artifact to tag. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * @param comment A comment to store with the tag. * - * @return A BlackboardArtifactTag data transfer object (DTO) representing - * the new tag. + * @return A BlackboardArtifactTag object representing the new tag. * * @throws TskCoreException If there is an error adding the tag to the case * database. */ - public BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - BlackboardArtifactTag tag; - synchronized (this) { - lazyLoadExistingTagNames(); - if (null == comment) { - throw new IllegalArgumentException("Passed null comment argument"); - } - tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment); - } - + public synchronized BlackboardArtifactTag addBlackboardArtifactTag(BlackboardArtifact artifact, TagName tagName, String comment) throws TskCoreException { + BlackboardArtifactTag tag = caseDb.addBlackboardArtifactTag(artifact, tagName, comment); try { Case.getCurrentCase().notifyBlackBoardArtifactTagAdded(tag); } catch (IllegalStateException ex) { - logger.log(Level.SEVERE, NbBundle.getMessage(TagsManager.class, "TagsManager.addBlackboardArtifactTag.noCaseWarning"), ex); + LOGGER.log(Level.SEVERE, "Added a tag to a closed case", ex); } return tag; } /** - * Deletes a blackboard artifact tag. + * Deletes an artifact tag. * * @param tag The tag to delete. * * @throws TskCoreException If there is an error deleting the tag from the * case database. */ - public void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - synchronized (this) { - lazyLoadExistingTagNames(); - caseDb.deleteBlackboardArtifactTag(tag); - } - + public synchronized void deleteBlackboardArtifactTag(BlackboardArtifactTag tag) throws TskCoreException { + caseDb.deleteBlackboardArtifactTag(tag); try { Case.getCurrentCase().notifyBlackBoardArtifactTagDeleted(tag); } catch (IllegalStateException ex) { - logger.log(Level.WARNING, NbBundle.getMessage(TagsManager.class, "TagsManager.deleteBlackboardArtifactTag.noCaseWarning"), ex); + LOGGER.log(Level.SEVERE, "Deleted a tag from a closed case", ex); } } /** - * Gets all blackboard artifact tags for the current case. + * Gets all artifact tags for the current case. * - * @return A list, possibly empty, of blackboard artifact tags. + * @return A list, possibly empty, of artifact tags. * * @throws TskCoreException If there is an error getting the tags from the * case database. */ public synchronized List getAllBlackboardArtifactTags() throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getAllBlackboardArtifactTags(); } /** - * Gets blackboard artifact tags count by tag name. + * Gets an artifact tags count by tag name. * - * @param tagName The tag name of interest. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * - * @return A count of the blackboard artifact tags with the specified tag - * name. + * @return A count of the artifact tags with the specified tag name. * * @throws TskCoreException If there is an error getting the tags count from * the case database. */ public synchronized long getBlackboardArtifactTagsCountByTagName(TagName tagName) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsCountByTagName(tagName); } /** - * Gets a blackboard artifact tag by tag id. + * Gets an artifact tag by tag id. * - * @param tagID The tag id of interest. + * @param tagId The tag id of interest. * - * @return the blackboard artifact tag with the specified tag id. + * @return The artifact tag with the specified tag id. * * @throws TskCoreException If there is an error getting the tag from the * case database. */ - public synchronized BlackboardArtifactTag getBlackboardArtifactTagByTagID(long tagID) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); - return caseDb.getBlackboardArtifactTagByID(tagID); + public synchronized BlackboardArtifactTag getBlackboardArtifactTagByTagID(long tagId) throws TskCoreException { + return caseDb.getBlackboardArtifactTagByID(tagId); } /** - * Gets blackboard artifact tags by tag name. + * Gets artifact tags by tag name. * - * @param tagName The tag name of interest. + * @param tagName The representation of the desired tag type in the case + * database, which can be obtained by calling getTagNames + * and/or addTagName. * - * @return A list, possibly empty, of the blackboard artifact tags with the - * specified tag name. + * @return A list, possibly empty, of the artifact tags with the specified + * tag name. * * @throws TskCoreException If there is an error getting the tags from the * case database. */ public synchronized List getBlackboardArtifactTagsByTagName(TagName tagName) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsByTagName(tagName); } /** - * Gets blackboard artifact tags for a particular blackboard artifact. + * Gets artifact tags for a particular artifact. * - * @param artifact The blackboard artifact of interest. + * @param artifact The artifact of interest. * * @return A list, possibly empty, of the tags that have been applied to the * artifact. @@ -621,129 +465,15 @@ public class TagsManager implements Closeable { * case database. */ public synchronized List getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact) throws TskCoreException { - if (null == caseDb) { - throw new TskCoreException("Tags manager has been closed"); - } - lazyLoadExistingTagNames(); return caseDb.getBlackboardArtifactTagsByArtifact(artifact); } - /** - * Closes the tags manager, saving the available tag names to secondary - * storage. - * - * @throws IOException If there is a problem closing the tags manager. - * @deprecated Tags manager clients should not close the tags manager. - */ - @Override - @Deprecated - public synchronized void close() throws IOException { - caseDb = null; - } - - /** - * Populates the tag names collection and the tag names table in the case - * database with the existing tag names from all sources. - */ - private void lazyLoadExistingTagNames() { - if (!tagNamesLoaded) { - addTagNamesFromCurrentCase(); - addPredefinedTagNames(); - addTagNamesFromTagsSettings(); - tagNamesLoaded = true; - } else { - // Reload case db tag names in case another user has added some. - addTagNamesFromCurrentCase(); - } - } - - /** - * Adds any tag names that are in the case database to the tag names - * collection. - */ - private void addTagNamesFromCurrentCase() { - try { - List currentTagNames = caseDb.getAllTagNames(); - for (TagName tagName : currentTagNames) { - uniqueTagNames.put(tagName.getDisplayName(), tagName); - } - } catch (TskCoreException ex) { - Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to get tag types from the current case", ex); //NON-NLS - } - } - - /** - * Adds any tag names that are in the properties file to the tag names - * collection and to the case database. The properties file is used to make - * it possible to use tag names across cases. - */ - private void addTagNamesFromTagsSettings() { - String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); - if (null != setting && !setting.isEmpty()) { - // Read the tag name setting and break it into tag name tuples. - List tagNameTuples = Arrays.asList(setting.split(";")); - - // Parse each tuple and add the tag names to the current case, one - // at a time to gracefully discard any duplicates or corrupt tuples. - for (String tagNameTuple : tagNameTuples) { - String[] tagNameAttributes = tagNameTuple.split(","); - if (!uniqueTagNames.containsKey(tagNameAttributes[0])) { - uniqueTagNames.put(tagNameAttributes[0], null); - } - } - } - } - - /** - * Adds the standard tag names to the tag names collection. - */ - private void addPredefinedTagNames() { - if (!uniqueTagNames.containsKey(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"))) { - try { - TagName tagName = caseDb.addTagName( - NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), "", TagName.HTML_COLOR.NONE); - uniqueTagNames.put(tagName.getDisplayName(), tagName); - } catch (TskCoreException ex) { - Logger.getLogger(TagsManager.class.getName()).log(Level.SEVERE, "Failed to add standard 'Bookmark' tag name to case database", ex); //NON-NLS - } - } - } - - /** - * Adds any user defined tag name to the case db and also to uniqueTagNames, - * to allow user tag names to be displayed while tagging. - * - * @param userTagNames a List of UserTagName objects to be potentially added - */ - void storeNewUserTagNames(List userTagNames) { - lazyLoadExistingTagNames(); - for (UserTagName utn : userTagNames) { - if (!uniqueTagNames.containsKey(utn.getDisplayName())) { - uniqueTagNames.put(utn.getDisplayName(), null); - } - } - } - - /** - * Adds a new tag name to the settings file, used when user creates a new - * tag name. - */ - private void addNewTagNameToTagsSettings(TagName tagName) { - String setting = ModuleSettings.getConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY); - if (setting == null || setting.isEmpty()) { - setting = ""; - } else { - setting += ";"; - } - setting += tagName.getDisplayName() + "," + tagName.getDescription() + "," + tagName.getColor().toString(); - ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting); - } - /** * Returns true if the tag display name contains an illegal character. Used * after a tag display name is retrieved from user input. * * @param content Display name of the tag being added. + * * @return boolean indicating whether the name has an invalid character. */ public static boolean containsIllegalCharacters(String content) { @@ -757,6 +487,7 @@ public class TagsManager implements Closeable { || content.contains("|") || content.contains(",") || content.contains(";")); + } /** @@ -767,4 +498,36 @@ public class TagsManager implements Closeable { private static final long serialVersionUID = 1L; } + /** + * Checks whether a tag name with a given display name exists in the case + * database. + * + * @param tagDisplayName The display name. + * + * @return True or false. + * + * @deprecated Not reliable for multi-user cases. + */ + @Deprecated + public synchronized boolean tagNameExists(String tagDisplayName) { + try { + Map tagNames = getDisplayNamesToTagNamesMap(); + return tagNames.containsKey(tagDisplayName) && (tagNames.get(tagDisplayName) != null); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Error querying case database for tag names", ex); + return false; + } + } + + /** + * Closes the tags manager. + * + * @throws IOException If there is a problem closing the tags manager. + * @deprecated Tags manager clients should not close the tags manager. + */ + @Override + @Deprecated + public synchronized void close() throws IOException { + } + } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java deleted file mode 100755 index c761665c08..0000000000 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/UserTagName.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -* Autopsy Forensic Browser -* -* Copyright 2011-2016 Basis Technology Corp. -* Contact: carrier sleuthkit 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.casemodule.services; - -import java.util.Objects; - -/** - * Because the DTO TagName constructor can not be called outside of its class - * package, UserTagName is used to keep track of user tag names while - * preserving properties that will potentially be implemented in the future - * (tag name description and tag name color). - */ -class UserTagName implements Comparable { - - private final String displayName; - private final String description; - private final String colorName; - - UserTagName(String displayName, String description, String colorName) { - this.displayName = displayName; - this.description = description; - this.colorName = colorName; - } - - String getDisplayName() { - return displayName; - } - - String getDescription() { - return description; - } - - String getColorName() { - return colorName; - } - - @Override - public int compareTo(UserTagName other) { - return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 83 * hash + Objects.hashCode(this.displayName); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof UserTagName)) { - return false; - } - UserTagName thatTagName = (UserTagName) obj; - return this.getDisplayName().equals(thatTagName.getDisplayName()); - } - - @Override - public String toString() { - return displayName; - } - - /** - * @return A string representation of the tag name in the format that is - * used by the properties file. - */ - public String toSettingsFormat() { - return displayName + "," + description + "," + colorName; - } -}