package org.intermine.webservice.server.template;

/*
 * Copyright (C) 2002-2012 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.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.intermine.api.InterMineAPI;
import org.intermine.api.profile.Profile;
import org.intermine.api.template.TemplateManager;
import org.intermine.api.template.TemplatePopulator;
import org.intermine.pathquery.Path;
import org.intermine.pathquery.PathException;
import org.intermine.pathquery.PathQuery;
import org.intermine.template.TemplatePopulatorException;
import org.intermine.template.TemplateQuery;
import org.intermine.template.TemplateValue;
import org.intermine.web.logic.template.TemplateHelper;
import org.intermine.web.logic.template.TemplateHelper.TemplateValueParseException;
import org.intermine.web.logic.template.TemplateResultInput;
import org.intermine.webservice.server.exceptions.BadRequestException;
import org.intermine.webservice.server.query.QueryToListService;
import org.intermine.webservice.server.template.result.TemplateResultRequestParser;

/**
 * A service for turning the results of a template query into a list.
 * @author Alexis Kalderimis
 *
 */
public class TemplateToListService extends QueryToListService
{

    private static final String NEW_VIEW_PARAM = "path";

    private final TemplateManager templateManager;

    private static final Logger LOG = Logger.getLogger(TemplateToListService.class);

    /**
     * Constructor
     * @param im API settings bundle
     */
    public TemplateToListService(InterMineAPI im) {
        super(im);
        templateManager = im.getTemplateManager();
    }

    @Override
    protected PathQuery getQuery(HttpServletRequest request) {

        String newViewString = request.getParameter(NEW_VIEW_PARAM);
        if (StringUtils.isEmpty(newViewString)) {
            throw new BadRequestException("new view string is blank");
        }

        Profile profile = getPermission().getProfile();

        TemplateResultInput input = new TemplateResultRequestParser(request).getInput();
        TemplateQuery template = templateManager.getUserOrGlobalTemplate(profile, input.getName());

        Path newViewPath;
        try {
            newViewPath = new Path(template.getModel(), newViewString);
        } catch (PathException e) {
            throw new BadRequestException("The new view string is not a valid path", e);
        }

        if (newViewPath.endIsAttribute()) {
            if (!newViewString.endsWith(".id")) {
                throw new BadRequestException(
                        "The new view string refers to an attribute which is not the object id");
            }
        } else {
            newViewString += ".id";
        }


        Map<String, List<TemplateValue>> templateValues;
        try {
            templateValues = TemplateHelper.getValuesFromInput(template, input);
        } catch (TemplateValueParseException e) {
            throw new BadRequestException(e.getMessage(), e);
        }
        TemplateQuery populatedTemplate;
        try {
            populatedTemplate =
                TemplatePopulator.getPopulatedTemplate(template, templateValues);
        } catch (TemplatePopulatorException e) {
            e.printStackTrace();
            LOG.error("Error populating template: " + template.getName() + ". " + e);
            throw new BadRequestException("Error in applying constraint values to template: "
                    + template.getName(), e);
        }

        PathQuery pq = populatedTemplate.getQueryToExecute();

        pq.clearView();
        pq.addView(newViewString);

        return pq;
    }

}

@@ -1566,16 +1566,450 @@
 vice%0A%7B%0A%0A
+    /* ERROR MESSAGES */%0A    private static final String NOT_LISTABLE = %22You cannot make lists from objects of type %22;%0A    private static final String INVALID_VIEW = %22The new view string is not a valid path%22;%0A    private static final String NOT_IM_OBJECT = %22The new view string refers to an attribute which is not the object id%22;%0A    private static final String BAD_CONSTRAINT_VALUES = %22Could not apply template constraint values. %22;%0A
     priv
@@ -2109,17 +2109,16 @@
 anager;%0A
-%0A
     priv
@@ -2992,38 +2992,26 @@
 h = 
-new Path(template.getModel(), 
+template.makePath(
 newV
@@ -3104,49 +3104,20 @@
 ion(
-%22The new view string is not a valid path%22
+INVALID_VIEW
 , e)
@@ -3269,16 +3269,80 @@
 ception(
+NOT_IM_OBJECT);%0A            %7D%0A        %7D else %7B%0A            try %7B
 %0A       
@@ -3353,157 +3353,353 @@
     
-         %22The
  new
- view s
+ViewS
 tring 
-refers to an attribute which is not the object id%22);%0A            %7D%0A        %7D else %7B%0A            newViewString += %22.id%22;
+= newViewPath.append(%22id%22).getNoConstraintsString();%0A            %7D catch (PathException e) %7B%0A                // FastPath objects don't have IDs, and can't be stored in lists.%0A                throw new BadRequestException(%0A                    NOT_LISTABLE + newViewPath.getLastClassDescriptor().getUnqualifiedName());%0A            %7D
 %0A   
@@ -3706,17 +3706,16 @@
      %7D%0A%0A
-%0A
         
@@ -4066,32 +4066,16 @@
 mplate =
-%0A               
  Templat
@@ -4198,246 +4198,73 @@
     
-e.printStackTrace();%0A            LOG.error(%22Error populating template: %22 + template.getName() + %22. %22 + e);%0A            throw new BadRequestException(%22Error in applying constraint values to template: %22%0A                    + template.getNam
+throw new BadRequestException(BAD_CONSTRAINT_VALUES + e.getMessag
 e(),
@@ -4427,11 +4427,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

Clean up code