All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.directwebremoting.webwork.DWRAction Maven / Gradle / Ivy

Go to download

DWR is easy Ajax for Java. It makes it simple to call Java code directly from Javascript. It gets rid of almost all the boiler plate code between the web browser and your Java code.

The newest version!
/*
 * Copyright 2006 Alexandru Popescu
 *
 * Licensed 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.
 */
package org.directwebremoting.webwork;

import java.io.UnsupportedEncodingException;
import java.util.Map;

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

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.directwebremoting.util.FakeHttpServletResponse;
import org.directwebremoting.util.LocalUtil;

import com.opensymphony.webwork.ServletActionContext;
import com.opensymphony.webwork.dispatcher.DispatcherUtils;
import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.ActionProxy;
import com.opensymphony.xwork.ActionProxyFactory;
import com.opensymphony.xwork.Result;
import com.opensymphony.xwork.config.ConfigurationException;
import com.opensymphony.xwork.util.OgnlValueStack;
import com.opensymphony.xwork.util.XWorkContinuationConfig;

/**
 * This class represents the entry point to all WebWork action invocations. It identifies the
 * action to be invoked, prepares the action invocation context and finally wraps the
 * result.
 * You can configure an IDWRActionProcessor through a context-wide initialization parameter
 * dwrActionProcessor that whose methods will be invoked around action invocation.
 *
 * @author Alexandru Popescu
 */
public class DWRAction
{
    /**
     * @param servletContext
     * @throws ServletException
     */
    private DWRAction(ServletContext servletContext) throws ServletException
    {
        DispatcherUtils.initialize(servletContext);
        wwDispatcher = DispatcherUtils.getInstance();
        actionProcessor = loadActionProcessor(servletContext.getInitParameter(DWRACTIONPROCESSOR_INIT_PARAM));
    }

    /**
     * 
     */
    protected AjaxResult doExecute(ActionDefinition actionDefinition, Map params, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) throws ServletException
    {
        FakeHttpServletResponse actionResponse = new FakeHttpServletResponse();

        if (null != actionProcessor)
        {
            actionProcessor.preProcess(request, response, actionResponse, params);
        }

        wwDispatcher.prepare(request, actionResponse);

        ActionInvocation invocation = invokeAction(wwDispatcher, request, actionResponse, servletContext, actionDefinition, params);

        AjaxResult result;
        if (actionDefinition.isExecuteResult())
        {
            // HINT: we have output string
            result = getTextResult(actionResponse);
        }
        else
        {
            result = new DefaultAjaxDataResult(invocation.getAction());
        }

        if (null != actionProcessor)
        {
            actionProcessor.postProcess(request, response, actionResponse, result);
        }

        return result;
    }

    /**
     * 
     */
    @SuppressWarnings("unchecked")
    protected ActionInvocation invokeAction(DispatcherUtils du, HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionDefinition actionDefinition, Map params) throws ServletException
    {
        ActionMapping mapping = getActionMapping(actionDefinition, params);
        Map extraContext = du.createContextMap(request, response, mapping, context);

        // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
        OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
        if (null != stack)
        {
            extraContext.put(ActionContext.VALUE_STACK, new OgnlValueStack(stack));
        }

        try
        {
            prepareContinuationAction(request, extraContext);

            ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(actionDefinition.getNamespace(), actionDefinition.getAction(), extraContext, actionDefinition.isExecuteResult(), false);
            proxy.setMethod(actionDefinition.getMethod());
            request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());

            // if the ActionMapping says to go straight to a result, do it!
            if (mapping.getResult() != null)
            {
                Result result = mapping.getResult();
                result.execute(proxy.getInvocation());
            }
            else
            {
                proxy.execute();
            }

            return proxy.getInvocation();
        }
        catch (ConfigurationException ce)
        {
            throw new ServletException("Cannot invoke action '" + actionDefinition.getAction() + "' in namespace '" + actionDefinition.getNamespace() + "'", ce);
        }
        catch (Exception e)
        {
            throw new ServletException("Cannot invoke action '" + actionDefinition.getAction() + "' in namespace '" + actionDefinition.getNamespace() + "'", e);
        }
        finally
        {
            // If there was a previous value stack then set it back onto the request
            if (null != stack)
            {
                request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, stack);
            }
        }
    }

    /**
     * 
     */
    @SuppressWarnings("unchecked")
    protected void prepareContinuationAction(HttpServletRequest request, Map extraContext)
    {
        String id = request.getParameter(XWorkContinuationConfig.CONTINUE_PARAM);
        if (null != id)
        {
            // remove the continue key from the params - we don't want to bother setting
            // on the value stack since we know it won't work. Besides, this breaks devMode!
            Map params = (Map) extraContext.get(ActionContext.PARAMETERS);
            params.remove(XWorkContinuationConfig.CONTINUE_PARAM);

            // and now put the key in the context to be picked up later by XWork
            extraContext.put(XWorkContinuationConfig.CONTINUE_KEY, id);
        }
    }

    /**
     * 
     */
    protected ActionMapping getActionMapping(ActionDefinition actionDefinition, Map params)
    {
        ActionMapping actionMapping = new ActionMapping(actionDefinition.getAction(), actionDefinition.getNamespace(), actionDefinition.getMethod(), params);
        return actionMapping;
    }

    /**
     * 
     */
    protected AjaxTextResult getTextResult(FakeHttpServletResponse response)
    {
        DefaultAjaxTextResult result = new DefaultAjaxTextResult();

        String text = null;
        try
        {
            text = response.getContentAsString();
        }
        catch (UnsupportedEncodingException uee)
        {
            log.warn("Cannot retrieve text output as string", uee);
        }

        if (null == text)
        {
            try
            {
                text = response.getCharacterEncoding() != null ? new String(response.getContentAsByteArray(), response.getCharacterEncoding()) : new String(response.getContentAsByteArray());
            }
            catch (UnsupportedEncodingException uee)
            {
                log.warn("Cannot retrieve text output as encoded byte array", uee);
                text = new String(response.getContentAsByteArray());
            }
        }

        result.setText(text);
        return result;
    }

    /**
     * Entry point for all action invocations.
     * @param actionDefinition the identification information for the action
     * @param params action invocation parameters
     * @param request original request
     * @param response original response
     * @param servletContext current ServletContext
     * @return an AjaxResult wrapping invocation result
     * @throws ServletException thrown if the initialization or invocation of the action fails
     */
    public static AjaxResult execute(ActionDefinition actionDefinition, Map params, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) throws ServletException
    {
        initialize(servletContext);

        return instance.doExecute(actionDefinition, params, request, response, servletContext);
    }

    /**
     * Performs the one time initialization of the singleton DWRAction.
     * @param servletContext
     * @throws ServletException thrown in case the singleton initialization fails
     */
    private static void initialize(ServletContext servletContext) throws ServletException
    {
        synchronized(DWRAction.class)
        {
            if (null == instance)
            {
                instance = new DWRAction(servletContext);
            }
        }
    }

    /**
     * Tries to instantiate an IDWRActionProcessor if defined in web.xml.
     * @param actionProcessorClassName
     * @return an instance of IDWRActionProcessor if the init-param is defined or null
     * @throws ServletException thrown if the IDWRActionProcessor cannot be loaded and instantiated
     */
    private static IDWRActionProcessor loadActionProcessor(String actionProcessorClassName) throws ServletException
    {
        if (null == actionProcessorClassName || "".equals(actionProcessorClassName))
        {
            return null;
        }

        IDWRActionProcessor reply = LocalUtil.classNewInstance("DWRActionProcessor", actionProcessorClassName, IDWRActionProcessor.class);
        if (reply == null)
        {
            throw new ServletException("Cannot load DWRActionProcessor class '" + actionProcessorClassName + "'");
        }

        return reply;
    }

    /**
     * The log stream
     */
    private static final Log log = LogFactory.getLog(DWRAction.class);

    private static final String DWRACTIONPROCESSOR_INIT_PARAM = "dwrActionProcessor";

    private static DWRAction instance;

    private DispatcherUtils wwDispatcher;

    private IDWRActionProcessor actionProcessor;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy