From df3886317891665b5b568be2f7db01ba400d4c17 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Mon, 26 Sep 2016 10:15:49 -0400 Subject: [PATCH 1/4] Changed datetime value type attributes to be formatted as dates instead of longs --- .../datamodel/ArtifactStringContent.java | 75 ++++++++----------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java index fa59de87c1..53523be839 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java @@ -27,7 +27,6 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskException; @@ -68,7 +67,7 @@ public class ArtifactStringContent implements StringContent { buffer.append(""); //NON-NLS buffer.append("\n"); //NON-NLS - // cycle through each attribute and display in a row in the table. + // cycle through each attribute and display in a row in the table. for (BlackboardAttribute attr : artifact.getAttributes()) { // name column @@ -78,48 +77,36 @@ public class ArtifactStringContent implements StringContent { // value column buffer.append(""); //NON-NLS - if (attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_START.getTypeID() - || attr.getAttributeType().getTypeID() == ATTRIBUTE_TYPE.TSK_DATETIME_END.getTypeID()) { - long epoch = attr.getValueLong(); - String time = "0000-00-00 00:00:00"; - if (epoch != 0) { - dateFormatter.setTimeZone(getTimeZone(artifact)); - time = dateFormatter.format(new java.util.Date(epoch * 1000)); - } - buffer.append(time); - } else { - switch (attr.getAttributeType().getValueType()) { - case STRING: - String str = attr.getValueString(); - str = str.replaceAll(" ", " "); //NON-NLS - str = str.replaceAll("<", "<"); //NON-NLS - str = str.replaceAll(">", ">"); //NON-NLS - str = str.replaceAll("(\r\n|\n)", "
"); //NON-NLS - buffer.append(str); - break; - case INTEGER: - buffer.append(attr.getValueInt()); - break; - case LONG: - buffer.append(attr.getValueLong()); - break; - case DOUBLE: - buffer.append(attr.getValueDouble()); - break; - case BYTE: - buffer.append(Arrays.toString(attr.getValueBytes())); - break; - case DATETIME: - buffer.append(attr.getValueLong()); - break; - - } + switch (attr.getAttributeType().getValueType()) { + case STRING: + String str = attr.getValueString(); + str = str.replaceAll(" ", " "); //NON-NLS + str = str.replaceAll("<", "<"); //NON-NLS + str = str.replaceAll(">", ">"); //NON-NLS + str = str.replaceAll("(\r\n|\n)", "
"); //NON-NLS + buffer.append(str); + break; + case INTEGER: + buffer.append(attr.getValueInt()); + break; + case LONG: + buffer.append(attr.getValueLong()); + break; + case DOUBLE: + buffer.append(attr.getValueDouble()); + break; + case BYTE: + buffer.append(Arrays.toString(attr.getValueBytes())); + break; + case DATETIME: + long epoch = attr.getValueLong(); + String time = "0000-00-00 00:00:00"; + if (epoch != 0) { + dateFormatter.setTimeZone(getTimeZone(artifact)); + time = dateFormatter.format(new java.util.Date(epoch * 1000)); + } + buffer.append(time); + break; } if (!"".equals(attr.getContext())) { buffer.append(" ("); From 6e60f9a9788c5a1c2c0a2362a53196c54d3ddccd Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Sun, 2 Oct 2016 23:31:56 -0400 Subject: [PATCH 2/4] 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; - } -} From 4115dab3334d4153a83d9723d791f4321cf94ed5 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 3 Oct 2016 00:23:47 -0400 Subject: [PATCH 3/4] Changes to tags management (partial) --- .../autopsy/actions/AddTagAction.java | 1 + .../actions/GetTagNameAndCommentDialog.java | 14 +- .../autopsy/actions/GetTagNameDialog.java | 27 ++- .../casemodule/services/Bundle.properties | 8 +- ...ettingsPanel.form => TagOptionsPanel.form} | 42 ++--- ...ettingsPanel.java => TagOptionsPanel.java} | 171 ++++++++---------- ...r.java => TagsOptionsPanelController.java} | 17 +- 7 files changed, 135 insertions(+), 145 deletions(-) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagNamesSettingsPanel.form => TagOptionsPanel.form} (85%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagNamesSettingsPanel.java => TagOptionsPanel.java} (55%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagNamesOptionsPanelController.java => TagsOptionsPanelController.java} (85%) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 5a9d371b50..26288a54a2 100755 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -39,6 +39,7 @@ import org.sleuthkit.datamodel.TskCoreException; */ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { + private static final long serialVersionUID = 1L; private static final String NO_COMMENT = ""; AddTagAction(String menuText) { diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java index 5a30a49c72..73290602e9 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameAndCommentDialog.java @@ -91,13 +91,18 @@ public class GetTagNameAndCommentDialog extends JDialog { * dialog. */ public static TagNameAndComment doDialog(Window owner) { - return new GetTagNameAndCommentDialog(owner).tagNameAndComment; + GetTagNameAndCommentDialog dialog = new GetTagNameAndCommentDialog(owner); + dialog.display(); + return dialog.tagNameAndComment; } private GetTagNameAndCommentDialog(Window owner) { super(owner, NbBundle.getMessage(GetTagNameAndCommentDialog.class, "GetTagNameAndCommentDialog.createTag"), ModalityType.APPLICATION_MODAL); + } + + private void display() { initComponents(); // Set up the dialog to close when Esc is pressed. @@ -106,6 +111,7 @@ public class GetTagNameAndCommentDialog extends JDialog { inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName); ActionMap actionMap = getRootPane().getActionMap(); actionMap.put(cancelName, new AbstractAction() { + private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { dispose(); @@ -131,10 +137,10 @@ public class GetTagNameAndCommentDialog extends JDialog { } // Center and show the dialog box. - this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - setVisible(true); + this.setLocationRelativeTo(this.getOwner()); + setVisible(true); } - + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always diff --git a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java index 268512898e..3d1057a041 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/actions/GetTagNameDialog.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013 Basis Technology Corp. + * Copyright 2011-2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -45,6 +45,7 @@ import org.sleuthkit.datamodel.TskCoreException; public class GetTagNameDialog extends JDialog { + private static final long serialVersionUID = 1L; private static final String TAG_ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS private final Map tagNamesMap = new TreeMap<>(); private TagName tagName = null; @@ -71,14 +72,19 @@ public class GetTagNameDialog extends JDialog { * @return a TagName instance selected by the user, or null if the user * canceled the dialog. */ - public static TagName doDialog(final Window owner) { - return new GetTagNameDialog(owner).tagName; + public static TagName doDialog(Window owner) { + GetTagNameDialog dialog = new GetTagNameDialog(owner); + dialog.display(); + return dialog.tagName; } - private GetTagNameDialog(final Window owner) { - super(owner, + private GetTagNameDialog(Window owner) { + super(owner, NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.createTag"), ModalityType.APPLICATION_MODAL); + } + + private void display() { setIconImage(ImageUtilities.loadImage(TAG_ICON_PATH)); initComponents(); @@ -88,6 +94,8 @@ public class GetTagNameDialog extends JDialog { inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName); ActionMap actionMap = getRootPane().getActionMap(); actionMap.put(cancelName, new AbstractAction() { + private static final long serialVersionUID = 1L; + @Override public void actionPerformed(ActionEvent e) { cancelButtonActionPerformed(e); @@ -104,19 +112,20 @@ public class GetTagNameDialog extends JDialog { } // Populate the tag names table. - tagsTable.setModel(new TagsTableModel(new ArrayList(tagNamesMap.keySet()))); + tagsTable.setModel(new TagsTableModel(new ArrayList<>(tagNamesMap.keySet()))); tagsTable.setTableHeader(null); tagsTable.setCellSelectionEnabled(false); tagsTable.setFocusable(false); tagsTable.setRowHeight(tagsTable.getRowHeight() + 5); // Center and show the dialog box. - this.setLocationRelativeTo(owner); - setVisible(true); + this.setLocationRelativeTo(this.getOwner()); + setVisible(true); } - + private class TagsTableModel extends AbstractTableModel { + private static final long serialVersionUID = 1L; private final ArrayList tagDisplayNames = new ArrayList<>(); TagsTableModel(List tagDisplayNames) { diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index ed80e8696e..3550c648f6 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -9,8 +9,6 @@ TagsManager.deleteContentTag.noCaseWarning=Failed to publish content tag deleted TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackboard artifact tag event. There is no case open. TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open. Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0} -TagNamesSettingsPanel.deleteTagNameButton.text=Delete Tag Name -TagNamesSettingsPanel.tagNamesListLabel.text=Tag names: NewUserTagNameDialog.tagNameTextField.text= NewUserTagNameDialog.newTagNameLabel.text=New Tag Name: NewUserTagNameDialog.okButton.text=OK @@ -22,5 +20,7 @@ TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message=The tag name alre TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title=Tag name already exists NewUserTagNameDialog.JOptionPane.tagNameEmpty.message=The tag name cannot be empty NewUserTagNameDialog.JOptionPane.tagNameEmpty.title=Empty tag name -TagNamesSettingsPanel.panelDescriptionLabel.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. -TagNamesSettingsPanel.newTagNameButton.text=New Tag Name +TagOptionsPanel.newTagTypeButton.text=New Tag Type +TagOptionsPanel.tagTypesListLabel.text=Tag Types: +TagOptionsPanel.panelDescriptionLabel.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. +TagOptionsPanel.deleteTagTypeButton.text=Delete Tag Type diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form similarity index 85% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form index 5b896fdd36..4b3a77eb92 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form @@ -65,7 +65,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -90,12 +90,12 @@ - + - + - - + + @@ -107,13 +107,13 @@ - + - - + + @@ -121,10 +121,10 @@ - + - + @@ -138,47 +138,45 @@ - - - + - + - + - + - + - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java similarity index 55% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java index 1a74acc4ae..d1fcfdd992 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java @@ -18,37 +18,31 @@ */ package org.sleuthkit.autopsy.casemodule.services; -import java.util.Collections; -import java.util.HashSet; 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.corecomponents.OptionsPanel; -import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.TagName; /** - * A panel to allow the user to create new tag names or to delete tag names that - * user has created in the past. List of user tag names is maintained in a - * properties file, able to be used across cases. Potentially room to add other - * tag name options in the future. + * A panel to allow the user to create and delete custom tag types. */ -final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsPanel { +final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { private static final long serialVersionUID = 1L; private static final String DEFAULT_DESCRIPTION = ""; - private static final String DEFAULT_COLOR_STRING = "NONE"; + private static final TagName.HTML_COLOR DEFAULT_COLOR = TagName.HTML_COLOR.NONE; private final DefaultListModel tagTypesListModel; - private final Set tagTypes; + private Set tagTypes; /** * Creates new form TagsManagerOptionsPanel */ - TagNamesSettingsPanel() { + TagOptionsPanel() { tagTypesListModel = new DefaultListModel<>(); tagTypes = new TreeSet<>(TagType.getCustomTagTypes()); initComponents(); @@ -74,91 +68,86 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP jPanel1 = new javax.swing.JPanel(); panelDescriptionLabel = new javax.swing.JLabel(); jSplitPane1 = new javax.swing.JSplitPane(); - modifyTagNameListPanel = new javax.swing.JPanel(); - tagNamesListLabel = new javax.swing.JLabel(); + modifyTagTypesListPanel = new javax.swing.JPanel(); + tagTypesListLabel = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); tagNamesList = new javax.swing.JList<>(); - newTagNameButton = new javax.swing.JButton(); - deleteTagNameButton = new javax.swing.JButton(); - tagNameAdditionalPanel = new javax.swing.JPanel(); + newTagTypeButton = new javax.swing.JButton(); + deleteTagTypeButton = new javax.swing.JButton(); + tagTypesAdditionalPanel = new javax.swing.JPanel(); jPanel1.setPreferredSize(new java.awt.Dimension(750, 500)); - org.openide.awt.Mnemonics.setLocalizedText(panelDescriptionLabel, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.panelDescriptionLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(panelDescriptionLabel, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.panelDescriptionLabel.text")); // NOI18N jSplitPane1.setDividerLocation(400); jSplitPane1.setDividerSize(1); - org.openide.awt.Mnemonics.setLocalizedText(tagNamesListLabel, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.tagNamesListLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(tagTypesListLabel, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.tagTypesListLabel.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 - org.openide.awt.Mnemonics.setLocalizedText(newTagNameButton, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.newTagNameButton.text")); // NOI18N - newTagNameButton.addActionListener(new java.awt.event.ActionListener() { + newTagTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(newTagTypeButton, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.newTagTypeButton.text")); // NOI18N + newTagTypeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - newTagNameButtonActionPerformed(evt); + newTagTypeButtonActionPerformed(evt); } }); - deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagNamesSettingsPanel.class, "TagNamesSettingsPanel.deleteTagNameButton.text")); // NOI18N - deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { + deleteTagTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteTagTypeButton, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.deleteTagTypeButton.text")); // NOI18N + deleteTagTypeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - deleteTagNameButtonActionPerformed(evt); + deleteTagTypeButtonActionPerformed(evt); } }); - javax.swing.GroupLayout modifyTagNameListPanelLayout = new javax.swing.GroupLayout(modifyTagNameListPanel); - modifyTagNameListPanel.setLayout(modifyTagNameListPanelLayout); - modifyTagNameListPanelLayout.setHorizontalGroup( - modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() + javax.swing.GroupLayout modifyTagTypesListPanelLayout = new javax.swing.GroupLayout(modifyTagTypesListPanel); + modifyTagTypesListPanel.setLayout(modifyTagTypesListPanelLayout); + modifyTagTypesListPanelLayout.setHorizontalGroup( + modifyTagTypesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(modifyTagTypesListPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tagNamesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() - .addComponent(newTagNameButton) + .addGroup(modifyTagTypesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tagTypesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(modifyTagTypesListPanelLayout.createSequentialGroup() + .addComponent(newTagTypeButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(deleteTagNameButton) - .addGap(0, 113, Short.MAX_VALUE)) + .addComponent(deleteTagTypeButton) + .addGap(0, 121, Short.MAX_VALUE)) .addComponent(jScrollPane1)) .addContainerGap()) ); - modifyTagNameListPanelLayout.setVerticalGroup( - modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(modifyTagNameListPanelLayout.createSequentialGroup() + modifyTagTypesListPanelLayout.setVerticalGroup( + modifyTagTypesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(modifyTagTypesListPanelLayout.createSequentialGroup() .addContainerGap() - .addComponent(tagNamesListLabel) + .addComponent(tagTypesListLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(modifyTagNameListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(newTagNameButton) - .addComponent(deleteTagNameButton)) + .addGroup(modifyTagTypesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(newTagTypeButton) + .addComponent(deleteTagTypeButton)) .addContainerGap()) ); - jSplitPane1.setLeftComponent(modifyTagNameListPanel); + jSplitPane1.setLeftComponent(modifyTagTypesListPanel); - javax.swing.GroupLayout tagNameAdditionalPanelLayout = new javax.swing.GroupLayout(tagNameAdditionalPanel); - tagNameAdditionalPanel.setLayout(tagNameAdditionalPanelLayout); - tagNameAdditionalPanelLayout.setHorizontalGroup( - tagNameAdditionalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + javax.swing.GroupLayout tagTypesAdditionalPanelLayout = new javax.swing.GroupLayout(tagTypesAdditionalPanel); + tagTypesAdditionalPanel.setLayout(tagTypesAdditionalPanelLayout); + tagTypesAdditionalPanelLayout.setHorizontalGroup( + tagTypesAdditionalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 356, Short.MAX_VALUE) ); - tagNameAdditionalPanelLayout.setVerticalGroup( - tagNameAdditionalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + tagTypesAdditionalPanelLayout.setVerticalGroup( + tagTypesAdditionalPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 456, Short.MAX_VALUE) ); - jSplitPane1.setRightComponent(tagNameAdditionalPanel); + jSplitPane1.setRightComponent(tagTypesAdditionalPanel); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); @@ -195,53 +184,49 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP ); }// //GEN-END:initComponents - private void newTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagNameButtonActionPerformed + private void newTagTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagTypeButtonActionPerformed NewUserTagNameDialog dialog = new NewUserTagNameDialog(); NewUserTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); if (result == NewUserTagNameDialog.BUTTON_PRESSED.OK) { String newTagDisplayName = dialog.getTagName(); - TagType newTagType = new TagType(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR_STRING); + TagType newTagType = new TagType(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR); /* * If tag name already exists, don't add the tag name. */ - 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 { + if (!tagTypes.contains(newTagType)) { tagTypes.add(newTagType); updateTagNamesListModel(); - /* - * Set the selection to the tag name that was just added. - */ - int index = tagTypes.indexOf(newTagType); - tagNamesList.setSelectedIndex(index); + tagNamesList.setSelectedValue(newTagType, true); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } else { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(TagOptionsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message"), + NbBundle.getMessage(TagOptionsPanel.class, "TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title"), + JOptionPane.INFORMATION_MESSAGE); } } - }//GEN-LAST:event_newTagNameButtonActionPerformed + }//GEN-LAST:event_newTagTypeButtonActionPerformed - private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed + private void deleteTagTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagTypeButtonActionPerformed TagType tagName = tagNamesList.getSelectedValue(); tagTypes.remove(tagName); updateTagNamesListModel(); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_deleteTagNameButtonActionPerformed + }//GEN-LAST:event_deleteTagTypeButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton deleteTagNameButton; + private javax.swing.JButton deleteTagTypeButton; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSplitPane jSplitPane1; - private javax.swing.JPanel modifyTagNameListPanel; - private javax.swing.JButton newTagNameButton; + private javax.swing.JPanel modifyTagTypesListPanel; + private javax.swing.JButton newTagTypeButton; private javax.swing.JLabel panelDescriptionLabel; - private javax.swing.JPanel tagNameAdditionalPanel; - private javax.swing.JList tagNamesList; - private javax.swing.JLabel tagNamesListLabel; + private javax.swing.JList tagNamesList; + private javax.swing.JPanel tagTypesAdditionalPanel; + private javax.swing.JLabel tagTypesListLabel; // End of variables declaration//GEN-END:variables /** @@ -249,33 +234,23 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP */ private void updateTagNamesListModel() { 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. + * Loads the stored custom tag types. */ @Override public void load() { - tagTypes = TagType.getCustomTagTypes(); + tagTypes = new TreeSet<>(TagType.getCustomTagTypes()); updateTagNamesListModel(); enableButtons(); } /** - * Stores tag name changes in the properties file, called when OK or Apply - * is selected in the options panel. - * - * Adds all new tag names to the case database for displaying usable tag - * names when tagging. + * Stores the custom tag types. */ @Override public void store() { @@ -283,11 +258,15 @@ final class TagNamesSettingsPanel extends javax.swing.JPanel implements OptionsP } /** - * Only enable the delete button when there is a tag type selected in the - * tag types JList. + * Enables the button components based on the state of the tag types list + * component. */ private void enableButtons() { - deleteTagNameButton.setEnabled(tagNamesList.getSelectedIndex() != -1); + /* + * Only enable the delete button when there is a tag type selected in + * the tag types JList. + */ + deleteTagTypeButton.setEnabled(tagNamesList.getSelectedIndex() != -1); } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java index 20c478d966..48947d51f1 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNamesOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java @@ -33,9 +33,9 @@ import org.openide.util.Lookup; keywordsCategory = "CustomTagNames", position = 8 ) -public final class TagNamesOptionsPanelController extends OptionsPanelController { +public final class TagsOptionsPanelController extends OptionsPanelController { - private TagNamesSettingsPanel panel; + private TagOptionsPanel panel; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private boolean changed; @@ -106,15 +106,12 @@ public final class TagNamesOptionsPanelController extends OptionsPanelController pcs.removePropertyChangeListener(l); } - private TagNamesSettingsPanel getPanel() { + private TagOptionsPanel getPanel() { if (panel == null) { - panel = new TagNamesSettingsPanel(); - panel.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) { - changed(); - } + panel = new TagOptionsPanel(); + panel.addPropertyChangeListener((PropertyChangeEvent evt) -> { + if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) { + changed(); } }); } From 1464fc973dca756e96118eb43af363c78cc5d17b Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 3 Oct 2016 18:12:08 -0400 Subject: [PATCH 4/4] Improve/fix tags option panel implementation --- .../casemodule/services/Bundle.properties | 22 ++---- .../casemodule/services/Bundle_ja.properties | 7 -- ...gNameDialog.form => NewTagNameDialog.form} | 8 +- ...gNameDialog.java => NewTagNameDialog.java} | 25 ++++--- .../{TagType.java => TagNameDefiniton.java} | 69 +++++++++--------- .../casemodule/services/TagOptionsPanel.form | 24 +++--- .../casemodule/services/TagOptionsPanel.java | 68 ++++++++--------- .../casemodule/services/TagsManager.java | 31 +++++--- .../services/TagsOptionsPanelController.java | 2 +- ...manager.png => tag-options-panel-icon.png} | Bin 10 files changed, 126 insertions(+), 130 deletions(-) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{NewUserTagNameDialog.form => NewTagNameDialog.form} (90%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{NewUserTagNameDialog.java => NewTagNameDialog.java} (87%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{TagType.java => TagNameDefiniton.java} (63%) rename Core/src/org/sleuthkit/autopsy/casemodule/services/{tags-manager.png => tag-options-panel-icon.png} (100%) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties index 3550c648f6..229d26af58 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle.properties @@ -1,18 +1,6 @@ OptionsCategory_Name_TagNamesOptions=Tags OptionsCategory_TagNames=TagNames -TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} out of content size range (0 - {1}) -TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} out of content size range (0 - {1}) -TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset -TagsManager.predefTagNames.bookmark.text=Bookmark -TagsManager.addContentTag.noCaseWarning=Failed to publish new content tag event. There is no case open. -TagsManager.deleteContentTag.noCaseWarning=Failed to publish content tag deleted event. There is no case open. -TagsManager.addBlackboardArtifactTag.noCaseWarning=Failed to publish new blackboard artifact tag event. There is no case open. -TagsManager.deleteBlackboardArtifactTag.noCaseWarning=Failed to publish blackboard artifact tag deleted event. There is no case open. Blackboard.unableToIndexArtifact.error.msg=Unable to index blackboard artifact {0} -NewUserTagNameDialog.tagNameTextField.text= -NewUserTagNameDialog.newTagNameLabel.text=New Tag Name: -NewUserTagNameDialog.okButton.text=OK -NewUserTagNameDialog.cancelButton.text=Cancel NewUserTagNameDialog.title.text=New Tag Name NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message=Tag name may not contain any of the following symbols\: \\ \: * ? " < > | , ; NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title=Invalid character in tag name @@ -20,7 +8,11 @@ TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.message=The tag name alre TagNamesSettingsPanel.JOptionPane.tagNameAlreadyExists.title=Tag name already exists NewUserTagNameDialog.JOptionPane.tagNameEmpty.message=The tag name cannot be empty NewUserTagNameDialog.JOptionPane.tagNameEmpty.title=Empty tag name -TagOptionsPanel.newTagTypeButton.text=New Tag Type -TagOptionsPanel.tagTypesListLabel.text=Tag Types: +TagOptionsPanel.tagTypesListLabel.text=Tag Names: TagOptionsPanel.panelDescriptionLabel.text=Autopsy keeps a list of the tag names you have created in the past. Add more or delete them here. -TagOptionsPanel.deleteTagTypeButton.text=Delete Tag Type +NewTagNameDialog.okButton.text=OK +NewTagNameDialog.cancelButton.text=Cancel +NewTagNameDialog.tagNameTextField.text= +NewTagNameDialog.newTagNameLabel.text=New Tag Name: +TagOptionsPanel.deleteTagNameButton.text=Delete Tag Name +TagOptionsPanel.newTagNameButton.text=New Tag Name diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle_ja.properties index ca8ed3431a..a27e3ca586 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/Bundle_ja.properties @@ -1,9 +1,2 @@ -TagsManager.addContentTag.exception.beginByteOffsetOOR.msg=beginByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059 -TagsManager.addContentTag.exception.endByteOffsetOOR.msg=endByteOffset \= {0} \u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30ba\u7bc4\u56f2(0 - {1})\u306e\u5916\u3067\u3059 -TagsManager.addContentTag.exception.endLTbegin.msg=endByteOffset < beginByteOffset TagsManager.predefTagNames.bookmark.text=\u30d6\u30c3\u30af\u30de\u30fc\u30af -TagsManager.addContentTag.noCaseWarning=\u65b0\u3057\u3044\u30bf\u30b0\u30a4\u30d9\u30f3\u30c8\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002 -TagsManager.deleteContentTag.noCaseWarning=\u524a\u9664\u3055\u308c\u305f\u30a4\u30d9\u30f3\u30c8\u306e\u30bf\u30b0\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002 -TagsManager.addBlackboardArtifactTag.noCaseWarning=\u30a4\u30d9\u30f3\u30c8\u306e\u30bf\u30b0\u306e\u65b0\u3057\u3044blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002 -TagsManager.deleteBlackboardArtifactTag.noCaseWarning=\u524a\u9664\u3055\u308c\u305f\u30a4\u30d9\u30f3\u30c8\u306e\u30bf\u30b0\u306e\u65b0\u3057\u3044blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u958b\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002 Blackboard.unableToIndexArtifact.error.msg=blackboard\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8{0}\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewTagNameDialog.form similarity index 90% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form rename to Core/src/org/sleuthkit/autopsy/casemodule/services/NewTagNameDialog.form index 26ab153c27..b6400b7c31 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewTagNameDialog.form @@ -63,21 +63,21 @@ - + - + - + @@ -87,7 +87,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewTagNameDialog.java similarity index 87% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java rename to Core/src/org/sleuthkit/autopsy/casemodule/services/NewTagNameDialog.java index bd04678ba9..fbb7594c44 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/NewUserTagNameDialog.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/NewTagNameDialog.java @@ -29,8 +29,9 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.openide.util.NbBundle; -class NewUserTagNameDialog extends javax.swing.JDialog { +final class NewTagNameDialog extends javax.swing.JDialog { + private static final long serialVersionUID = 1L; private String userTagDisplayName; private BUTTON_PRESSED result; @@ -41,9 +42,9 @@ class NewUserTagNameDialog extends javax.swing.JDialog { /** * Creates a new NewUserTagNameDialog dialog. */ - NewUserTagNameDialog() { - super(new JFrame(NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text")), - NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.title.text"), true); + NewTagNameDialog() { + super(new JFrame(NbBundle.getMessage(NewTagNameDialog.class, "NewUserTagNameDialog.title.text")), + NbBundle.getMessage(NewTagNameDialog.class, "NewUserTagNameDialog.title.text"), true); initComponents(); this.display(); } @@ -111,15 +112,15 @@ class NewUserTagNameDialog extends javax.swing.JDialog { String newTagDisplayName = tagNameTextField.getText().trim(); if (newTagDisplayName.isEmpty()) { JOptionPane.showMessageDialog(null, - NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameEmpty.message"), - NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameEmpty.title"), + NbBundle.getMessage(NewTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameEmpty.message"), + NbBundle.getMessage(NewTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameEmpty.title"), JOptionPane.ERROR_MESSAGE); return; } if (TagsManager.containsIllegalCharacters(newTagDisplayName)) { JOptionPane.showMessageDialog(null, - NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message"), - NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title"), + NbBundle.getMessage(NewTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.message"), + NbBundle.getMessage(NewTagNameDialog.class, "NewUserTagNameDialog.JOptionPane.tagNameIllegalCharacters.title"), JOptionPane.ERROR_MESSAGE); return; } @@ -175,18 +176,18 @@ class NewUserTagNameDialog extends javax.swing.JDialog { setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - org.openide.awt.Mnemonics.setLocalizedText(newTagNameLabel, org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.newTagNameLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(newTagNameLabel, org.openide.util.NbBundle.getMessage(NewTagNameDialog.class, "NewTagNameDialog.newTagNameLabel.text")); // NOI18N - tagNameTextField.setText(org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.tagNameTextField.text")); // NOI18N + tagNameTextField.setText(org.openide.util.NbBundle.getMessage(NewTagNameDialog.class, "NewTagNameDialog.tagNameTextField.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.cancelButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(NewTagNameDialog.class, "NewTagNameDialog.cancelButton.text")); // NOI18N cancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cancelButtonActionPerformed(evt); } }); - org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(NewUserTagNameDialog.class, "NewUserTagNameDialog.okButton.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(NewTagNameDialog.class, "NewTagNameDialog.okButton.text")); // NOI18N okButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { okButtonActionPerformed(evt); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefiniton.java similarity index 63% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java rename to Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefiniton.java index 71415cb615..101d68fa4c 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagType.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagNameDefiniton.java @@ -28,10 +28,10 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.datamodel.TagName; /** - * A tag type definition consisting of a display name, description and color. + * A tag name definition consisting of a display name, description and color. */ @Immutable -final class TagType implements Comparable { +final class TagNameDefiniton implements Comparable { private static final String TAGS_SETTINGS_NAME = "Tags"; //NON-NLS private static final String TAG_NAMES_SETTING_KEY = "TagNames"; //NON-NLS @@ -40,21 +40,21 @@ final class TagType implements Comparable { private final TagName.HTML_COLOR color; /** - * Constructs a tag type definition consisting of a display name, + * Constructs a tag name 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. + * @param displayName The display name for the tag name. + * @param description The description for the tag name. + * @param color The color for the tag name. */ - TagType(String displayName, String description, TagName.HTML_COLOR color) { + TagNameDefiniton(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. + * Gets the display name for the tag name. * * @return The display name. */ @@ -63,7 +63,7 @@ final class TagType implements Comparable { } /** - * Gets the description of a tag type. + * Gets the description for the tag name. * * @return The description. */ @@ -72,7 +72,7 @@ final class TagType implements Comparable { } /** - * Gets the color associated with the tag type. + * Gets the color for the tag name. * * @return The color. */ @@ -81,21 +81,23 @@ final class TagType implements Comparable { } /** - * Compares this tag type with the specified tag type for order. + * Compares this tag name definition with the specified tag name definition + * for order. * - * @param other The tag type to which to compare this tag type. + * @param other The tag name definition to which to compare this tag name + * definition. * * @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. + * this tag name definition is less than, equal to, or greater than + * the specified tag name definition. */ @Override - public int compareTo(TagType other) { + public int compareTo(TagNameDefiniton other) { return this.getDisplayName().toLowerCase().compareTo(other.getDisplayName().toLowerCase()); } /** - * Returns a hash code value for this tag type. + * Returns a hash code value for this tag name definition. * * @return The has code. */ @@ -107,7 +109,8 @@ final class TagType implements Comparable { } /** - * Indicates whether some other object is "equal to" this tag type. + * Indicates whether some other object is "equal to" this tag name + * definition. * * @param obj The object to test for equality. * @@ -115,15 +118,15 @@ final class TagType implements Comparable { */ @Override public boolean equals(Object obj) { - if (!(obj instanceof TagType)) { + if (!(obj instanceof TagNameDefiniton)) { return false; } - TagType thatTagName = (TagType) obj; + TagNameDefiniton thatTagName = (TagNameDefiniton) obj; return this.getDisplayName().equals(thatTagName.getDisplayName()); } /** - * A string representation of this tag type. + * A string representation of this tag name definition. * * @return The display name of the tag type. */ @@ -133,43 +136,43 @@ final class TagType implements Comparable { } /** - * @return A string representation of the tag name in the format that is - * used by the properties file. + * @return A string representation of the tag name definition in the format + * that is used by the tags settings file. */ private String toSettingsFormat() { return displayName + "," + description + "," + color.name(); } /** - * Gets the custom tag types for the current user. + * Gets tag name definitions from the tag settings file. * - * @return A set of tag type objects. + * @return A set of tag name definition objects. */ - static synchronized Set getCustomTagTypes() { - Set tagTypes = new HashSet<>(); + static synchronized Set getTagNameDefinitions() { + Set tagNames = 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]))); + tagNames.add(new TagNameDefiniton(tagNameAttributes[0], tagNameAttributes[1], TagName.HTML_COLOR.valueOf(tagNameAttributes[2]))); } } - return tagTypes; + return tagNames; } /** - * Sets the custom tag types for the current user. + * Sets the tag name definitions in the tag settings file. * - * @param tagTypes A set of tag type objects. + * @param tagNames A set of tag name definition objects. */ - static synchronized void setCustomTagTypes(Set tagTypes) { + static synchronized void setTagNameDefinitions(Set tagNames) { StringBuilder setting = new StringBuilder(); - for (TagType tagType : tagTypes) { + for (TagNameDefiniton tagName : tagNames) { if (setting.length() != 0) { setting.append(";"); } - setting.append(tagType.toSettingsFormat()); + setting.append(tagName.toSettingsFormat()); } ModuleSettings.setConfigSetting(TAGS_SETTINGS_NAME, TAG_NAMES_SETTING_KEY, setting.toString()); } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form index 4b3a77eb92..1f81b4d3aa 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.form @@ -92,10 +92,10 @@ - + - - + + @@ -112,8 +112,8 @@ - - + + @@ -143,35 +143,35 @@ - + - + - + - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java index d1fcfdd992..4f761062e8 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagOptionsPanel.java @@ -36,15 +36,15 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { private static final long serialVersionUID = 1L; private static final String DEFAULT_DESCRIPTION = ""; private static final TagName.HTML_COLOR DEFAULT_COLOR = TagName.HTML_COLOR.NONE; - private final DefaultListModel tagTypesListModel; - private Set tagTypes; + private final DefaultListModel tagTypesListModel; + private Set tagTypes; /** * Creates new form TagsManagerOptionsPanel */ TagOptionsPanel() { tagTypesListModel = new DefaultListModel<>(); - tagTypes = new TreeSet<>(TagType.getCustomTagTypes()); + tagTypes = new TreeSet<>(TagNameDefiniton.getTagNameDefinitions()); initComponents(); customizeComponents(); } @@ -72,8 +72,8 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { tagTypesListLabel = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); tagNamesList = new javax.swing.JList<>(); - newTagTypeButton = new javax.swing.JButton(); - deleteTagTypeButton = new javax.swing.JButton(); + newTagNameButton = new javax.swing.JButton(); + deleteTagNameButton = new javax.swing.JButton(); tagTypesAdditionalPanel = new javax.swing.JPanel(); jPanel1.setPreferredSize(new java.awt.Dimension(750, 500)); @@ -88,19 +88,19 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { tagNamesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane1.setViewportView(tagNamesList); - newTagTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(newTagTypeButton, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.newTagTypeButton.text")); // NOI18N - newTagTypeButton.addActionListener(new java.awt.event.ActionListener() { + newTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(newTagNameButton, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.newTagNameButton.text")); // NOI18N + newTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - newTagTypeButtonActionPerformed(evt); + newTagNameButtonActionPerformed(evt); } }); - deleteTagTypeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(deleteTagTypeButton, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.deleteTagTypeButton.text")); // NOI18N - deleteTagTypeButton.addActionListener(new java.awt.event.ActionListener() { + deleteTagNameButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete-tag.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteTagNameButton, org.openide.util.NbBundle.getMessage(TagOptionsPanel.class, "TagOptionsPanel.deleteTagNameButton.text")); // NOI18N + deleteTagNameButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - deleteTagTypeButtonActionPerformed(evt); + deleteTagNameButtonActionPerformed(evt); } }); @@ -113,10 +113,10 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { .addGroup(modifyTagTypesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(tagTypesListLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(modifyTagTypesListPanelLayout.createSequentialGroup() - .addComponent(newTagTypeButton) + .addComponent(newTagNameButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(deleteTagTypeButton) - .addGap(0, 121, Short.MAX_VALUE)) + .addComponent(deleteTagNameButton) + .addGap(0, 113, Short.MAX_VALUE)) .addComponent(jScrollPane1)) .addContainerGap()) ); @@ -129,8 +129,8 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(modifyTagTypesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(newTagTypeButton) - .addComponent(deleteTagTypeButton)) + .addComponent(newTagNameButton) + .addComponent(deleteTagNameButton)) .addContainerGap()) ); @@ -184,12 +184,12 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { ); }// //GEN-END:initComponents - private void newTagTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagTypeButtonActionPerformed - NewUserTagNameDialog dialog = new NewUserTagNameDialog(); - NewUserTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); - if (result == NewUserTagNameDialog.BUTTON_PRESSED.OK) { + private void newTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTagNameButtonActionPerformed + NewTagNameDialog dialog = new NewTagNameDialog(); + NewTagNameDialog.BUTTON_PRESSED result = dialog.getResult(); + if (result == NewTagNameDialog.BUTTON_PRESSED.OK) { String newTagDisplayName = dialog.getTagName(); - TagType newTagType = new TagType(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR); + TagNameDefiniton newTagType = new TagNameDefiniton(newTagDisplayName, DEFAULT_DESCRIPTION, DEFAULT_COLOR); /* * If tag name already exists, don't add the tag name. */ @@ -206,25 +206,25 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { JOptionPane.INFORMATION_MESSAGE); } } - }//GEN-LAST:event_newTagTypeButtonActionPerformed + }//GEN-LAST:event_newTagNameButtonActionPerformed - private void deleteTagTypeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagTypeButtonActionPerformed - TagType tagName = tagNamesList.getSelectedValue(); + private void deleteTagNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteTagNameButtonActionPerformed + TagNameDefiniton tagName = tagNamesList.getSelectedValue(); tagTypes.remove(tagName); updateTagNamesListModel(); enableButtons(); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_deleteTagTypeButtonActionPerformed + }//GEN-LAST:event_deleteTagNameButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton deleteTagTypeButton; + private javax.swing.JButton deleteTagNameButton; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JPanel modifyTagTypesListPanel; - private javax.swing.JButton newTagTypeButton; + private javax.swing.JButton newTagNameButton; private javax.swing.JLabel panelDescriptionLabel; - private javax.swing.JList tagNamesList; + private javax.swing.JList tagNamesList; private javax.swing.JPanel tagTypesAdditionalPanel; private javax.swing.JLabel tagTypesListLabel; // End of variables declaration//GEN-END:variables @@ -234,7 +234,7 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { */ private void updateTagNamesListModel() { tagTypesListModel.clear(); - for (TagType tagName : tagTypes) { + for (TagNameDefiniton tagName : tagTypes) { tagTypesListModel.addElement(tagName); } } @@ -244,7 +244,7 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { */ @Override public void load() { - tagTypes = new TreeSet<>(TagType.getCustomTagTypes()); + tagTypes = new TreeSet<>(TagNameDefiniton.getTagNameDefinitions()); updateTagNamesListModel(); enableButtons(); } @@ -254,7 +254,7 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { */ @Override public void store() { - TagType.setCustomTagTypes(tagTypes); + TagNameDefiniton.setTagNameDefinitions(tagTypes); } /** @@ -266,7 +266,7 @@ final class TagOptionsPanel extends javax.swing.JPanel implements OptionsPanel { * Only enable the delete button when there is a tag type selected in * the tag types JList. */ - deleteTagTypeButton.setEnabled(tagNamesList.getSelectedIndex() != -1); + deleteTagNameButton.setEnabled(tagNamesList.getSelectedIndex() != -1); } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java index 9b7a62bc9c..46982397f8 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsManager.java @@ -20,11 +20,14 @@ 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.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.datamodel.BlackboardArtifact; @@ -42,6 +45,8 @@ import org.sleuthkit.datamodel.TskCoreException; public class TagsManager implements Closeable { private static final Logger LOGGER = Logger.getLogger(TagsManager.class.getName()); + @NbBundle.Messages("TagsManager.predefTagNames.bookmark.text=Bookmark") + private static final Set STANDARD_TAG_DISPLAY_NAMES = new HashSet<>(Arrays.asList(Bundle.TagsManager_predefTagNames_bookmark_text())); private final SleuthkitCase caseDb; /** @@ -104,9 +109,9 @@ public class TagsManager implements Closeable { * map. */ Map tagNames = new HashMap<>(); - tagNames.put("TagsManager.predefTagNames.bookmark.text", null); - Set customTypes = TagType.getCustomTagTypes(); - for (TagType tagType : customTypes) { + tagNames.put(NbBundle.getMessage(this.getClass(), "TagsManager.predefTagNames.bookmark.text"), null); + Set customTypes = TagNameDefiniton.getTagNameDefinitions(); + for (TagNameDefiniton tagType : customTypes) { tagNames.put(tagType.getDisplayName(), null); } for (TagName tagName : caseDb.getAllTagNames()) { @@ -116,8 +121,8 @@ public class TagsManager implements Closeable { } /** - * Adds a tag name entry to the case database and adds a corresponding - * tag type to the current user's custom tag types. + * 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 type. * @@ -134,8 +139,8 @@ public class TagsManager implements Closeable { } /** - * Adds a tag name entry to the case database and adds a corresponding - * tag type to the current user's custom tag types. + * 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 type. * @param description The description for the new tag type. @@ -153,8 +158,8 @@ public class TagsManager implements Closeable { } /** - * Adds a tag name entry to the case database and adds a corresponding - * tag type to the current user's custom tag types. + * 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 type. * @param description The description for the new tag type. @@ -170,9 +175,11 @@ public class TagsManager implements Closeable { public synchronized TagName addTagName(String displayName, String description, TagName.HTML_COLOR color) throws TagNameAlreadyExistsException, TskCoreException { try { TagName tagName = caseDb.addTagName(displayName, description, color); - Set customTypes = TagType.getCustomTagTypes(); - customTypes.add(new TagType(displayName, description, color)); - TagType.setCustomTagTypes(customTypes); + if (!STANDARD_TAG_DISPLAY_NAMES.contains(displayName)) { + Set customTypes = TagNameDefiniton.getTagNameDefinitions(); + customTypes.add(new TagNameDefiniton(displayName, description, color)); + TagNameDefiniton.setTagNameDefinitions(customTypes); + } return tagName; } catch (TskCoreException ex) { List existingTagNames = caseDb.getAllTagNames(); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java index 48947d51f1..3d36e8ae00 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/services/TagsOptionsPanelController.java @@ -28,7 +28,7 @@ import org.openide.util.Lookup; @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_TagNamesOptions", - iconBase = "org/sleuthkit/autopsy/casemodule/services/tags-manager.png", + iconBase = "org/sleuthkit/autopsy/casemodule/services/tag-options-panel-icon.png", keywords = "#OptionsCategory_TagNames", keywordsCategory = "CustomTagNames", position = 8 diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png b/Core/src/org/sleuthkit/autopsy/casemodule/services/tag-options-panel-icon.png similarity index 100% rename from Core/src/org/sleuthkit/autopsy/casemodule/services/tags-manager.png rename to Core/src/org/sleuthkit/autopsy/casemodule/services/tag-options-panel-icon.png