package org.apache.velocity.tools.struts;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.util.Locale;
import java.util.Iterator;

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

import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.ForwardConfig;
import org.apache.struts.config.ActionConfig;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.ModuleUtils;

/**
 * <p>A utility class to expose the Struts shared
 * resources. All methods are static.</p>
 *
 * <p>This class is provided for use by Velocity view tools
 * that need access to Struts resources. By having all Struts-
 * specific code in this utility class, maintenance is simplified
 * and reuse fostered.</p>
 *
 * <p>It is the aim, that sooner or later the functionality in
 * this class is integrated into Struts itself.  See
 * <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16814">Bug #16814</a>
 * for more on that.</p>
 *
 * @author <a href="mailto:marinoj@centrum.is">Marino A. Jonsson</a>
 * @author Nathan Bubna
 * @author <a href="mailto:sidler@teamup.com">Gabe Sidler</a>
 * based on code by <a href="mailto:ted@husted.org">Ted Husted</a>
 *
 * @version $Id$
 */
public class StrutsUtils
{

    /****************** Struts ServletContext Resources ****************/

    /**
     * Returns the message resources for this application or <code>null</code>
     * if not found.
     *
     * @param app the servlet context
     * @since VelocityTools 1.1
     */
    public static MessageResources getMessageResources(HttpServletRequest request,
                                                       ServletContext app)
    {
        return getMessageResources(request, app, null);
    }


    /**
     * Returns the message resources with the specified bundle name for this application
     * or <code>null</code> if not found.
     *
     * @param app the servlet context
     * @param bundle The bundle name to look for.  If this is <code>null</code>, the
     *               default bundle name is used.
     * @since VelocityTools 1.1
     */
    public static MessageResources getMessageResources(HttpServletRequest request,
                                                       ServletContext app,
                                                       String bundle)
    {
        /* Identify the current module */
        ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, app);

        if (bundle == null) {
            bundle = Globals.MESSAGES_KEY;
        }

        // First check request scope
        MessageResources resources =
            (MessageResources)request.getAttribute(bundle + moduleConfig.getPrefix());

        if (resources == null) {
            resources = (MessageResources) app.getAttribute(bundle + moduleConfig.getPrefix());
        }
        return resources;
    }


    /**
     * Select the module to which the specified request belongs, and
     * add return the corresponding ModuleConfig.
     *
     * @param urlPath The requested URL
     * @param app The ServletContext for this web application
     * @return The ModuleConfig for the given URL path
     * @since VelocityTools 1.1
     */
    public static ModuleConfig selectModule(String urlPath,
                                            ServletContext app)
    {
        /* Match against the list of sub-application prefixes */
        String prefix = ModuleUtils.getInstance().getModuleName(urlPath, app);

        /* Expose the resources for this sub-application */
        ModuleConfig config = (ModuleConfig)
            app.getAttribute(Globals.MODULE_KEY + prefix);

        return config;
    }


    /********************** Struts Session Resources ******************/

    /**
     * Returns the <code>java.util.Locale</code> for the user. If a
     * locale object is not found in the user's session, the system
     * default locale is returned.
     *
     * @param request the servlet request
     * @param session the HTTP session
     */
    public static Locale getLocale(HttpServletRequest request,
                                   HttpSession session)
    {
        Locale locale = null;

        if (session != null)
        {
            locale = (Locale)session.getAttribute(Globals.LOCALE_KEY);
        }
        if (locale == null)
        {
            locale = request.getLocale();
        }
        return locale;
    }


    /**
     * Returns the transaction token stored in this session or
     * <code>null</code> if not used.
     *
     * @param session the HTTP session
     */
    public static String getToken(HttpSession session)
    {
        if (session == null)
        {
            return null;
        }
        return (String)session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
    }


    /*********************** Struts Request Resources ****************/

    /**
     * Returns the Struts errors for this request or <code>null</code>
     * if none exist. Since VelocityTools 1.2, this will also check
     * the session (if there is one) for errors if there are no errors
     * in the request.
     *
     * @param request the servlet request
     * @since VelocityTools 1.1
     */
    public static ActionMessages getErrors(HttpServletRequest request)
    {
        ActionMessages errors = (ActionMessages)request.getAttribute(Globals.ERROR_KEY);
        if (errors == null || errors.isEmpty())
        {
            // then check the session
            HttpSession session = request.getSession(false);
            if (session != null)
            {
                errors = (ActionMessages)session.getAttribute(Globals.ERROR_KEY);
            }
        }
        return errors;
    }

    /**
     * Returns the Struts messages for this request or <code>null</code>
     * if none exist.  Since VelocityTools 1.2, this will also check
     * the session (if there is one) for messages if there are no messages
     * in the request.
     *
     * @param request the servlet request
     * @since VelocityTools 1.1
     */
    public static ActionMessages getMessages(HttpServletRequest request)
    {
        ActionMessages messages = (ActionMessages)request.getAttribute(Globals.MESSAGE_KEY);
        if (messages == null || messages.isEmpty())
        {
            // then check the session
            HttpSession session = request.getSession(false);
            if (session != null)
            {
                messages = (ActionMessages)session.getAttribute(Globals.MESSAGE_KEY);
            }
        }
        return messages;
    }

    /**
     * Returns the <code>ActionForm</code> bean associated with
     * this request of <code>null</code> if none exists.
     *
     * @param request the servlet request
     * @param session the HTTP session
     */
    public static ActionForm getActionForm(HttpServletRequest request,
                                           HttpSession session)
    {
        /* Is there a mapping associated with this request? */
        ActionConfig mapping =
            (ActionConfig)request.getAttribute(Globals.MAPPING_KEY);
        if (mapping == null)
        {
            return null;
        }

        /* Is there a form bean associated with this mapping? */
        String attribute = mapping.getAttribute();
        if (attribute == null)
        {
            return null;
        }

        /* Look up the existing form bean */
        if ("request".equals(mapping.getScope()))
        {
            return (ActionForm)request.getAttribute(attribute);
        }
        if (session != null)
        {
            return (ActionForm)session.getAttribute(attribute);
        }
        return null;
    }

    /**
     * Returns the ActionForm name associated with
     * this request of <code>null</code> if none exists.
     *
     * @param request the servlet request
     * @param session the HTTP session
     */
    public static String getActionFormName(HttpServletRequest request,
                                           HttpSession session)
    {
        /* Is there a mapping associated with this request? */
        ActionConfig mapping =
            (ActionConfig)request.getAttribute(Globals.MAPPING_KEY);
        if (mapping == null)
        {
            return null;
        }

        return mapping.getAttribute();
    }



    /*************************** Utilities *************************/

    /**
     * Return the form action converted into an action mapping path.  The
     * value of the <code>action</code> property is manipulated as follows in
     * computing the name of the requested mapping:
     * <ul>
     * <li>Any filename extension is removed (on the theory that extension
     *     mapping is being used to select the controller servlet).</li>
     * <li>If the resulting value does not start with a slash, then a
     *     slash is prepended.</li>
     * </ul>
     */
    public static String getActionMappingName(String action) {

        String value = action;
        int question = action.indexOf("?");
        if (question >= 0) {
            value = value.substring(0, question);
        }

        int slash = value.lastIndexOf("/");
        int period = value.lastIndexOf(".");
        if ((period >= 0) && (period > slash)) {
            value = value.substring(0, period);
        }

        return value.startsWith("/") ? value : ("/" + value);
    }

    /**
     * Returns the form action converted into a server-relative URI
     * reference.
     *
     * @param application the servlet context
     * @param request the servlet request
     * @param action the name of an action as per struts-config.xml
     */
    public static String getActionMappingURL(ServletContext application,
                                             HttpServletRequest request,
                                             String action)
    {
        StringBuffer value = new StringBuffer(request.getContextPath());
        ModuleConfig config =
            (ModuleConfig)request.getAttribute(Globals.MODULE_KEY);
        if (config != null)
        {
            value.append(config.getPrefix());
        }

        /* Use our servlet mapping, if one is specified */
        String servletMapping =
            (String)application.getAttribute(Globals.SERVLET_KEY);

        if (servletMapping != null)
        {
            String queryString = null;
            int question = action.indexOf("?");

            if (question >= 0)
            {
                queryString = action.substring(question);
            }

            String actionMapping = TagUtils.getInstance().getActionMappingName(action);

            if (servletMapping.startsWith("*."))
            {
                value.append(actionMapping);
                value.append(servletMapping.substring(1));
            }
            else if (servletMapping.endsWith("/*"))
            {
                value.append(servletMapping.substring
                             (0, servletMapping.length() - 2));
                value.append(actionMapping);
            }

            if (queryString != null)
            {
                value.append(queryString);
            }
        }
        else
        {
            /* Otherwise, assume extension mapping is in use and extension is
             * already included in the action property */
            if (!action.startsWith("/"))
            {
                value.append("/");
            }
            value.append(action);
        }

        /* Return the completed value */
        return value.toString();
    }


    /**
     * Returns the action forward name converted into a server-relative URI
     * reference.
     *
     * @param app the servlet context
     * @param request the servlet request
     * @param forward the name of a forward as per struts-config.xml
     */
    public static String getForwardURL(HttpServletRequest request,
                                       ServletContext app,
                                       String forward)
    {
        ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, app);
        //TODO? beware of null module config if ActionServlet isn't init'ed?

        ActionConfig actionConfig =
            (ActionConfig)request.getAttribute(Globals.MAPPING_KEY);

        // NOTE: ActionConfig.findForwardConfig only searches local forwards
        ForwardConfig fc = null;
        if(actionConfig != null)
        {
            fc = actionConfig.findForwardConfig(forward);

            // No ActionConfig forward?
            // Find the ForwardConfig in the global-forwards.
            if(fc == null)
            {
                fc = moduleConfig.findForwardConfig(forward);

                // ok, give up
                if (fc == null)
                {
                    return null;
                }
            }
        }

        StringBuffer url = new StringBuffer();
        if (fc.getPath().startsWith("/"))
        {
            url.append(request.getContextPath());
            url.append(RequestUtils.forwardURL(request, fc, moduleConfig));
        }
        else
        {
            url.append(fc.getPath());
        }
        return url.toString();
    }


    /**
     * Returns a formatted error message. The error message is assembled from
     * the following three pieces: First, value of message resource
     * "errors.header" is prepended. Then, the list of error messages is
     * rendered. Finally, the value of message resource "errors.footer"
     * is appended.
     *
     * @param property the category of errors to markup and return
     * @param request the servlet request
     * @param session the HTTP session
     * @param application the servlet context
     *
     * @return The formatted error message. If no error messages are queued,
     * an empty string is returned.
     */
    public static String errorMarkup(String property,
                                     HttpServletRequest request,
                                     HttpSession session,
                                     ServletContext application)
    {
        return errorMarkup(property, null, request, session, application);
    }


    /**
     * Returns a formatted error message. The error message is assembled from
     * the following three pieces: First, value of message resource
     * "errors.header" is prepended. Then, the list of error messages is
     * rendered. Finally, the value of message resource "errors.footer"
     * is appended.
     *
     * @param property the category of errors to markup and return
     * @param bundle the message resource bundle to use
     * @param request the servlet request
     * @param session the HTTP session
     * @param application the servlet context
     * @since VelocityTools 1.1
     * @return The formatted error message. If no error messages are queued,
     * an empty string is returned.
     */
    public static String errorMarkup(String property,
                                     String bundle,
                                     HttpServletRequest request,
                                     HttpSession session,
                                     ServletContext application)
    {
        ActionMessages errors = getErrors(request);
        if (errors == null)
        {
            return "";
        }

        /* fetch the error messages */
        Iterator reports = null;
        if (property == null)
        {
            reports = errors.get();
        }
        else
        {
            reports = errors.get(property);
        }

        if (!reports.hasNext())
        {
            return "";
        }

        /* Render the error messages appropriately if errors have been queued */
        StringBuffer results = new StringBuffer();
        String header = null;
        String footer = null;
        String prefix = null;
        String suffix = null;
        Locale locale = getLocale(request, session);

        MessageResources resources =
            getMessageResources(request, application, bundle);
        if (resources != null)
        {
            header = resources.getMessage(locale, "errors.header");
            footer = resources.getMessage(locale, "errors.footer");
            prefix = resources.getMessage(locale, "errors.prefix");
            suffix = resources.getMessage(locale, "errors.suffix");
        }
        if (header == null)
        {
            header = "errors.header";
        }
        if (footer == null)
        {
            footer = "errors.footer";
        }
        /* prefix or suffix are optional, be quiet if they're missing */
        if (prefix == null)
        {
            prefix = "";
        }
        if (suffix == null)
        {
            suffix = "";
        }

        results.append(header);
        results.append("\r\n");

        String message;
        while (reports.hasNext())
        {
            message = null;
            ActionMessage report = (ActionMessage)reports.next();
            if (resources != null && report.isResource())
            {
                message = resources.getMessage(locale,
                                               report.getKey(),
                                               report.getValues());
            }

            results.append(prefix);

            if (message != null)
            {
                results.append(message);
            }
            else
            {
                results.append(report.getKey());
            }

            results.append(suffix);
            results.append("\r\n");
        }

        results.append(footer);
        results.append("\r\n");

        /* return result */
        return results.toString();
    }

}
