<commit_before>package org.intermine.bio.web.util;

/*
 * Copyright (C) 2002-2011 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.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.intermine.api.InterMineAPI;
import org.intermine.api.mines.FriendlyMineManager;
import org.intermine.api.mines.Mine;
import org.intermine.api.profile.ProfileManager;
import org.intermine.api.query.PathQueryExecutor;
import org.intermine.api.results.ExportResultsIterator;
import org.intermine.api.results.ResultElement;
import org.intermine.pathquery.Constraints;
import org.intermine.pathquery.OrderDirection;
import org.intermine.pathquery.PathQuery;
import org.intermine.util.Util;
import org.intermine.web.util.InterMineLinkGenerator;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Helper class for intermine links generated on report pages
 *
 * @author <NAME>
 */
public final class FriendlyMineListLinkGenerator extends InterMineLinkGenerator
{
    private static final Logger LOG = Logger.getLogger(FriendlyMineListLinkGenerator.class);

    /**
     * Constructor
     */
    public FriendlyMineListLinkGenerator() {
        super();
    }

    /**
     * Generate a list of genes and orthologues for remote mines.
     *
     * 1. Query local mine for orthologues for gene given.
     * 2. if orthologue found query remote mine for that gene
     * 3. if orthologue not found query remote mine for orthologues
     *
     * @param linkManager LinkManager
     * @param organisms organism.shortName, eg. C. elegans
     * @param identifiers unused for now
     * @param mineName name of mine to query
     * @return map from mine to organism-->genes
     */
    @Override
    public Collection<JSONObject> getLinks(FriendlyMineManager linkManager, String mineName,
            String organisms, String identifiers) {
        Collection<JSONObject> results = null;
        try {
            results = getRelatedValues(linkManager, mineName, organisms, identifiers);
        } catch (JSONException e) {
            LOG.error("error generating JSON objects", e);
        }
        return results;
    }

    /**
     * used on LIST ANALYSIS page
     *
     * For a given mine and list of values, return filtered list of values contained in mine.  eg.
     * for a list of organisms, return the list of organism present in the given mine.
     *
     * Returns NULL if invalid mine or values not found.
     *
     * @param mineName name of mine to test
     * @param values list of values to check for in the mine
     * @return subset of values given that are present in the mine
     * @throws JSONException
     */
    private Collection<JSONObject> getRelatedValues(FriendlyMineManager linkManager,
            String mineName, String values, String identifiers) throws JSONException {
        if (StringUtils.isEmpty(mineName) || StringUtils.isEmpty(values)) {
            return null;
        }
        List<String> organismsInList = Arrays.asList(values.split(","));
        List<String> identifierSet = Arrays.asList(identifiers.split(","));
        Mine mine = linkManager.getMine(mineName);
        if (mine == null) {
            // mine is dead
            return null;
        }
        Set<String> homologues = mine.getMatchingMapKeys(null, organismsInList);

        if (homologues.isEmpty()) {
            // test if local mine has orthologues
            return checkLocalMine(linkManager, mine, organismsInList, identifierSet);
        }
        return convertToJSON(homologues, identifierSet, true);
    }

    // test if local mine has orthologues
    private Collection<JSONObject> checkLocalMine(FriendlyMineManager linkManager,
            Mine mine, List<String> organismsInList, List<String> identifierSet)
        throws JSONException {
        boolean isOrthologue = true;
        Mine localMine = linkManager.getLocalMine();

        // <NAME> --> Dmel
        Set<String> homologues = localMine.getMatchingMapKeys(mine.getMineValues(),
                organismsInList);
        if (homologues.isEmpty()) {
            // one more try
            // look for Dmel --> <NAME>
            homologues = localMine.getMatchingMapValues(mine.getMineValues(), organismsInList);
            isOrthologue = false;
        }
        if (homologues.isEmpty()) {
            // neither mine has orthologues
            return null;
        }
        // convert
        InterMineAPI im = linkManager.getInterMineAPI();
        ProfileManager profileManager = im.getProfileManager();
        Map<String, List<String>> results =  runLocalQuery(im, profileManager,
                identifierSet, homologues, isOrthologue);
        if (results.isEmpty()) {
            return null;
        }
        return convertToJSON(results, isOrthologue);
    }

    private static Map<String, List<String>> runLocalQuery(InterMineAPI im,
            ProfileManager profileManager, List<String> identifiers,  Set<String> organisms,
            boolean isOrthologue) {
        Map<String, List<String>> results = new HashMap<String, List<String>>();
        PathQueryExecutor executor = im.getPathQueryExecutor(profileManager.getSuperuserProfile());
        PathQuery q = getLocalOrthologueQuery(im, identifiers, organisms, isOrthologue);
        ExportResultsIterator it = null;
        try {
            it = executor.execute(q);
        } catch (Exception e) {
            return Collections.emptyMap();
        }
        while (it.hasNext()) {
            List<ResultElement> row = it.next();
            String orthologuePrimaryIdentifier = (String) row.get(0).getField();
//            String orthologueSymbol = (String) row.get(1).getField();
            String organismName = (String) row.get(2).getField();
            String orthologueIdentifer = null;
            if (!StringUtils.isEmpty(orthologuePrimaryIdentifier)) {
                orthologueIdentifer = orthologuePrimaryIdentifier;
            }
//            if (!StringUtils.isEmpty(orthologueSymbol)) {
//                orthologueIdentifer = orthologueSymbol;
//            }
            if (!StringUtils.isEmpty(orthologueIdentifer)) {
                Util.addToListMap(results, organismName, orthologueIdentifer);
            }
        }<commit_msg>handle mines with no homologues in model<commit_after>package org.intermine.bio.web.util;

/*
 * Copyright (C) 2002-2011 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.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.intermine.api.InterMineAPI;
import org.intermine.api.mines.FriendlyMineManager;
import org.intermine.api.mines.Mine;
import org.intermine.api.profile.ProfileManager;
import org.intermine.api.query.PathQueryExecutor;
import org.intermine.api.results.ExportResultsIterator;
import org.intermine.api.results.ResultElement;
import org.intermine.objectstore.ObjectStoreException;
import org.intermine.pathquery.Constraints;
import org.intermine.pathquery.OrderDirection;
import org.intermine.pathquery.PathQuery;
import org.intermine.util.Util;
import org.intermine.web.util.InterMineLinkGenerator;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Helper class for intermine links generated on report pages
 *
 * @author <NAME>
 */
public final class FriendlyMineListLinkGenerator extends InterMineLinkGenerator
{
    private static final Logger LOG = Logger.getLogger(FriendlyMineListLinkGenerator.class);

    /**
     * Constructor
     */
    public FriendlyMineListLinkGenerator() {
        super();
    }

    /**
     * Generate a list of genes and orthologues for remote mines.
     *
     * 1. Query local mine for orthologues for gene given.
     * 2. if orthologue found query remote mine for that gene
     * 3. if orthologue not found query remote mine for orthologues
     *
     * @param linkManager LinkManager
     * @param organisms organism.shortName, eg. C. elegans
     * @param identifiers unused for now
     * @param mineName name of mine to query
     * @return map from mine to organism-->genes
     */
    @Override
    public Collection<JSONObject> getLinks(FriendlyMineManager linkManager, String mineName,
            String organisms, String identifiers) {
        Collection<JSONObject> results = null;
        try {
            results = getRelatedValues(linkManager, mineName, organisms, identifiers);
        } catch (JSONException e) {
            LOG.error("error generating JSON objects", e);
        }
        return results;
    }

    /**
     * used on LIST ANALYSIS page
     *
     * For a given mine and list of values, return filtered list of values contained in mine.  eg.
     * for a list of organisms, return the list of organism present in the given mine.
     *
     * Returns NULL if invalid mine or values not found.
     *
     * @param mineName name of mine to test
     * @param values list of values to check for in the mine
     * @return subset of values given that are present in the mine
     * @throws JSONException
     */
    private Collection<JSONObject> getRelatedValues(FriendlyMineManager linkManager,
            String mineName, String values, String identifiers) throws JSONException {
        if (StringUtils.isEmpty(mineName) || StringUtils.isEmpty(values)) {
            return null;
        }
        List<String> organismsInList = Arrays.asList(values.split(","));
        List<String> identifierSet = Arrays.asList(identifiers.split(","));
        Mine mine = linkManager.getMine(mineName);
        if (mine == null) {
            // mine is dead
            return null;
        }
        Set<String> homologues = mine.getMatchingMapKeys(null, organismsInList);

        if (homologues.isEmpty()) {
            // test if local mine has orthologues
            return checkLocalMine(linkManager, mine, organismsInList, identifierSet);
        }
        return convertToJSON(homologues, identifierSet, true);
    }

    // test if local mine has orthologues
    private Collection<JSONObject> checkLocalMine(FriendlyMineManager linkManager,
            Mine mine, List<String> organismsInList, List<String> identifierSet)
        throws JSONException {
        boolean isOrthologue = true;
        Mine localMine = linkManager.getLocalMine();

        // <NAME> --> Dmel
        Set<String> homologues = localMine.getMatchingMapKeys(mine.getMineValues(),
                organismsInList);
        if (homologues.isEmpty()) {
            // one more try
            // look for Dmel --> <NAME>
            homologues = localMine.getMatchingMapValues(mine.getMineValues(), organismsInList);
            isOrthologue = false;
        }
        if (homologues.isEmpty()) {
            // neither mine has orthologues
            return null;
        }
        // convert
        InterMineAPI im = linkManager.getInterMineAPI();
        ProfileManager profileManager = im.getProfileManager();
        Map<String, List<String>> results =  runLocalQuery(im, profileManager,
                identifierSet, homologues, isOrthologue);
        if (results.isEmpty()) {
            return null;
        }
        return convertToJSON(results, isOrthologue);
    }

    private static Map<String, List<String>> runLocalQuery(InterMineAPI im,
            ProfileManager profileManager, List<String> identifiers,  Set<String> organisms,
            boolean isOrthologue) {
        Map<String, List<String>> results = new HashMap<String, List<String>>();
        PathQueryExecutor executor = im.getPathQueryExecutor(profileManager.getSuperuserProfile());
        PathQuery q = getLocalOrthologueQuery(im, identifiers, organisms, isOrthologue);
        if (!q.isValid()) {
            return Collections.emptyMap();
        }
        ExportResultsIterator it = executor.execute(q);
        while (it.hasNext()) {
            List<ResultElement> row = it.next();
            String orthologuePrimaryIdentifier = (String) row.get(0).getField();
//            String orthologueSymbol = (String) row.get(1).getField();
            String organismName = (String) row.get(2).getField();
            String orthologueIdentifer = null;
            if (!StringUtils.isEmpty(orthologuePrimaryIdentifier)) {
                orthologueIdentifer = orthologuePrimaryIdentifier;
            }
//            if (!StringUtils.isEmpty(orthologueSymbol)) {
//                orthologueIdentifer = orthologueSymbol;
//            }
            if (!StringUtils.isEmpty(orthologueIdentifer)) {
                Util.addToListMap(results, organismName, orthologueIdentifer);
            }
        }
{'fraction_non_alphanumeric': 0.09068645640074212, 'fraction_numerical': 0.0022263450834879408, 'mean_word_length': 2.745414118954975, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5398477', 'n_tokens_mistral': 3705, 'n_tokens_neox': 3579, 'n_words': 988}