<commit_before>package org.intermine.bio.dataconversion;

/*
 * Copyright (C) 2002-2013 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.collections.keyvalue.MultiKey;
import org.apache.commons.collections.map.MultiKeyMap;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * Hold data about primary identifiers and synonyms for a particular class in the
 * data model and provide methods to resolved synonyms into corresponding
 * primary identifier(s).
 *
 * @author rns
 * @author <NAME>
 */
public class IdResolver
{
    private static final Logger LOG = Logger.getLogger(IdResolver.class);

    private String clsName;

    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgIdMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgSynMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgMainMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgIdMainMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgIdSynMaps = new MultiKeyMap();

    /**
     * Construct and empty IdResolver
     */
    public IdResolver() {
    }

    /**
     * Construct and empty IdResolver
     * @param clsName the class to resolve identifiers for
     */
    public IdResolver(String clsName) {
        this.clsName = clsName;
    }

    // check that the given taxon id has some data for it
    // if an exception thrown, there must be something wrong with resolver factory.
    protected void checkTaxonId(String taxonId, String clsName) {
        if (!orgIdMaps.containsKey(new MultiKey(taxonId, clsName))) {
            throw new IllegalArgumentException(clsName + " IdResolver has "
                                               + "no data for taxonId: "
                                               + taxonId + ".");
        }
    }

    /**
     * Check whether the given id is a primary identifier for this taxonId
     * @param taxonId the organism to look up
     * @param clsName go term
     * @param id an identifier
     * @return true if id is a primaryIdentifier
     */
    public boolean isPrimaryIdentifier(String taxonId, String clsName, String id) {
        checkTaxonId(taxonId, clsName);
        return orgIdMaps.get(new MultiKey(taxonId, clsName)).containsKey(id);
    }

    /**
     * Check whether the given id is a primary identifier for this taxonId
     * @param taxonId the organism to look up
     * @param id an identifier
     * @return true if id is a primaryIdentifier
     */
    public boolean isPrimaryIdentifier(String taxonId, String id) {
        return isPrimaryIdentifier(taxonId, this.clsName, id);
    }

    /**
     * For the given id return a set of matching primary identifiers in the given
     * taxonId.  In many cases the set will have just one element. Some will have
     * zero element.
     * @param taxonId the organism to search within
     * @param clsName go term
     * @param id the identifier to resolve
     * @return a set of matching primary identifiers
     */
    public Set<String> resolveId(String taxonId, String clsName, String id) {
        checkTaxonId(taxonId,clsName);
        // if this is a primary identifier, just return it
        if (isPrimaryIdentifier(taxonId, clsName, id)) {
            return Collections.singleton(id);
        }
        if (orgMainMaps.containsKey(new MultiKey(taxonId, clsName))
            && orgMainMaps.get(new MultiKey(taxonId, clsName)).containsKey(id)) {
            return orgMainMaps.get(new MultiKey(taxonId, clsName)).get(id);
        }
        if (orgSynMaps.containsKey(new MultiKey(taxonId, clsName))
            && orgSynMaps.get(new MultiKey(taxonId, clsName)).containsKey(id)) {
            return orgSynMaps.get(new MultiKey(taxonId, clsName)).get(id);
        }
        return Collections.emptySet();
    }

    /**
     * For the given set of ids return a map of matching primary identifiers in the given
     * taxonId.  In many cases the set will have just one element. Some will have
     * zero element.
     * @param taxonId the organism to search within
     * @param clsName go term
     * @param ids the identifier set to resolve
     * @return a set of common pid
     */
    public Set<String> resolveIds(String taxonId, String clsName, List<String> ids) {
        Set<String> common = new LinkedHashSet<String>();
        for (int i=0; i<ids.size();i++) {
            Set<String> resovledSet = resolveId(taxonId, clsName, ids.get(i));
            if (i == 0) {
                common.addAll(resovledSet);
            } else {
                common.retainAll(resovledSet);
            }
        }

        return common;
    }

    /**
     * For the given id return a set of matching primary identifiers in the given
     * taxonId.  In many cases the set will have just one element. Some will have
     * zero element.
     * @param taxonId the organism to search within
     * @param id the identifier to resolve
     * @return a set of matching primary identifiers
     */
    public Set<String> resolveId(String taxonId, String id) {
        return resolveId(taxonId, this.clsName, id);
    }

    /**
     * For the given id set return a map of matching primary identifiers in the given<commit_msg>fixed a bug when resolving muliple ids<commit_after>package org.intermine.bio.dataconversion;

/*
 * Copyright (C) 2002-2013 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.collections.keyvalue.MultiKey;
import org.apache.commons.collections.map.MultiKeyMap;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * Hold data about primary identifiers and synonyms for a particular class in the
 * data model and provide methods to resolved synonyms into corresponding
 * primary identifier(s).
 *
 * @author rns
 * @author <NAME>
 */
public class IdResolver
{
    private static final Logger LOG = Logger.getLogger(IdResolver.class);

    private String clsName;

    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgIdMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgSynMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgMainMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgIdMainMaps = new MultiKeyMap();
    @SuppressWarnings("unchecked")
    protected Map<MultiKey, Map<String, Set<String>>> orgIdSynMaps = new MultiKeyMap();

    /**
     * Construct and empty IdResolver
     */
    public IdResolver() {
    }

    /**
     * Construct and empty IdResolver
     * @param clsName the class to resolve identifiers for
     */
    public IdResolver(String clsName) {
        this.clsName = clsName;
    }

    // check that the given taxon id has some data for it
    // if an exception thrown, there must be something wrong with resolver factory.
    protected void checkTaxonId(String taxonId, String clsName) {
        if (!orgIdMaps.containsKey(new MultiKey(taxonId, clsName))) {
            throw new IllegalArgumentException(clsName + " IdResolver has "
                                               + "no data for taxonId: "
                                               + taxonId + ".");
        }
    }

    /**
     * Check whether the given id is a primary identifier for this taxonId
     * @param taxonId the organism to look up
     * @param clsName go term
     * @param id an identifier
     * @return true if id is a primaryIdentifier
     */
    public boolean isPrimaryIdentifier(String taxonId, String clsName, String id) {
        checkTaxonId(taxonId, clsName);
        return orgIdMaps.get(new MultiKey(taxonId, clsName)).containsKey(id);
    }

    /**
     * Check whether the given id is a primary identifier for this taxonId
     * @param taxonId the organism to look up
     * @param id an identifier
     * @return true if id is a primaryIdentifier
     */
    public boolean isPrimaryIdentifier(String taxonId, String id) {
        return isPrimaryIdentifier(taxonId, this.clsName, id);
    }

    /**
     * For the given id return a set of matching primary identifiers in the given
     * taxonId.  In many cases the set will have just one element. Some will have
     * zero element.
     * @param taxonId the organism to search within
     * @param clsName go term
     * @param id the identifier to resolve
     * @return a set of matching primary identifiers
     */
    public Set<String> resolveId(String taxonId, String clsName, String id) {
        checkTaxonId(taxonId,clsName);
        // if this is a primary identifier, just return it
        if (isPrimaryIdentifier(taxonId, clsName, id)) {
            return Collections.singleton(id);
        }
        if (orgMainMaps.containsKey(new MultiKey(taxonId, clsName))
            && orgMainMaps.get(new MultiKey(taxonId, clsName)).containsKey(id)) {
            return orgMainMaps.get(new MultiKey(taxonId, clsName)).get(id);
        }
        if (orgSynMaps.containsKey(new MultiKey(taxonId, clsName))
            && orgSynMaps.get(new MultiKey(taxonId, clsName)).containsKey(id)) {
            return orgSynMaps.get(new MultiKey(taxonId, clsName)).get(id);
        }
        return Collections.emptySet();
    }

    /**
     * For the given set of ids return a map of matching primary identifiers in the given
     * taxonId.  In many cases the set will have just one element. Some will have
     * zero element.
     * @param taxonId the organism to search within
     * @param clsName go term
     * @param ids the identifier set to resolve
     * @return a set of common pid
     */
    public Set<String> resolveIds(String taxonId, String clsName, List<String> ids) {
        Set<String> common = new LinkedHashSet<String>();
        for (int i=0; i<ids.size();i++) {
            Set<String> resovledSet = resolveId(taxonId, clsName, ids.get(i));
            common.addAll(resovledSet);
        }

        common.remove(null);
        return common;
    }

    /**
     * For the given id return a set of matching primary identifiers in the given
     * taxonId.  In many cases the set will have just one element. Some will have
     * zero element.
     * @param taxonId the organism to search within
     * @param id the identifier to resolve
     * @return a set of matching primary identifiers
     */
    public Set<String> resolveId(String taxonId, String id) {
        return resolveId(taxonId, this.clsName, id);
    }

    /**
     * For the given id set return a map of matching primary identifiers in the given
{'fraction_non_alphanumeric': 0.09044732098967721, 'fraction_numerical': 0.0017204653449123383, 'mean_word_length': 2.841095028319698, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2769334', 'n_tokens_mistral': 3476, 'n_tokens_neox': 3465, 'n_words': 1155}