package org.intermine.web;

/*
 * Copyright (C) 2002-2004 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 javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionError;

import org.intermine.metadata.Model;
import org.intermine.objectstore.query.ResultsInfo;
import org.intermine.objectstore.ObjectStoreException;
import org.intermine.objectstore.ObjectStoreQueryDurationException;

/**
 * Implementation of <strong>Action</strong> that saves a Query from a session.
 *
 * @author Richard Smith
 * @author Matthew Wakeling
 */
public class SaveQueryAction extends Action
{
    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     *
     * @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,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
        throws Exception {
        HttpSession session = request.getSession();
        Map qNodes = (Map) session.getAttribute(Constants.QUERY);
        List view = (List) session.getAttribute(Constants.VIEW);
        String queryName = ((SaveQueryForm) form).getQueryName();

        try {
            ResultsInfo resultsInfo = ViewHelper.makeEstimate(request);
            saveQuery(request, queryName, qNodes, view, resultsInfo);
        } catch (ObjectStoreException e) {
            ActionMessages actionMessages = new ActionMessages();
            String key = (e instanceof ObjectStoreQueryDurationException)
                ? "errors.query.estimatetimetoolong"
                : "errors.query.objectstoreerror";
            ActionError error = new ActionError(key);
            actionMessages.add(ActionMessages.GLOBAL_MESSAGE, error);
            saveMessages(request, actionMessages);
        }

        return mapping.findForward("query");
    }

    /**
     * Save a query in the Map on the session, and clone it to allow further editing
     * @param request The HTTP request we are processing
     * @param queryName the name to save the query under
     * @param qNodes the actual query
     * @param view the paths in the SELECT list
     * @param resultsInfo the resultsInfo for the query
     */
    public static void saveQuery(HttpServletRequest request,
                                 String queryName,
                                 Map qNodes,
                                 List view,
                                 ResultsInfo resultsInfo) {
        HttpSession session = request.getSession();
        ServletContext servletContext = session.getServletContext();
        Model model = (Model) servletContext.getAttribute(Constants.MODEL);
        Map savedQueries = (Map) session.getAttribute(Constants.SAVED_QUERIES);

        if (savedQueries == null) {
            savedQueries = new LinkedHashMap();
            session.setAttribute(Constants.SAVED_QUERIES, savedQueries);
        }
        
        savedQueries.put(queryName, new QueryInfo(qNodes, view, resultsInfo));
        
        session.setAttribute(Constants.QUERY, SaveQueryHelper.clone(qNodes, model));
        session.setAttribute(Constants.VIEW, new ArrayList(view));
    }
}

@@ -717,23 +717,24 @@
 n.Action
-Forward
+Messages
 ;%0Aimport
@@ -766,22 +766,69 @@
 .ActionM
-apping
+essage;%0Aimport org.apache.struts.action.ActionForward
 ;%0Aimport
@@ -852,39 +852,38 @@
 s.action.ActionM
-essages
+apping
 ;%0Aimport org.apa
@@ -912,16 +912,50 @@
 onError;
+%0Aimport org.apache.struts.Globals;
 %0A%0Aimport
@@ -4637,16 +4637,261 @@
 (view));
+%0A%0A        ActionMessages messages = new ActionMessages();%0A        ActionMessage message = new ActionMessage(%22saveQuery.message%22, queryName);%0A        messages.add(%22saveQuery%22, message);%0A        request.setAttribute(Globals.MESSAGE_KEY, messages);
 %0A    %7D%0A%7D

Save an ActionMessage after saving a query.