KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > webwork > dispatcher > DispatcherUtils


1 package com.opensymphony.webwork.dispatcher;
2
3 import com.opensymphony.util.ClassLoaderUtil;
4 import com.opensymphony.util.FileManager;
5 import com.opensymphony.webwork.ServletActionContext;
6 import com.opensymphony.webwork.WebWorkStatics;
7 import com.opensymphony.webwork.config.Configuration;
8 import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
9 import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequest;
10 import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper;
11 import com.opensymphony.webwork.dispatcher.multipart.WebWorkRequestWrapper;
12 import com.opensymphony.webwork.util.AttributeMap;
13 import com.opensymphony.xwork.ActionContext;
14 import com.opensymphony.xwork.ActionProxy;
15 import com.opensymphony.xwork.ActionProxyFactory;
16 import com.opensymphony.xwork.ObjectFactory;
17 import com.opensymphony.xwork.config.ConfigurationException;
18 import com.opensymphony.xwork.interceptor.component.ComponentInterceptor;
19 import com.opensymphony.xwork.interceptor.component.ComponentManager;
20 import com.opensymphony.xwork.util.LocalizedTextUtil;
21 import com.opensymphony.xwork.util.OgnlValueStack;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import javax.servlet.ServletContext JavaDoc;
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.http.HttpServletResponse JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Map JavaDoc;
33
34 /**
35  * User: patrick
36  * Date: Jun 24, 2005
37  * Time: 2:11:59 PM
38  */

39 public class DispatcherUtils {
40     private static final Log LOG = LogFactory.getLog(DispatcherUtils.class);
41
42     private static DispatcherUtils instance;
43
44     public static void initialize(ServletContext JavaDoc servletContext) {
45         synchronized (DispatcherUtils.class) {
46             if (instance == null) {
47                 instance = new DispatcherUtils(servletContext);
48             }
49         }
50     }
51
52     public static DispatcherUtils getInstance() {
53         return instance;
54     }
55
56     public static void setInstance(DispatcherUtils instance) {
57         DispatcherUtils.instance = instance;
58     }
59
60     // set from the webwork.i18n.encoding property in webwork.properties
61
protected String JavaDoc encoding = null;
62
63     // set from webwork.locale property in webwork.properties
64
protected Locale JavaDoc locale = null;
65
66     // used to get WebLogic to play nice
67
protected boolean paramsWorkaroundEnabled = false;
68
69     protected DispatcherUtils(ServletContext JavaDoc servletContext) {
70         boolean reloadi18n = Boolean.valueOf((String JavaDoc) Configuration.get("webwork.i18n.reload")).booleanValue();
71         LocalizedTextUtil.setReloadBundles(reloadi18n);
72
73         if (Configuration.isSet("webwork.objectFactory")) {
74             String JavaDoc className = (String JavaDoc) Configuration.get("webwork.objectFactory");
75             try {
76                 Class JavaDoc clazz = ClassLoaderUtil.loadClass(className, DispatcherUtils.class);
77                 ObjectFactory objectFactory = (ObjectFactory) clazz.newInstance();
78                 ObjectFactory.setObjectFactory(objectFactory);
79             } catch (Exception JavaDoc e) {
80                 LOG.error("Could not load ObjectFactory named " + className + ". Using default ObjectFactory.", e);
81             }
82         }
83
84         LocalizedTextUtil.addDefaultResourceBundle("com/opensymphony/webwork/webwork-messages");
85
86         //check for configuration reloading
87
if ("true".equalsIgnoreCase(Configuration.getString("webwork.configuration.xml.reload"))) {
88             FileManager.setReloadingConfigs(true);
89         }
90
91         if (Configuration.isSet("webwork.i18n.encoding")) {
92             encoding = Configuration.getString("webwork.i18n.encoding");
93         }
94
95         if (Configuration.isSet("webwork.locale")) {
96             locale = localeFromString(Configuration.getString("webwork.locale"));
97         }
98
99         // test wether param-access workaround needs to be enabled
100
if (servletContext.getServerInfo().indexOf("WebLogic") >= 0) {
101             LOG.info("WebLogic server detected. Enabling WebWork parameter access work-around.");
102             paramsWorkaroundEnabled = true;
103         } else if (Configuration.isSet("webwork.dispatcher.parametersWorkaround")) {
104             paramsWorkaroundEnabled = "true".equals(Configuration.get("webwork.dispatcher.parametersWorkaround"));
105         } else {
106             LOG.debug("Parameter access work-around disabled.");
107         }
108     }
109
110     /**
111      * Loads the action and executes it. This method first creates the action context from the given
112      * parameters then loads an <tt>ActionProxy</tt> from the given action name and namespace. After that,
113      * the action is executed and output channels throught the response object. Errors are also
114      * sent back to the user via the {@link DispatcherUtils#sendError} method.
115      *
116      * @param request the HttpServletRequest object
117      * @param response the HttpServletResponse object
118      * @param mapping the action mapping object
119      */

120     public void serviceAction(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ServletContext JavaDoc context, ActionMapping mapping) {
121         // request map wrapping the http request objects
122
Map requestMap = new RequestMap(request);
123
124         // parameters map wrapping the http paraneters.
125
Map params = mapping.getParams();
126         Map requestParams = new HashMap JavaDoc(request.getParameterMap());
127         if (params != null) {
128             params.putAll(requestParams);
129         } else {
130             params = requestParams;
131         }
132
133         // session map wrapping the http session
134
Map session = new SessionMap(request);
135
136         // application map wrapping the ServletContext
137
Map application = new ApplicationMap(context);
138
139         HashMap JavaDoc extraContext = createContextMap(requestMap, params, session, application, request, response, context);
140
141         // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
142
OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
143         if (stack != null) {
144             extraContext.put(ActionContext.VALUE_STACK, new OgnlValueStack(stack));
145         }
146         try {
147             String JavaDoc namespace = mapping.getNamespace();
148             String JavaDoc name = mapping.getName();
149             String JavaDoc method = mapping.getMethod();
150
151             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, name, extraContext);
152             proxy.setMethod(method);
153             request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
154             proxy.execute();
155             // If there was a previous value stack then set it back onto the request
156
if (stack != null) {
157                 request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, stack);
158             }
159         } catch (ConfigurationException e) {
160             LOG.error("Could not find action", e);
161             sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
162         } catch (Exception JavaDoc e) {
163             LOG.error("Could not execute action", e);
164             sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
165         }
166     }
167
168     /**
169      * Merges all application and servlet attributes into a single <tt>HashMap</tt> to represent the entire
170      * <tt>Action</tt> context.
171      *
172      * @param requestMap a Map of all request attributes.
173      * @param parameterMap a Map of all request parameters.
174      * @param sessionMap a Map of all session attributes.
175      * @param applicationMap a Map of all servlet context attributes.
176      * @param request the HttpServletRequest object.
177      * @param response the HttpServletResponse object.
178      * @param servletContext the ServletContext object.
179      * @return a HashMap representing the <tt>Action</tt> context.
180      */

181     public HashMap JavaDoc createContextMap(Map requestMap,
182                                     Map parameterMap,
183                                     Map sessionMap,
184                                     Map applicationMap,
185                                     HttpServletRequest JavaDoc request,
186                                     HttpServletResponse JavaDoc response,
187                                     ServletContext JavaDoc servletContext) {
188         HashMap JavaDoc extraContext = new HashMap JavaDoc();
189         extraContext.put(ActionContext.PARAMETERS, new HashMap JavaDoc(parameterMap));
190         extraContext.put(ActionContext.SESSION, sessionMap);
191         extraContext.put(ActionContext.APPLICATION, applicationMap);
192         extraContext.put(ActionContext.LOCALE, (locale == null) ? request.getLocale() : locale);
193
194         extraContext.put(WebWorkStatics.HTTP_REQUEST, request);
195         extraContext.put(WebWorkStatics.HTTP_RESPONSE, response);
196         extraContext.put(WebWorkStatics.SERVLET_CONTEXT, servletContext);
197         extraContext.put(ComponentInterceptor.COMPONENT_MANAGER, request.getAttribute(ComponentManager.COMPONENT_MANAGER_KEY));
198
199         // helpers to get access to request/session/application scope
200
extraContext.put("request", requestMap);
201         extraContext.put("session", sessionMap);
202         extraContext.put("application", applicationMap);
203         extraContext.put("parameters", parameterMap);
204
205         AttributeMap attrMap = new AttributeMap(extraContext);
206         extraContext.put("attr", attrMap);
207
208         return extraContext;
209     }
210
211     /**
212      * Builds a {@link java.util.Locale} from a String of the form en_US_foo into a Locale
213      * with language "en", country "US" and variant "foo". This will parse the output of
214      * {@link java.util.Locale#toString()}.
215      * todo move this to LocalizedTextUtil in xwork 1.0.6
216      */

217     public Locale JavaDoc localeFromString(String JavaDoc localeStr) {
218         if ((localeStr == null) || (localeStr.trim().length() == 0) || (localeStr.equals("_"))) {
219             return null;
220         }
221         int index = localeStr.indexOf('_');
222         if (index < 0) {
223             return new Locale JavaDoc(localeStr, "");
224         }
225         String JavaDoc language = localeStr.substring(0, index);
226         if (index == localeStr.length()) {
227             return new Locale JavaDoc(language, "");
228         }
229         localeStr = localeStr.substring(index + 1);
230         index = localeStr.indexOf('_');
231         if (index < 0) {
232             return new Locale JavaDoc(language, localeStr);
233         }
234         String JavaDoc country = localeStr.substring(0, index);
235         if (index == localeStr.length()) {
236             return new Locale JavaDoc(language, country);
237         }
238         localeStr = localeStr.substring(index + 1);
239         return new Locale JavaDoc(language, country, localeStr);
240     }
241
242     /**
243      * Returns the maximum upload size allowed for multipart requests (this is configurable).
244      *
245      * @return the maximum upload size allowed for multipart requests
246      */

247     public static int getMaxSize() {
248         Integer JavaDoc maxSize = new Integer JavaDoc(Integer.MAX_VALUE);
249         try {
250             String JavaDoc maxSizeStr = Configuration.getString("webwork.multipart.maxSize");
251
252             if (maxSizeStr != null) {
253                 try {
254                     maxSize = new Integer JavaDoc(maxSizeStr);
255                 } catch (NumberFormatException JavaDoc e) {
256                     LOG.warn("Unable to format 'webwork.multipart.maxSize' property setting. Defaulting to Integer.MAX_VALUE");
257                 }
258             } else {
259                 LOG.warn("Unable to format 'webwork.multipart.maxSize' property setting. Defaulting to Integer.MAX_VALUE");
260             }
261         } catch (IllegalArgumentException JavaDoc e1) {
262             LOG.warn("Unable to format 'webwork.multipart.maxSize' property setting. Defaulting to Integer.MAX_VALUE");
263         }
264
265         if (LOG.isDebugEnabled()) {
266             LOG.debug("maxSize=" + maxSize);
267         }
268
269         return maxSize.intValue();
270     }
271
272     /**
273      * Returns the path to save uploaded files to (this is configurable).
274      *
275      * @return the path to save uploaded files to
276      */

277     public String JavaDoc getSaveDir(ServletContext JavaDoc servletContext) {
278         String JavaDoc saveDir = Configuration.getString("webwork.multipart.saveDir").trim();
279
280         if (saveDir.equals("")) {
281             File JavaDoc tempdir = (File JavaDoc) servletContext.getAttribute("javax.servlet.context.tempdir");
282             LOG.info("Unable to find 'webwork.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");
283
284             if (tempdir != null) {
285                 saveDir = tempdir.toString();
286             }
287         } else {
288             File JavaDoc multipartSaveDir = new File JavaDoc(saveDir);
289
290             if (!multipartSaveDir.exists()) {
291                 multipartSaveDir.mkdir();
292             }
293         }
294
295         if (LOG.isDebugEnabled()) {
296             LOG.debug("saveDir=" + saveDir);
297         }
298
299         return saveDir;
300     }
301
302     public void prepare(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
303         if (encoding != null) {
304             try {
305                 request.setCharacterEncoding(encoding);
306             } catch (Exception JavaDoc e) {
307                 LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);
308             }
309         }
310
311         if (locale != null) {
312             response.setLocale(locale);
313         }
314
315         if (paramsWorkaroundEnabled) {
316             request.getParameter("foo"); // simply read any parameter (existing or not) to "prime" the request
317
}
318     }
319
320     /**
321      * Wraps and returns the given response or returns the original response object. This is used to transparently
322      * handle multipart data as a wrapped class around the given request. Override this method to handle multipart
323      * requests in a special way or to handle other types of requests. Note, {@link com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper} is
324      * flexible - you should look to that first before overriding this method to handle multipart data.
325      *
326      * @param request the HttpServletRequest object.
327      * @return a wrapped request or original request.
328      * @see com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper
329      */

330     public HttpServletRequest JavaDoc wrapRequest(HttpServletRequest JavaDoc request, ServletContext JavaDoc servletContext) throws IOException JavaDoc {
331         // don't wrap more than once
332
if (request instanceof WebWorkRequestWrapper) {
333             return request;
334         }
335
336         if (MultiPartRequest.isMultiPart(request)) {
337             request = new MultiPartRequestWrapper(request, getSaveDir(servletContext), getMaxSize());
338         } else {
339             request = new WebWorkRequestWrapper(request);
340         }
341
342         return request;
343     }
344
345     /**
346      * Sends an HTTP error response code.
347      *
348      * @param request the HttpServletRequest object.
349      * @param response the HttpServletResponse object.
350      * @param code the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible error codes).
351      * @param e the Exception that is reported.
352      */

353     public void sendError(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, int code, Exception JavaDoc e) {
354         try {
355             // send a http error response to use the servlet defined error handler
356
// make the exception availible to the web.xml defined error page
357
request.setAttribute("javax.servlet.error.exception", e);
358
359             // for compatibility
360
request.setAttribute("javax.servlet.jsp.jspException", e);
361
362             // send the error response
363
response.sendError(code, e.getMessage());
364         } catch (IOException JavaDoc e1) {
365         }
366     }
367 }
368
Popular Tags