<commit_before>package org.intermine.web.struts;

/*
 * Copyright (C) 2002-2007 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.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.Globals;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;
import org.intermine.metadata.Model;
import org.intermine.model.InterMineObject;
import org.intermine.objectstore.ObjectStore;
import org.intermine.objectstore.ObjectStoreWriter;
import org.intermine.objectstore.intermine.ObjectStoreWriterInterMineImpl;
import org.intermine.objectstore.query.ConstraintOp;
import org.intermine.objectstore.query.ResultsRow;
import org.intermine.path.Path;
import org.intermine.util.StringUtil;
import org.intermine.web.logic.Constants;
import org.intermine.web.logic.bag.BagConverter;
import org.intermine.web.logic.bag.BagQueryConfig;
import org.intermine.web.logic.bag.BagQueryResult;
import org.intermine.web.logic.bag.BagQueryRunner;
import org.intermine.web.logic.bag.InterMineBag;
import org.intermine.web.logic.config.WebConfig;
import org.intermine.web.logic.profile.Profile;
import org.intermine.web.logic.query.PathQuery;
import org.intermine.web.logic.query.QueryMonitorTimeout;
import org.intermine.web.logic.results.PagedTable;
import org.intermine.web.logic.session.SessionMethods;
import org.intermine.web.logic.template.TemplateHelper;
import org.intermine.web.logic.template.TemplateQuery;

/**
 * The portal query action handles links into flymine from external sites.
 * The action expects 'class' and 'externalid' or 'externalids' parameters
 * it handles the creation of lists if linking in with multiple identifiers
 * and is capable of converting types (e.g. Protein into Gene).
 *
 * @author <NAME>
 * @author <NAME>
 */

public class PortalQueryAction extends InterMineAction
{
    private static int index = 0;

    /**
     * Link-ins from other sites end up here (after some redirection).
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     * @return an ActionForward object defining where control goes next
     *
     * @exception Exception if the application business logic throws
     *  an exception
     */
    public ActionForward execute(ActionMapping mapping,
                                 @SuppressWarnings("unused") ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws Exception {
        HttpSession session = request.getSession();
        ServletContext servletContext = session.getServletContext();
        String extId = request.getParameter("externalid");
        String origin = request.getParameter("origin");
        String className = request.getParameter("class");
        String organism = request.getParameter("organism");
        if ((extId == null) || (extId.length() <= 0)) {
            extId = request.getParameter("externalids");
        }
        // Add a message to welcome the user
        Properties properties = (Properties) servletContext.getAttribute(Constants.WEB_PROPERTIES);
        String welcomeMsg = properties.getProperty("portal.welcome" + origin);
        if (welcomeMsg == null || welcomeMsg.length() == 0) {
            welcomeMsg = properties.getProperty("portal.welcome");
        }
        SessionMethods.recordMessage(welcomeMsg, session);

        if (extId == null || extId.length() == 0) {
            recordError(new ActionMessage("errors.badportalquery"), request);
            return mapping.findForward("failure");
        }
        ActionMessages actionMessages = new ActionMessages();
        session.setAttribute(Constants.PORTAL_QUERY_FLAG, Boolean.TRUE);

        // Set collapsed/uncollapsed state of object details UI
        // TODO This might not be used anymore
        Map<String, Boolean> collapsed = SessionMethods.getCollapsedMap(session);
        collapsed.put("fields", Boolean.TRUE);
        collapsed.put("further", Boolean.FALSE);
        collapsed.put("summary", Boolean.FALSE);

        session.setAttribute(Constants.PORTAL_QUERY_FLAG, Boolean.TRUE);

        Profile profile = (Profile) session.getAttribute(Constants.PROFILE);
        String[] idList = extId.split(",");

        // Use the old way = quicksearch template in case some people used to link in
        // without class name
        if ((idList.length == 1) && (className == null || className.length() == 0)) {
            String qid = loadObjectDetails(servletContext, session, request, response,
                                           profile.getUsername(), extId, origin);
            return new ForwardParameters(mapping.findForward("waiting"))
            .addParameter("qid", qid).forward();
        }

        ObjectStore os = (ObjectStore) servletContext.getAttribute(Constants.OBJECTSTORE);
        WebConfig webConfig = (WebConfig) servletContext.getAttribute(Constants.WEBCONFIG);
        Map classKeys = (Map) servletContext.getAttribute(Constants.CLASS_KEYS);
        Model model = os.getModel();
        BagQueryConfig bagQueryConfig =
                (BagQueryConfig) servletContext.getAttribute(Constants.BAG_QUERY_CONFIG);
        BagQueryRunner bagRunner =
                new BagQueryRunner(os, classKeys, bagQueryConfig, servletContext);

        // If the class is not in the model, we can't continue
        try {
            className = StringUtil.capitalise(className);
            Class.forName(model.getPackageName() + "." + className);
        } catch (ClassNotFoundException clse) {
            recordError(new ActionMessage("errors.badportalclass"), request);
            return mapping.findForward("results");
        }
        ObjectStoreWriter uosw = profile.getProfileManager().getUserProfileObjectStore();
        String bagName = null;
        Map<String, InterMineBag> profileBags = profile.getSavedBags();
        boolean bagExists = true;
        int number = 0;
        while (bagExists) {
            bagName = ".link";
            if (origin != null) {
                bagName += origin;
            }
            bagName += "_" + number;
            bagExists = false;
            for (String name : profileBags.keySet()) {
                if (bagName.equals(name)) {
                    bagExists = true;
                }
            }
            number++;
        }
        InterMineBag imBag = new InterMineBag(bagName,
                                              className , null , new Date() ,
                                              os , profile.getUserId() , uosw);

        BagQueryResult bagQueryResult =
            bagRunner.searchForBag(className, Arrays.asList(idList), organism, false);

        List <Integer> bagList = new ArrayList <Integer> ();
        bagList.addAll(bagQueryResult.getMatchAndIssueIds());
        int matches = bagQueryResult.getMatchAndIssueIds().size();

        DisplayLookupMessageHandler.handleMessages(bagQueryResult, session, 
                                                   properties, className, null);

        // Use custom converters
        Map<String, String []> additionalConverters = bagQueryConfig.getAdditionalConverters();
        for (String converterClassName : additionalConverters.keySet()) {
            Class clazz = Class.forName(converterClassName);
            Constructor constructor = clazz.getConstructor();
            String [] paramArray = additionalConverters.get(converterClassName);
            String [] urlFields = paramArray[0].split(",");
            String addparameter = null;
            String urlField = null;
            for (int i = 0; i < urlFields.length; i++) {
                if (request.getParameter(urlFields[i]) != null) {
                    addparameter = request.getParameter(urlFields[i]);
                    urlField = urlFields[i];
                    break;
                }
            }
            if (addparameter != null && addparameter.length() != 0) {
                BagConverter bagConverter = (BagConverter) constructor.newInstance();
                List<ResultsRow> result = bagConverter.getConvertedObjects(session, addparameter,
                                                bagList, className);
                imBag = new InterMineBag(bagName, className , null , new Date() ,
                                         os , profile.getUserId() , uosw);
                ObjectStoreWriter osw = new ObjectStoreWriterInterMineImpl(os);
                List<Integer> converted = new ArrayList<Integer>();
                for (ResultsRow resRow:result) {
                    converted.add(((InterMineObject) resRow.get(0)).getId());
                }
                if (converted.size() <= 0) {
                    recordMessage(new ActionMessage("portal.nomatches", extId), request);

                    WebPathCollection webPathCollection =
                        new WebPathCollection(os, new Path(model, className), new ArrayList()
                                              , model, webConfig,
                                          classKeys);
                    PagedTable pc = new PagedTable(webPathCollection);
                    String identifier = "col" + index++;
                    SessionMethods.setResultsTable(session, identifier, pc);
                    return new ForwardParameters(mapping.findForward("results"))
                    .addParameter("noSelect", "true")
                    .addParameter("table", identifier)
                    .addParameter("trail", "").forward();
                }
                if (converted.size() == 1) {
                    return new ForwardParameters(mapping.findForward("objectDetails"))
                    .addParameter("id", converted.get(0).toString()).forward();
                }
                osw.addAllToBag(imBag.getOsb(), converted);
                osw.close();
                profile.saveBag(imBag.getName(), imBag);
                
                actionMessages.add(Constants.PORTAL_MSG, bagConverter.getActionMessage(
                                    model, extId, addparameter, imBag, idList.length));
                session.setAttribute(Constants.PORTAL_MSG, actionMessages);


                return new ForwardParameters(mapping.findForward("bagDetails"))
                .addParameter("addparameter", addparameter)
                .addParameter("externalids", extId)
                .addParameter("bagName", imBag.getName()).forward();
            }
        }

        // Attach messages
        if (bagList.size() == 0 && bagQueryResult.getMatches().size() == 1) {<commit_msg>Message displays also when only one matching ortholog<commit_after>package org.intermine.web.struts;

/*
 * Copyright (C) 2002-2007 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.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.Globals;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;
import org.intermine.metadata.Model;
import org.intermine.model.InterMineObject;
import org.intermine.objectstore.ObjectStore;
import org.intermine.objectstore.ObjectStoreWriter;
import org.intermine.objectstore.intermine.ObjectStoreWriterInterMineImpl;
import org.intermine.objectstore.query.ConstraintOp;
import org.intermine.objectstore.query.ResultsRow;
import org.intermine.path.Path;
import org.intermine.util.StringUtil;
import org.intermine.web.logic.Constants;
import org.intermine.web.logic.bag.BagConverter;
import org.intermine.web.logic.bag.BagQueryConfig;
import org.intermine.web.logic.bag.BagQueryResult;
import org.intermine.web.logic.bag.BagQueryRunner;
import org.intermine.web.logic.bag.InterMineBag;
import org.intermine.web.logic.config.WebConfig;
import org.intermine.web.logic.profile.Profile;
import org.intermine.web.logic.query.PathQuery;
import org.intermine.web.logic.query.QueryMonitorTimeout;
import org.intermine.web.logic.results.PagedTable;
import org.intermine.web.logic.session.SessionMethods;
import org.intermine.web.logic.template.TemplateHelper;
import org.intermine.web.logic.template.TemplateQuery;

/**
 * The portal query action handles links into flymine from external sites.
 * The action expects 'class' and 'externalid' or 'externalids' parameters
 * it handles the creation of lists if linking in with multiple identifiers
 * and is capable of converting types (e.g. Protein into Gene).
 *
 * @author <NAME>
 * @author <NAME>
 */

public class PortalQueryAction extends InterMineAction
{
    private static int index = 0;

    /**
     * Link-ins from other sites end up here (after some redirection).
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     * @return an ActionForward object defining where control goes next
     *
     * @exception Exception if the application business logic throws
     *  an exception
     */
    public ActionForward execute(ActionMapping mapping,
                                 @SuppressWarnings("unused") ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws Exception {
        HttpSession session = request.getSession();
        ServletContext servletContext = session.getServletContext();
        String extId = request.getParameter("externalid");
        String origin = request.getParameter("origin");
        String className = request.getParameter("class");
        String organism = request.getParameter("organism");
        if ((extId == null) || (extId.length() <= 0)) {
            extId = request.getParameter("externalids");
        }
        // Add a message to welcome the user
        Properties properties = (Properties) servletContext.getAttribute(Constants.WEB_PROPERTIES);
        String welcomeMsg = properties.getProperty("portal.welcome" + origin);
        if (welcomeMsg == null || welcomeMsg.length() == 0) {
            welcomeMsg = properties.getProperty("portal.welcome");
        }
        SessionMethods.recordMessage(welcomeMsg, session);

        if (extId == null || extId.length() == 0) {
            recordError(new ActionMessage("errors.badportalquery"), request);
            return mapping.findForward("failure");
        }
        ActionMessages actionMessages = new ActionMessages();
        session.setAttribute(Constants.PORTAL_QUERY_FLAG, Boolean.TRUE);

        // Set collapsed/uncollapsed state of object details UI
        // TODO This might not be used anymore
        Map<String, Boolean> collapsed = SessionMethods.getCollapsedMap(session);
        collapsed.put("fields", Boolean.TRUE);
        collapsed.put("further", Boolean.FALSE);
        collapsed.put("summary", Boolean.FALSE);

        session.setAttribute(Constants.PORTAL_QUERY_FLAG, Boolean.TRUE);

        Profile profile = (Profile) session.getAttribute(Constants.PROFILE);
        String[] idList = extId.split(",");

        // Use the old way = quicksearch template in case some people used to link in
        // without class name
        if ((idList.length == 1) && (className == null || className.length() == 0)) {
            String qid = loadObjectDetails(servletContext, session, request, response,
                                           profile.getUsername(), extId, origin);
            return new ForwardParameters(mapping.findForward("waiting"))
            .addParameter("qid", qid).forward();
        }

        ObjectStore os = (ObjectStore) servletContext.getAttribute(Constants.OBJECTSTORE);
        WebConfig webConfig = (WebConfig) servletContext.getAttribute(Constants.WEBCONFIG);
        Map classKeys = (Map) servletContext.getAttribute(Constants.CLASS_KEYS);
        Model model = os.getModel();
        BagQueryConfig bagQueryConfig =
                (BagQueryConfig) servletContext.getAttribute(Constants.BAG_QUERY_CONFIG);
        BagQueryRunner bagRunner =
                new BagQueryRunner(os, classKeys, bagQueryConfig, servletContext);

        // If the class is not in the model, we can't continue
        try {
            className = StringUtil.capitalise(className);
            Class.forName(model.getPackageName() + "." + className);
        } catch (ClassNotFoundException clse) {
            recordError(new ActionMessage("errors.badportalclass"), request);
            return mapping.findForward("results");
        }
        ObjectStoreWriter uosw = profile.getProfileManager().getUserProfileObjectStore();
        String bagName = null;
        Map<String, InterMineBag> profileBags = profile.getSavedBags();
        boolean bagExists = true;
        int number = 0;
        while (bagExists) {
            bagName = ".link";
            if (origin != null) {
                bagName += origin;
            }
            bagName += "_" + number;
            bagExists = false;
            for (String name : profileBags.keySet()) {
                if (bagName.equals(name)) {
                    bagExists = true;
                }
            }
            number++;
        }
        InterMineBag imBag = new InterMineBag(bagName,
                                              className , null , new Date() ,
                                              os , profile.getUserId() , uosw);

        BagQueryResult bagQueryResult =
            bagRunner.searchForBag(className, Arrays.asList(idList), organism, false);

        List <Integer> bagList = new ArrayList <Integer> ();
        bagList.addAll(bagQueryResult.getMatchAndIssueIds());
        int matches = bagQueryResult.getMatchAndIssueIds().size();

        DisplayLookupMessageHandler.handleMessages(bagQueryResult, session, 
                                                   properties, className, null);

        // Use custom converters
        Map<String, String []> additionalConverters = bagQueryConfig.getAdditionalConverters();
        for (String converterClassName : additionalConverters.keySet()) {
            Class clazz = Class.forName(converterClassName);
            Constructor constructor = clazz.getConstructor();
            String [] paramArray = additionalConverters.get(converterClassName);
            String [] urlFields = paramArray[0].split(",");
            String addparameter = null;
            String urlField = null;
            for (int i = 0; i < urlFields.length; i++) {
                if (request.getParameter(urlFields[i]) != null) {
                    addparameter = request.getParameter(urlFields[i]);
                    urlField = urlFields[i];
                    break;
                }
            }
            if (addparameter != null && addparameter.length() != 0) {
                BagConverter bagConverter = (BagConverter) constructor.newInstance();
                List<ResultsRow> result = bagConverter.getConvertedObjects(session, addparameter,
                                                bagList, className);
                imBag = new InterMineBag(bagName, className , null , new Date() ,
                                         os , profile.getUserId() , uosw);
                ObjectStoreWriter osw = new ObjectStoreWriterInterMineImpl(os);
                List<Integer> converted = new ArrayList<Integer>();
                for (ResultsRow resRow:result) {
                    converted.add(((InterMineObject) resRow.get(0)).getId());
                }
                if (converted.size() <= 0) {
                    recordMessage(new ActionMessage("portal.nomatches", extId), request);

                    WebPathCollection webPathCollection =
                        new WebPathCollection(os, new Path(model, className), new ArrayList()
                                              , model, webConfig,
                                          classKeys);
                    PagedTable pc = new PagedTable(webPathCollection);
                    String identifier = "col" + index++;
                    SessionMethods.setResultsTable(session, identifier, pc);
                    return new ForwardParameters(mapping.findForward("results"))
                    .addParameter("noSelect", "true")
                    .addParameter("table", identifier)
                    .addParameter("trail", "").forward();
                }
                osw.addAllToBag(imBag.getOsb(), converted);
                osw.close();
                profile.saveBag(imBag.getName(), imBag);
                
                actionMessages.add(Constants.PORTAL_MSG, bagConverter.getActionMessage(
                                    model, extId, addparameter, imBag, idList.length));
                session.setAttribute(Constants.PORTAL_MSG, actionMessages);

                if (converted.size() == 1) {
                    return new ForwardParameters(mapping.findForward("objectDetails"))
                    .addParameter("id", converted.get(0).toString()).forward();
                } else {
                    return new ForwardParameters(mapping.findForward("bagDetails"))
                    .addParameter("addparameter", addparameter)
                    .addParameter("externalids", extId)
                    .addParameter("bagName", imBag.getName()).forward();
                }
            }
        }

        // Attach messages
        if (bagList.size() == 0 && bagQueryResult.getMatches().size() == 1) {
{'fraction_non_alphanumeric': 0.09921111301663522, 'fraction_numerical': 0.0020579660435602813, 'mean_word_length': 2.378476245654693, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4334027', 'n_tokens_mistral': 5862, 'n_tokens_neox': 5694, 'n_words': 1366}