KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > webwork > DWRAction


1 package org.directwebremoting.webwork;
2
3 import java.io.UnsupportedEncodingException JavaDoc;
4 import java.util.Map JavaDoc;
5
6 import javax.servlet.ServletContext JavaDoc;
7 import javax.servlet.ServletException JavaDoc;
8 import javax.servlet.http.HttpServletRequest JavaDoc;
9 import javax.servlet.http.HttpServletResponse JavaDoc;
10
11 import org.directwebremoting.util.FakeHttpServletResponse;
12 import org.directwebremoting.util.LocalUtil;
13 import org.directwebremoting.util.Logger;
14
15 import com.opensymphony.webwork.ServletActionContext;
16 import com.opensymphony.webwork.dispatcher.DispatcherUtils;
17 import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
18 import com.opensymphony.xwork.ActionContext;
19 import com.opensymphony.xwork.ActionInvocation;
20 import com.opensymphony.xwork.ActionProxy;
21 import com.opensymphony.xwork.ActionProxyFactory;
22 import com.opensymphony.xwork.Result;
23 import com.opensymphony.xwork.config.ConfigurationException;
24 import com.opensymphony.xwork.util.OgnlValueStack;
25 import com.opensymphony.xwork.util.XWorkContinuationConfig;
26
27 /**
28  * This class represents the entry point to all WebWork action invocations. It identifies the
29  * action to be invoked, prepares the action invocation context and finally wraps the
30  * result.
31  * You can configure an <code>IDWRActionProcessor</code> through a context-wide initialization parameter
32  * <code>dwrActionProcessor</code> that whose methods will be invoked around action invocation.
33  *
34  * @author <a HREF='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
35  */

36 public class DWRAction
37 {
38     /**
39      * The log stream
40      */

41     private static final Logger log = Logger.getLogger(DWRAction.class);
42
43     private static final String JavaDoc DWRACTIONPROCESSOR_INIT_PARAM = "dwrActionProcessor";
44
45     private static DWRAction s_instance;
46
47     private DispatcherUtils m_wwDispatcher;
48
49     private IDWRActionProcessor m_actionProcessor;
50
51     private DWRAction(ServletContext JavaDoc servletContext) throws ServletException JavaDoc
52     {
53         DispatcherUtils.initialize(servletContext);
54         m_wwDispatcher = DispatcherUtils.getInstance();
55         m_actionProcessor = loadActionProcessor(servletContext.getInitParameter(DWRACTIONPROCESSOR_INIT_PARAM));
56     }
57
58     /**
59      * Entry point for all action invocations.
60      *
61      * @param actionDefinition the identification information for the action
62      * @param params action invocation parameters
63      * @param request original request
64      * @param response original response
65      * @param servletContext current <code>ServletContext</code>
66      * @return an <code>AjaxResult</code> wrapping invocation result
67      *
68      * @throws ServletException thrown if the initialization or invocation of the action fails
69      */

70     public static AjaxResult execute(ActionDefinition actionDefinition, Map JavaDoc params, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ServletContext JavaDoc servletContext) throws ServletException JavaDoc
71     {
72         initialize(servletContext);
73
74         return s_instance.doExecute(actionDefinition, params, request, response, servletContext);
75     }
76
77     protected AjaxResult doExecute(ActionDefinition actionDefinition, Map JavaDoc params, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ServletContext JavaDoc servletContext) throws ServletException JavaDoc
78     {
79
80         FakeHttpServletResponse actionResponse = new FakeHttpServletResponse();
81
82         if (null != m_actionProcessor)
83         {
84             m_actionProcessor.preProcess(request, response, actionResponse, params);
85         }
86
87         m_wwDispatcher.prepare(request, actionResponse);
88
89         ActionInvocation invocation = invokeAction(m_wwDispatcher, request, actionResponse, servletContext, actionDefinition, params);
90
91         AjaxResult result = null;
92         if (actionDefinition.isExecuteResult())
93         {
94             // HINT: we have output string
95
result = getTextResult(actionResponse);
96         }
97         else
98         {
99             result = new DefaultAjaxDataResult(invocation.getAction());
100         }
101
102         if (null != m_actionProcessor)
103         {
104             m_actionProcessor.postProcess(request, response, actionResponse, result);
105         }
106
107         return result;
108     }
109
110     protected ActionInvocation invokeAction(DispatcherUtils du, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ServletContext JavaDoc context, ActionDefinition actionDefinition, Map JavaDoc params) throws ServletException JavaDoc
111     {
112         ActionMapping mapping = getActionMapping(actionDefinition, params);
113         Map JavaDoc extraContext = du.createContextMap(request, response, mapping, context);
114
115         // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
116
OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
117         if (null != stack)
118         {
119             extraContext.put(ActionContext.VALUE_STACK, new OgnlValueStack(stack));
120         }
121
122         try
123         {
124             prepareContinuationAction(request, extraContext);
125
126             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(actionDefinition.getNamespace(), actionDefinition.getAction(), extraContext, actionDefinition.isExecuteResult(), false);
127             proxy.setMethod(actionDefinition.getMethod());
128             request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
129
130             // if the ActionMapping says to go straight to a result, do it!
131
if (mapping.getResult() != null)
132             {
133                 Result result = mapping.getResult();
134                 result.execute(proxy.getInvocation());
135             }
136             else
137             {
138                 proxy.execute();
139             }
140
141             return proxy.getInvocation();
142         }
143         catch (ConfigurationException ce)
144         {
145             throw new ServletException JavaDoc("Cannot invoke action '" + actionDefinition.getAction() + "' in namespace '" + actionDefinition.getNamespace() + "'", ce);
146         }
147         catch (Exception JavaDoc e)
148         {
149             throw new ServletException JavaDoc("Cannot invoke action '" + actionDefinition.getAction() + "' in namespace '" + actionDefinition.getNamespace() + "'", e);
150         }
151         finally
152         {
153             // If there was a previous value stack then set it back onto the request
154
if (null != stack)
155             {
156                 request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, stack);
157             }
158         }
159     }
160
161     protected void prepareContinuationAction(HttpServletRequest JavaDoc request, Map JavaDoc extraContext)
162     {
163         String JavaDoc id = request.getParameter(XWorkContinuationConfig.CONTINUE_PARAM);
164         if (null != id)
165         {
166             // remove the continue key from the params - we don't want to bother setting
167
// on the value stack since we know it won't work. Besides, this breaks devMode!
168
Map JavaDoc params = (Map JavaDoc) extraContext.get(ActionContext.PARAMETERS);
169             params.remove(XWorkContinuationConfig.CONTINUE_PARAM);
170
171             // and now put the key in the context to be picked up later by XWork
172
extraContext.put(XWorkContinuationConfig.CONTINUE_KEY, id);
173         }
174     }
175
176     protected ActionMapping getActionMapping(ActionDefinition actionDefinition, Map JavaDoc params)
177     {
178         ActionMapping actionMapping = new ActionMapping(actionDefinition.getAction(), actionDefinition.getNamespace(), actionDefinition.getMethod(), params);
179
180         return actionMapping;
181     }
182
183     protected AjaxTextResult getTextResult(FakeHttpServletResponse response)
184     {
185         DefaultAjaxTextResult result = new DefaultAjaxTextResult();
186
187         String JavaDoc text = null;
188         try
189         {
190             text = response.getContentAsString();
191         }
192         catch (UnsupportedEncodingException JavaDoc uee)
193         {
194             log.warn("Cannot retrieve text output as string", uee);
195         }
196
197         if (null == text)
198         {
199             try
200             {
201                 text = response.getCharacterEncoding() != null ? new String JavaDoc(response.getContentAsByteArray(), response.getCharacterEncoding()) : new String JavaDoc(response.getContentAsByteArray());
202             }
203             catch (UnsupportedEncodingException JavaDoc uee)
204             {
205                 log.warn("Cannot retrieve text output as encoded byte array", uee);
206                 text = new String JavaDoc(response.getContentAsByteArray());
207             }
208         }
209
210         result.setText(text);
211         return result;
212     }
213
214     /**
215      * Performs the one time initialization of the singleton <code>DWRAction</code>.
216      *
217      * @param servletContext
218      * @throws ServletException thrown in case the singleton initialization fails
219      */

220     private static void initialize(ServletContext JavaDoc servletContext) throws ServletException JavaDoc
221     {
222         synchronized(DWRAction.class)
223         {
224             if (null == s_instance)
225             {
226                 s_instance = new DWRAction(servletContext);
227             }
228         }
229     }
230
231     /**
232      * Tries to instantiate an <code>IDWRActionProcessor</code> if defined in web.xml.
233      *
234      * @param actionProcessorClassName
235      * @return an instance of <code>IDWRActionProcessor</code> if the init-param is defined or <code>null</code>
236      * @throws ServletException thrown if the <code>IDWRActionProcessor</code> cannot be loaded and instantiated
237      */

238     private static IDWRActionProcessor loadActionProcessor(String JavaDoc actionProcessorClassName) throws ServletException JavaDoc
239     {
240         if (null == actionProcessorClassName || "".equals(actionProcessorClassName))
241         {
242             return null;
243         }
244
245         try
246         {
247             Class JavaDoc actionProcessorClass = LocalUtil.classForName(actionProcessorClassName);
248
249             return (IDWRActionProcessor) actionProcessorClass.newInstance();
250         }
251         catch(ClassNotFoundException JavaDoc cnfe)
252         {
253             throw new ServletException JavaDoc("Cannot load DWRActionProcessor class '" + actionProcessorClassName + "'", cnfe);
254         }
255         catch(IllegalAccessException JavaDoc iae)
256         {
257             throw new ServletException JavaDoc("Cannot instantiate DWRActionProcessor class '" + actionProcessorClassName + "'. Default constructor is not visible", iae);
258         }
259         catch(InstantiationException JavaDoc ie)
260         {
261             throw new ServletException JavaDoc("Cannot instantiate DWRActionProcessor class '" + actionProcessorClassName + "'. No default constructor found", ie);
262         }
263         catch(Throwable JavaDoc cause)
264         {
265             throw new ServletException JavaDoc("Cannot instantiate DWRActionProcessor class '" + actionProcessorClassName + "'", cause);
266         }
267     }
268
269 }
270
Popular Tags