<commit_before>/*
 * Autopsy Forensic Browser
 *
 * Copyright 2011-2018 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sleuthkit.autopsy.casemodule.services;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
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.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.services.contentviewertags.ContentViewerTagManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.CaseDbAccessManager;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TagSet;
import org.sleuthkit.datamodel.TaggingManager;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskData.DbType;

/**
 * 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 final SleuthkitCase caseDb;

    static String DEFAULT_TAG_SET_NAME = "Project VIC (United States)";

    static {

        //Create the contentviewer tags table if the current case does not 
        //have the table present
        Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), evt -> {
            if (evt.getNewValue() != null) {
                Case currentCase = (Case) evt.getNewValue();
                try {
                    CaseDbAccessManager caseDb = currentCase.getSleuthkitCase().getCaseDbAccessManager();
                    if (caseDb.tableExists(ContentViewerTagManager.TABLE_NAME)) {
                        return;
                    }

                    if (currentCase.getSleuthkitCase().getDatabaseType().equals(DbType.SQLITE)) {
                        caseDb.createTable(ContentViewerTagManager.TABLE_NAME, ContentViewerTagManager.TABLE_SCHEMA_SQLITE);
                    } else if (currentCase.getSleuthkitCase().getDatabaseType().equals(DbType.POSTGRESQL)) {
                        caseDb.createTable(ContentViewerTagManager.TABLE_NAME, ContentViewerTagManager.TABLE_SCHEMA_POSTGRESQL);
                    }
                } catch (TskCoreException ex) {
                    LOGGER.log(Level.SEVERE,
                            String.format("Unable to create the %s table for image tag storage.",
                                    ContentViewerTagManager.TABLE_NAME), ex);
                }
            }
        });
    }

    /**
     * Tests whether or not a given tag display name contains an illegal
     * character.
     *
     * @param tagDisplayName Display name of a tag.
     *
     * @return True or false.
     */
    public static boolean containsIllegalCharacters(String tagDisplayName) {
        return (tagDisplayName.contains("\\")
                || tagDisplayName.contains(":")
                || tagDisplayName.contains("*")
                || tagDisplayName.contains("?")
                || tagDisplayName.contains("\"")
                || tagDisplayName.contains("<")
                || tagDisplayName.contains(">")
                || tagDisplayName.contains("|")
                || tagDisplayName.contains(",")
                || tagDisplayName.contains(";"));

    }

    @NbBundle.Messages({"TagsManager.notableTagEnding.text= (Notable)"})
    /**
     * Get String of text which is used to label tags as notable to the user.
     *
     * @return Bundle message TagsManager.notableTagEnding.text
     */
    public static String getNotableTagLabel() {
        return Bundle.TagsManager_notableTagEnding_text();
    }

    /**
     * Gets the set of display names of the currently available tag types. This
     * includes the display names of the standard tag types, the current user's
     * custom tag types, and the tags in the case database of the current case
     * (if there is a current case).
     *
     * @return A set, possibly empty, of tag type display names.
     *
     * @throws TskCoreException If there is a current case and there is an error
     *                          querying the case database for tag types.
     */
    public static Set<String> getTagDisplayNames() throws TskCoreException {
        Set<String> tagDisplayNames = new HashSet<>();
        Set<TagNameDefinition> customNames = TagNameDefinition.getTagNameDefinitions();
        customNames.forEach((tagType) -> {
            tagDisplayNames.add(tagType.getDisplayName());
        });
        try {
            TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
            for (TagName tagName : tagsManager.getAllTagNames()) {
                tagDisplayNames.add(tagName.getDisplayName());
            }
        } catch (NoCurrentCaseException ignored) {
            /*
             * No current case, nothing more to add to the set.
             */
        }
        return tagDisplayNames;
    }

    public static List<String> getNotableTagDisplayNames() {
        List<String> tagDisplayNames = new ArrayList<>();
        for (TagNameDefinition tagDef : TagNameDefinition.getTagNameDefinitions()) {
            if (tagDef.getKnownStatus() == TskData.FileKnown.BAD) {
                tagDisplayNames.add(tagDef.getDisplayName());
            }
        }
        return tagDisplayNames;
    }

    /**
     * Returns a list of names of standard/predefined tags
     *
     * @return list of predefined tag names
     */
    public static List<String> getStandardTagNames() {
        return TagNameDefinition.getStandardTagNames();
    }

    /**
     * Constructs a per case Autopsy service that manages the addition of
     * content and artifact tags to the case database.
     *
     * @param caseDb The case database.
     */
    TagsManager(SleuthkitCase caseDb) {
        this.caseDb = caseDb;
<commit_msg>Fixed getNotableTagDisplayName<commit_after>/*
 * Autopsy Forensic Browser
 *
 * Copyright 2011-2018 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sleuthkit.autopsy.casemodule.services;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
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.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.casemodule.services.contentviewertags.ContentViewerTagManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.CaseDbAccessManager;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TagSet;
import org.sleuthkit.datamodel.TaggingManager;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskData.DbType;

/**
 * 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 final SleuthkitCase caseDb;

    static String DEFAULT_TAG_SET_NAME = "Project VIC (United States)";

    static {

        //Create the contentviewer tags table if the current case does not 
        //have the table present
        Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), evt -> {
            if (evt.getNewValue() != null) {
                Case currentCase = (Case) evt.getNewValue();
                try {
                    CaseDbAccessManager caseDb = currentCase.getSleuthkitCase().getCaseDbAccessManager();
                    if (caseDb.tableExists(ContentViewerTagManager.TABLE_NAME)) {
                        return;
                    }

                    if (currentCase.getSleuthkitCase().getDatabaseType().equals(DbType.SQLITE)) {
                        caseDb.createTable(ContentViewerTagManager.TABLE_NAME, ContentViewerTagManager.TABLE_SCHEMA_SQLITE);
                    } else if (currentCase.getSleuthkitCase().getDatabaseType().equals(DbType.POSTGRESQL)) {
                        caseDb.createTable(ContentViewerTagManager.TABLE_NAME, ContentViewerTagManager.TABLE_SCHEMA_POSTGRESQL);
                    }
                } catch (TskCoreException ex) {
                    LOGGER.log(Level.SEVERE,
                            String.format("Unable to create the %s table for image tag storage.",
                                    ContentViewerTagManager.TABLE_NAME), ex);
                }
            }
        });
    }

    /**
     * Tests whether or not a given tag display name contains an illegal
     * character.
     *
     * @param tagDisplayName Display name of a tag.
     *
     * @return True or false.
     */
    public static boolean containsIllegalCharacters(String tagDisplayName) {
        return (tagDisplayName.contains("\\")
                || tagDisplayName.contains(":")
                || tagDisplayName.contains("*")
                || tagDisplayName.contains("?")
                || tagDisplayName.contains("\"")
                || tagDisplayName.contains("<")
                || tagDisplayName.contains(">")
                || tagDisplayName.contains("|")
                || tagDisplayName.contains(",")
                || tagDisplayName.contains(";"));

    }

    @NbBundle.Messages({"TagsManager.notableTagEnding.text= (Notable)"})
    /**
     * Get String of text which is used to label tags as notable to the user.
     *
     * @return Bundle message TagsManager.notableTagEnding.text
     */
    public static String getNotableTagLabel() {
        return Bundle.TagsManager_notableTagEnding_text();
    }

    /**
     * Gets the set of display names of the currently available tag types. This
     * includes the display names of the standard tag types, the current user's
     * custom tag types, and the tags in the case database of the current case
     * (if there is a current case).
     *
     * @return A set, possibly empty, of tag type display names.
     *
     * @throws TskCoreException If there is a current case and there is an error
     *                          querying the case database for tag types.
     */
    public static Set<String> getTagDisplayNames() throws TskCoreException {
        Set<String> tagDisplayNames = new HashSet<>();
        Set<TagNameDefinition> customNames = TagNameDefinition.getTagNameDefinitions();
        customNames.forEach((tagType) -> {
            tagDisplayNames.add(tagType.getDisplayName());
        });
        try {
            TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
            for (TagName tagName : tagsManager.getAllTagNames()) {
                tagDisplayNames.add(tagName.getDisplayName());
            }
        } catch (NoCurrentCaseException ignored) {
            /*
             * No current case, nothing more to add to the set.
             */
        }
        return tagDisplayNames;
    }

    /**
     * Gets the set of display names of notable (TskData.FileKnown.BAD) tag types.
     * If a case is not open the list will only include only the user defined 
     * custom tags.  Otherwise the list will include all notable tags.
     * @return 
     */
    public static List<String> getNotableTagDisplayNames() {
        List<String> tagDisplayNames = new ArrayList<>();
        for (TagNameDefinition tagDef : TagNameDefinition.getTagNameDefinitions()) {
            if (tagDef.getKnownStatus() == TskData.FileKnown.BAD) {
                tagDisplayNames.add(tagDef.getDisplayName());
            }
        }
        
         try {
            TagsManager tagsManager = Case.getCurrentCaseThrows().getServices().getTagsManager();
            for (TagName tagName : tagsManager.getAllTagNames()) {
                if(tagName.getKnownStatus() == TskData.FileKnown.BAD &&
                        !tagDisplayNames.contains(tagName.getDisplayName())) {
                    tagDisplayNames.add(tagName.getDisplayName());
                }
            }
        } catch (NoCurrentCaseException ignored) {
            /*
             * No current case, nothing more to add to the set.
             */
        } catch(TskCoreException ex) {
            LOGGER.log(Level.SEVERE, "Faile to get list of TagNams from tagsManager.");
        }
        return tagDisplayNames;
    }

    /**
     * Returns a list of names of standard/predefined tags
     *
     * @return list of predefined tag names
     */
    public static List<String> getStandardTagNames() {
        return TagNameDefinition.getStandardTagNames();
    }

    /**
     * Constructs a per case Autopsy service that manages the addition of
     * content and artifact tags to the case database.
     *
     * @param caseDb The case database.
     */
    TagsManager(SleuthkitCase caseDb) {
        this.caseDb = caseDb;

{'fraction_non_alphanumeric': 0.09021899771597475, 'fraction_numerical': 0.0016122531237404273, 'mean_word_length': 2.5310721062618597, 'pattern_counts': {'":': 2, '<': 25, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4906706', 'n_tokens_mistral': 4162, 'n_tokens_neox': 3993, 'n_words': 1060}