Source code: org/apache/struts/util/RequestUtils.java
1 /*
2 * $Id: RequestUtils.java 76098 2004-11-17 07:07:32Z mrdon $
3 *
4 * Copyright 1999-2004 The Apache Software Foundation.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.struts.util;
20
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.util.Collections;
24 import java.util.Enumeration;
25 import java.util.HashMap;
26 import java.util.Hashtable;
27 import java.util.Locale;
28 import java.util.Map;
29
30 import javax.servlet.ServletContext;
31 import javax.servlet.ServletException;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpSession;
34 import javax.servlet.jsp.JspException;
35 import javax.servlet.jsp.PageContext;
36
37 import org.apache.commons.beanutils.BeanUtils;
38 import org.apache.commons.beanutils.DynaBean;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.struts.Globals;
42 import org.apache.struts.action.ActionErrors;
43 import org.apache.struts.action.ActionForm;
44 import org.apache.struts.action.ActionMapping;
45 import org.apache.struts.action.ActionMessages;
46 import org.apache.struts.action.ActionServlet;
47 import org.apache.struts.action.ActionServletWrapper;
48 import org.apache.struts.action.DynaActionForm;
49 import org.apache.struts.action.DynaActionFormClass;
50 import org.apache.struts.config.ActionConfig;
51 import org.apache.struts.config.FormBeanConfig;
52 import org.apache.struts.config.ForwardConfig;
53 import org.apache.struts.config.ModuleConfig;
54 import org.apache.struts.taglib.TagUtils;
55 import org.apache.struts.upload.MultipartRequestHandler;
56 import org.apache.struts.upload.MultipartRequestWrapper;
57
58 /**
59 * <p>General purpose utility methods related to processing a servlet request
60 * in the Struts controller framework.</p>
61 *
62 * @version $Rev: 76098 $ $Date: 2004-11-16 23:07:32 -0800 (Tue, 16 Nov 2004) $
63 */
64 public class RequestUtils {
65
66
67 // ------------------------------------------------------- Static Variables
68
69
70 /**
71 * <p>Commons Logging instance.</p>
72 */
73 protected static Log log = LogFactory.getLog(RequestUtils.class);
74
75
76 // --------------------------------------------------------- Public Methods
77
78
79 /**
80 * <p>Create and return an absolute URL for the specified context-relative
81 * path, based on the server and context information in the specified
82 * request.</p>
83 *
84 * @param request The servlet request we are processing
85 * @param path The context-relative path (must start with '/')
86 *
87 * @return absolute URL based on context-relative path
88 *
89 * @exception MalformedURLException if we cannot create an absolute URL
90 */
91 public static URL absoluteURL(HttpServletRequest request, String path)
92 throws MalformedURLException {
93
94 return (new URL(serverURL(request), request.getContextPath() + path));
95
96 }
97
98
99 /**
100 * <p>Return the <code>Class</code> object for the specified fully qualified
101 * class name, from this web application's class loader.</p>
102 *
103 * @param className Fully qualified class name to be loaded
104 * @return Class object
105 *
106 * @exception ClassNotFoundException if the class cannot be found
107 */
108 public static Class applicationClass(String className) throws ClassNotFoundException {
109
110 // Look up the class loader to be used
111 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
112 if (classLoader == null) {
113 classLoader = RequestUtils.class.getClassLoader();
114 }
115
116 // Attempt to load the specified class
117 return (classLoader.loadClass(className));
118
119 }
120
121
122 /**
123 * <p>Return a new instance of the specified fully qualified class name,
124 * after loading the class from this web application's class loader.
125 * The specified class <strong>MUST</strong> have a public zero-arguments
126 * constructor.</p>
127 *
128 * @param className Fully qualified class name to use
129 *
130 * @return new instance of class
131 * @exception ClassNotFoundException if the class cannot be found
132 * @exception IllegalAccessException if the class or its constructor
133 * is not accessible
134 * @exception InstantiationException if this class represents an
135 * abstract class, an interface, an array class, a primitive type,
136 * or void
137 * @exception InstantiationException if this class has no
138 * zero-arguments constructor
139 */
140 public static Object applicationInstance(String className)
141 throws ClassNotFoundException, IllegalAccessException, InstantiationException {
142
143 return (applicationClass(className).newInstance());
144
145 }
146
147 /**
148 * <p>Create (if necessary) and return an <code>ActionForm</code> instance appropriate
149 * for this request. If no <code>ActionForm</code> instance is required, return
150 * <code>null</code>.</p>
151 *
152 * @param request The servlet request we are processing
153 * @param mapping The action mapping for this request
154 * @param moduleConfig The configuration for this module
155 * @param servlet The action servlet
156 *
157 * @return ActionForm instance associated with this request
158 */
159 public static ActionForm createActionForm(
160 HttpServletRequest request,
161 ActionMapping mapping,
162 ModuleConfig moduleConfig,
163 ActionServlet servlet) {
164
165 // Is there a form bean associated with this mapping?
166 String attribute = mapping.getAttribute();
167 if (attribute == null) {
168 return (null);
169 }
170
171 // Look up the form bean configuration information to use
172 String name = mapping.getName();
173 FormBeanConfig config = moduleConfig.findFormBeanConfig(name);
174 if (config == null) {
175 log.warn("No FormBeanConfig found under '" + name + "'");
176 return (null);
177 }
178
179 ActionForm instance = lookupActionForm(request, attribute, mapping.getScope());
180
181 // Can we recycle the existing form bean instance (if there is one)?
182 try {
183 if (instance != null && canReuseActionForm(instance, config)) {
184 return (instance);
185 }
186 } catch(ClassNotFoundException e) {
187 log.error(servlet.getInternal().getMessage("formBean", config.getType()), e);
188 return (null);
189 }
190
191 return createActionForm(config, servlet);
192 }
193
194
195
196 private static ActionForm lookupActionForm(HttpServletRequest request, String attribute, String scope)
197 {
198 // Look up any existing form bean instance
199 if (log.isDebugEnabled()) {
200 log.debug(
201 " Looking for ActionForm bean instance in scope '"
202 + scope
203 + "' under attribute key '"
204 + attribute
205 + "'");
206 }
207 ActionForm instance = null;
208 HttpSession session = null;
209 if ("request".equals(scope)) {
210 instance = (ActionForm) request.getAttribute(attribute);
211 } else {
212 session = request.getSession();
213 instance = (ActionForm) session.getAttribute(attribute);
214 }
215
216 return (instance);
217 }
218
219 /**
220 * <p>Determine whether <code>instance</code> of <code>ActionForm</code> is
221 * suitable for re-use as an instance of the form described by
222 * <code>config</code>.</p>
223 * @param instance an instance of <code>ActionForm</code> which was found,
224 * probably in either request or session scope.
225 * @param config the configuration for the ActionForm which is needed.
226 * @return true if the instance found is "compatible" with the type required
227 * in the <code>FormBeanConfig</code>; false if not, or if <code>instance</code>
228 * is null.
229 * @throws ClassNotFoundException if the <code>type</code> property of
230 * <code>config</code> is not a valid Class name.
231 */
232 private static boolean canReuseActionForm(ActionForm instance, FormBeanConfig config)
233 throws ClassNotFoundException
234 {
235 if (instance == null) {
236 return (false);
237 }
238
239 boolean canReuse = false;
240 String formType = null;
241 String className = null;
242
243 if (config.getDynamic()) {
244 className = ((DynaBean) instance).getDynaClass().getName();
245 canReuse = className.equals(config.getName());
246 formType = "DynaActionForm";
247 } else {
248 Class configClass = applicationClass(config.getType());
249 className = instance.getClass().getName();
250 canReuse = configClass.isAssignableFrom(instance.getClass());
251 formType = "ActionForm";
252 }
253
254 if (log.isDebugEnabled()) {
255 log.debug(
256 " Can recycle existing "
257 + formType
258 + " instance "
259 + "of type '"
260 + className
261 + "'?: "
262 + canReuse);
263 log.trace(" --> " + instance);
264 }
265 return (canReuse);
266 }
267
268 /**
269 * <p>Create and return an <code>ActionForm</code> instance appropriate
270 * to the information in <code>config</code>.</p>
271 *
272 * <p>Does not perform any checks to see if an existing ActionForm exists
273 * which could be reused.</p>
274 *
275 * @param config The configuration for the Form bean which is to be created.
276 * @param servlet The action servlet
277 *
278 * @return ActionForm instance associated with this request
279 */
280 public static ActionForm createActionForm(FormBeanConfig config, ActionServlet servlet)
281 {
282 if (config == null)
283 {
284 return (null);
285 }
286
287 ActionForm instance = null;
288
289 // Create and return a new form bean instance
290 try {
291
292 instance = config.createActionForm(servlet);
293 if (log.isDebugEnabled()) {
294 log.debug(
295 " Creating new "
296 + (config.getDynamic() ? "DynaActionForm" : "ActionForm")
297 + " instance of type '"
298 + config.getType()
299 + "'");
300 log.trace(" --> " + instance);
301 }
302
303 } catch(Throwable t) {
304 log.error(servlet.getInternal().getMessage("formBean", config.getType()), t);
305 }
306
307 return (instance);
308
309 }
310
311
312 /**
313 * <p>Look up and return current user locale, based on the specified parameters.</p>
314 *
315 * @param request The request used to lookup the Locale
316 * @param locale Name of the session attribute for our user's Locale. If this is
317 * <code>null</code>, the default locale key is used for the lookup.
318 * @return current user locale
319 * @since Struts 1.2
320 */
321 public static Locale getUserLocale(HttpServletRequest request, String locale) {
322
323 Locale userLocale = null;
324 HttpSession session = request.getSession(false);
325
326 if (locale == null) {
327 locale = Globals.LOCALE_KEY;
328 }
329
330 // Only check session if sessions are enabled
331 if (session != null) {
332 userLocale = (Locale) session.getAttribute(locale);
333 }
334
335 if (userLocale == null) {
336 // Returns Locale based on Accept-Language header or the server default
337 userLocale = request.getLocale();
338 }
339
340 return userLocale;
341
342 }
343
344
345 /**
346 * <p>Populate the properties of the specified JavaBean from the specified
347 * HTTP request, based on matching each parameter name against the
348 * corresponding JavaBeans "property setter" methods in the bean's class.
349 * Suitable conversion is done for argument types as described under
350 * <code>convert()</code>.</p>
351 *
352 * @param bean The JavaBean whose properties are to be set
353 * @param request The HTTP request whose parameters are to be used
354 * to populate bean properties
355 *
356 * @exception ServletException if an exception is thrown while setting
357 * property values
358 */
359 public static void populate(Object bean, HttpServletRequest request) throws ServletException {
360
361 populate(bean, null, null, request);
362
363 }
364
365
366 /**
367 * <p>Populate the properties of the specified JavaBean from the specified
368 * HTTP request, based on matching each parameter name (plus an optional
369 * prefix and/or suffix) against the corresponding JavaBeans "property
370 * setter" methods in the bean's class. Suitable conversion is done for
371 * argument types as described under <code>setProperties</code>.</p>
372 *
373 * <p>If you specify a non-null <code>prefix</code> and a non-null
374 * <code>suffix</code>, the parameter name must match <strong>both</strong>
375 * conditions for its value(s) to be used in populating bean properties.
376 * If the request's content type is "multipart/form-data" and the
377 * method is "POST", the <code>HttpServletRequest</code> object will be wrapped in
378 * a <code>MultipartRequestWrapper</code object.</p>
379 *
380 * @param bean The JavaBean whose properties are to be set
381 * @param prefix The prefix (if any) to be prepend to bean property
382 * names when looking for matching parameters
383 * @param suffix The suffix (if any) to be appended to bean property
384 * names when looking for matching parameters
385 * @param request The HTTP request whose parameters are to be used
386 * to populate bean properties
387 *
388 * @exception ServletException if an exception is thrown while setting
389 * property values
390 */
391 public static void populate(
392 Object bean,
393 String prefix,
394 String suffix,
395 HttpServletRequest request)
396 throws ServletException {
397
398 // Build a list of relevant request parameters from this request
399 HashMap properties = new HashMap();
400 // Iterator of parameter names
401 Enumeration names = null;
402 // Map for multipart parameters
403 Map multipartParameters = null;
404
405 String contentType = request.getContentType();
406 String method = request.getMethod();
407 boolean isMultipart = false;
408
409 if ((contentType != null)
410 && (contentType.startsWith("multipart/form-data"))
411 && (method.equalsIgnoreCase("POST"))) {
412
413 // Get the ActionServletWrapper from the form bean
414 ActionServletWrapper servlet;
415 if (bean instanceof ActionForm) {
416 servlet = ((ActionForm) bean).getServletWrapper();
417 } else {
418 throw new ServletException(
419 "bean that's supposed to be "
420 + "populated from a multipart request is not of type "
421 + "\"org.apache.struts.action.ActionForm\", but type "
422 + "\""
423 + bean.getClass().getName()
424 + "\"");
425 }
426
427 // Obtain a MultipartRequestHandler
428 MultipartRequestHandler multipartHandler = getMultipartHandler(request);
429
430 // Set the multipart request handler for our ActionForm.
431 // If the bean isn't an ActionForm, an exception would have been
432 // thrown earlier, so it's safe to assume that our bean is
433 // in fact an ActionForm.
434 ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
435
436 if (multipartHandler != null) {
437 isMultipart = true;
438 // Set servlet and mapping info
439 servlet.setServletFor(multipartHandler);
440 multipartHandler.setMapping(
441 (ActionMapping) request.getAttribute(Globals.MAPPING_KEY));
442 // Initialize multipart request class handler
443 multipartHandler.handleRequest(request);
444 //stop here if the maximum length has been exceeded
445 Boolean maxLengthExceeded =
446 (Boolean) request.getAttribute(
447 MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);
448 if ((maxLengthExceeded != null) && (maxLengthExceeded.booleanValue())) {
449 return;
450 }
451 //retrieve form values and put into properties
452 multipartParameters = getAllParametersForMultipartRequest(
453 request, multipartHandler);
454 names = Collections.enumeration(multipartParameters.keySet());
455 }
456 }
457
458 if (!isMultipart) {
459 names = request.getParameterNames();
460 }
461
462 while (names.hasMoreElements()) {
463 String name = (String) names.nextElement();
464 String stripped = name;
465 if (prefix != null) {
466 if (!stripped.startsWith(prefix)) {
467 continue;
468 }
469 stripped = stripped.substring(prefix.length());
470 }
471 if (suffix != null) {
472 if (!stripped.endsWith(suffix)) {
473 continue;
474 }
475 stripped = stripped.substring(0, stripped.length() - suffix.length());
476 }
477 Object parameterValue = null;
478 if (isMultipart) {
479 parameterValue = multipartParameters.get(name);
480 } else {
481 parameterValue = request.getParameterValues(name);
482 }
483
484 // Populate parameters, except "standard" struts attributes
485 // such as 'org.apache.struts.action.CANCEL'
486 if (!(stripped.startsWith("org.apache.struts."))) {
487 properties.put(stripped, parameterValue);
488 }
489 }
490
491 // Set the corresponding properties of our bean
492 try {
493 BeanUtils.populate(bean, properties);
494 } catch(Exception e) {
495 throw new ServletException("BeanUtils.populate", e);
496 }
497
498 }
499
500
501 /**
502 * <p>Try to locate a multipart request handler for this request. First, look
503 * for a mapping-specific handler stored for us under an attribute. If one
504 * is not present, use the global multipart handler, if there is one.</p>
505 *
506 * @param request The HTTP request for which the multipart handler should
507 * be found.
508 * @return the multipart handler to use, or null if none is
509 * found.
510 *
511 * @exception ServletException if any exception is thrown while attempting
512 * to locate the multipart handler.
513 */
514 private static MultipartRequestHandler getMultipartHandler(HttpServletRequest request)
515 throws ServletException {
516
517 MultipartRequestHandler multipartHandler = null;
518 String multipartClass = (String) request.getAttribute(Globals.MULTIPART_KEY);
519 request.removeAttribute(Globals.MULTIPART_KEY);
520
521 // Try to initialize the mapping specific request handler
522 if (multipartClass != null) {
523 try {
524 multipartHandler = (MultipartRequestHandler) applicationInstance(multipartClass);
525 } catch(ClassNotFoundException cnfe) {
526 log.error(
527 "MultipartRequestHandler class \""
528 + multipartClass
529 + "\" in mapping class not found, "
530 + "defaulting to global multipart class");
531 } catch(InstantiationException ie) {
532 log.error(
533 "InstantiationException when instantiating "
534 + "MultipartRequestHandler \""
535 + multipartClass
536 + "\", "
537 + "defaulting to global multipart class, exception: "
538 + ie.getMessage());
539 } catch(IllegalAccessException iae) {
540 log.error(
541 "IllegalAccessException when instantiating "
542 + "MultipartRequestHandler \""
543 + multipartClass
544 + "\", "
545 + "defaulting to global multipart class, exception: "
546 + iae.getMessage());
547 }
548
549 if (multipartHandler != null) {
550 return multipartHandler;
551 }
552 }
553
554 ModuleConfig moduleConfig =
555 ModuleUtils.getInstance().getModuleConfig(request);
556
557 multipartClass = moduleConfig.getControllerConfig().getMultipartClass();
558
559 // Try to initialize the global request handler
560 if (multipartClass != null) {
561 try {
562 multipartHandler = (MultipartRequestHandler) applicationInstance(multipartClass);
563
564 } catch(ClassNotFoundException cnfe) {
565 throw new ServletException(
566 "Cannot find multipart class \""
567 + multipartClass
568 + "\""
569 + ", exception: "
570 + cnfe.getMessage());
571
572 } catch(InstantiationException ie) {
573 throw new ServletException(
574 "InstantiationException when instantiating "
575 + "multipart class \""
576 + multipartClass
577 + "\", exception: "
578 + ie.getMessage());
579
580 } catch(IllegalAccessException iae) {
581 throw new ServletException(
582 "IllegalAccessException when instantiating "
583 + "multipart class \""
584 + multipartClass
585 + "\", exception: "
586 + iae.getMessage());
587 }
588
589 if (multipartHandler != null) {
590 return multipartHandler;
591 }
592 }
593
594 return multipartHandler;
595 }
596
597
598 /**
599 *<p>Create a <code>Map</code> containing all of the parameters supplied for a multipart
600 * request, keyed by parameter name. In addition to text and file elements
601 * from the multipart body, query string parameters are included as well.</p>
602 *
603 * @param request The (wrapped) HTTP request whose parameters are to be
604 * added to the map.
605 * @param multipartHandler The multipart handler used to parse the request.
606 *
607 * @return the map containing all parameters for this multipart request.
608 */
609 private static Map getAllParametersForMultipartRequest(
610 HttpServletRequest request,
611 MultipartRequestHandler multipartHandler) {
612
613 Map parameters = new HashMap();
614 Hashtable elements = multipartHandler.getAllElements();
615 Enumeration e = elements.keys();
616 while (e.hasMoreElements()) {
617 String key = (String) e.nextElement();
618 parameters.put(key, elements.get(key));
619 }
620
621 if (request instanceof MultipartRequestWrapper) {
622 request = ((MultipartRequestWrapper) request).getRequest();
623 e = request.getParameterNames();
624 while (e.hasMoreElements()) {
625 String key = (String) e.nextElement();
626 parameters.put(key, request.getParameterValues(key));
627 }
628 } else {
629 log.debug("Gathering multipart parameters for unwrapped request");
630 }
631
632 return parameters;
633 }
634
635
636 /**
637 * <p>Compute the printable representation of a URL, leaving off the
638 * scheme/host/port part if no host is specified. This will typically
639 * be the case for URLs that were originally created from relative
640 * or context-relative URIs.</p>
641 *
642 * @param url URL to render in a printable representation
643 * @return printable representation of a URL
644 */
645 public static String printableURL(URL url) {
646
647 if (url.getHost() != null) {
648 return (url.toString());
649 }
650
651 String file = url.getFile();
652 String ref = url.getRef();
653 if (ref == null) {
654 return (file);
655 } else {
656 StringBuffer sb = new StringBuffer(file);
657 sb.append('#');
658 sb.append(ref);
659 return (sb.toString());
660 }
661
662 }
663
664
665 /**
666 * <p>Return the context-relative URL that corresponds to the specified
667 * {@link ActionConfig}, relative to the module associated
668 * with the current modules's {@link ModuleConfig}.</p>
669 *
670 * @param request The servlet request we are processing
671 * @param action ActionConfig to be evaluated
672 * @param pattern URL pattern used to map the controller servlet
673
674 * @return context-relative URL relative to the module
675 *
676 * @since Struts 1.1
677 */
678 public static String actionURL(
679 HttpServletRequest request,
680 ActionConfig action,
681 String pattern) {
682
683 StringBuffer sb = new StringBuffer();
684 if (pattern.endsWith("/*")) {
685 sb.append(pattern.substring(0, pattern.length() - 2));
686 sb.append(action.getPath());
687
688 } else if (pattern.startsWith("*.")) {
689 ModuleConfig appConfig =
690 ModuleUtils.getInstance().getModuleConfig(request);
691 sb.append(appConfig.getPrefix());
692 sb.append(action.getPath());
693 sb.append(pattern.substring(1));
694
695 } else {
696 throw new IllegalArgumentException(pattern);
697 }
698
699 return sb.toString();
700
701 }
702 /**
703 * <p>Return the context-relative URL that corresponds to the specified
704 * <code>ForwardConfig</code>. The URL is calculated based on the properties
705 * of the {@link ForwardConfig} instance as follows:</p>
706 * <ul>
707 * <li>If the <code>contextRelative</code> property is set, it is
708 * assumed that the <code>path</code> property contains a path
709 * that is already context-relative:
710 * <ul>
711 * <li>If the <code>path</code> property value starts with a slash,
712 * it is returned unmodified.</li>
713 * <li>If the <code>path</code> property value does not start
714 * with a slash, a slash is prepended.</li>
715 * </ul></li>
716 * <li>Acquire the <code>forwardPattern</code> property from the
717 * <code>ControllerConfig</code> for the application module used
718 * to process this request. If no pattern was configured, default
719 * to a pattern of <code>$M$P</code>, which is compatible with the
720 * hard-coded mapping behavior in Struts 1.0.</li>
721 * <li>Process the acquired <code>forwardPattern</code>, performing the
722 * following substitutions:
723 * <ul>
724 * <li><strong>$M</strong> - Replaced by the module prefix for the
725 * application module processing this request.</li>
726 * <li><strong>$P</strong> - Replaced by the <code>path</code>
727 * property of the specified {@link ForwardConfig}, prepended
728 * with a slash if it does not start with one.</li>
729 * <li><strong>$$</strong> - Replaced by a single dollar sign
730 * character.</li>
731 * <li><strong>$x</strong> (where "x" is any charater not listed
732 * above) - Silently omit these two characters from the result
733 * value. (This has the side effect of causing all other
734 * $+letter combinations to be reserved.)</li>
735 * </ul></li>
736 * </ul>
737 *
738 * @param request The servlet request we are processing
739 * @param forward ForwardConfig to be evaluated
740 *
741 * @return context-relative URL
742 * @since Struts 1.1
743 */
744 public static String forwardURL(HttpServletRequest request, ForwardConfig forward) {
745 return forwardURL(request,forward,null);
746 }
747
748 /**
749 * <p>Return the context-relative URL that corresponds to the specified
750 * <code>ForwardConfig</code>. The URL is calculated based on the properties
751 * of the {@link ForwardConfig} instance as follows:</p>
752 * <ul>
753 * <li>If the <code>contextRelative</code> property is set, it is
754 * assumed that the <code>path</code> property contains a path
755 * that is already context-relative:
756 * <ul>
757 * <li>If the <code>path</code> property value starts with a slash,
758 * it is returned unmodified.</li>
759 * <li>If the <code>path</code> property value does not start
760 * with a slash, a slash is prepended.</li>
761 * </ul></li>
762 * <li>Acquire the <code>forwardPattern</code> property from the
763 * <code>ControllerConfig</code> for the application module used
764 * to process this request. If no pattern was configured, default
765 * to a pattern of <code>$M$P</code>, which is compatible with the
766 * hard-coded mapping behavior in Struts 1.0.</li>
767 * <li>Process the acquired <code>forwardPattern</code>, performing the
768 * following substitutions:
769 * <ul>
770 * <li><strong>$M</strong> - Replaced by the module prefix for the
771 * application module processing this request.</li>
772 * <li><strong>$P</strong> - Replaced by the <code>path</code>
773 * property of the specified {@link ForwardConfig}, prepended
774 * with a slash if it does not start with one.</li>
775 * <li><strong>$$</strong> - Replaced by a single dollar sign
776 * character.</li>
777 * <li><strong>$x</strong> (where "x" is any charater not listed
778 * above) - Silently omit these two characters from the result
779 * value. (This has the side effect of causing all other
780 * $+letter combinations to be reserved.)</li>
781 * </ul></li>
782 * </ul>
783 *
784 * @param request The servlet request we are processing
785 * @param forward ForwardConfig to be evaluated
786 * @param moduleConfig Base forward on this module config.
787 *
788 * @return context-relative URL
789 * @since Struts 1.2
790 */
791 public static String forwardURL(HttpServletRequest request, ForwardConfig forward, ModuleConfig moduleConfig) {
792 //load the current moduleConfig, if null
793 if(moduleConfig == null) {
794 moduleConfig = ModuleUtils.getInstance().getModuleConfig(request);
795 }
796
797 String path = forward.getPath();
798 //load default prefix
799 String prefix = moduleConfig.getPrefix();
800
801 //override prefix if supplied by forward
802 if(forward.getModule() != null) {
803 prefix = forward.getModule();
804 if ("/".equals(prefix)) {
805 prefix = "";
806 }
807 }
808
809 // Handle a ForwardConfig marked as context relative
810 StringBuffer sb = new StringBuffer();
811 if (forward.getContextRelative()) {
812 if (!path.startsWith("/")) {
813 sb.append("/");
814 }
815 sb.append(path);
816 return (sb.toString());
817 }
818
819 // Calculate a context relative path for this ForwardConfig
820 String forwardPattern = moduleConfig.getControllerConfig().getForwardPattern();
821 if (forwardPattern == null) {
822 // Performance optimization for previous default behavior
823 sb.append(prefix);
824 // smoothly insert a '/' if needed
825 if (!path.startsWith("/")) {
826 sb.append("/");
827 }
828 sb.append(path);
829
830 } else {
831 boolean dollar = false;
832 for (int i = 0; i < forwardPattern.length(); i++) {
833 char ch = forwardPattern.charAt(i);
834 if (dollar) {
835 switch (ch) {
836 case 'M':
837 sb.append(prefix);
838 break;
839 case 'P':
840 // add '/' if needed
841 if (!path.startsWith("/")) {
842 sb.append("/");
843 }
844 sb.append(path);
845 break;
846 case '$':
847 sb.append('$');
848 break;
849 default :
850 ; // Silently swallow
851 }
852 dollar = false;
853 continue;
854 } else if (ch == '$') {
855 dollar = true;
856 } else {
857 sb.append(ch);
858 }
859 }
860 }
861
862 return (sb.toString());
863
864 }
865
866
867 /**
868 * <p>Return the URL representing the current request. This is equivalent
869 * to <code>HttpServletRequest.getRequestURL</code> in Servlet 2.3.</p>
870 *
871 * @param request The servlet request we are processing
872
873 * @return URL representing the current request
874 * @exception MalformedURLException if a URL cannot be created
875 */
876 public static URL requestURL(HttpServletRequest request) throws MalformedURLException {
877
878 StringBuffer url = requestToServerUriStringBuffer(request);
879 return (new URL(url.toString()));
880
881 }
882
883
884 /**
885 * <p>Return the URL representing the scheme, server, and port number of
886 * the current request. Server-relative URLs can be created by simply
887 * appending the server-relative path (starting with '/') to this.</p>
888 *
889 * @param request The servlet request we are processing
890 *
891 * @return URL representing the scheme, server, and port number of
892 * the current request
893 * @exception MalformedURLException if a URL cannot be created
894 */
895 public static URL serverURL(HttpServletRequest request) throws MalformedURLException {
896
897 StringBuffer url = requestToServerStringBuffer(request);
898 return (new URL(url.toString()));
899
900 }
901
902
903 /**
904 * <p>Return the string representing the scheme, server, and port number of
905 * the current request. Server-relative URLs can be created by simply
906 * appending the server-relative path (starting with '/') to this.</p>
907 *
908 * @param request The servlet request we are processing
909
910 * @return URL representing the scheme, server, and port number of
911 * the current request
912 * @since Struts 1.2.0
913 */
914 public static StringBuffer requestToServerUriStringBuffer(HttpServletRequest request) {
915
916 StringBuffer serverUri = createServerUriStringBuffer(request.getScheme(),request.getServerName(),
917 request.getServerPort(),request.getRequestURI());
918 return serverUri;
919
920 }
921
922 /**
923 * <p>Return <code>StringBuffer</code> representing the scheme, server, and port number of
924 * the current request. Server-relative URLs can be created by simply
925 * appending the server-relative path (starting with '/') to this.</p>
926 *
927 * @param request The servlet request we are processing
928 *
929 * @return URL representing the scheme, server, and port number of
930 * the current request
931 * @since Struts 1.2.0
932 */
933 public static StringBuffer requestToServerStringBuffer(HttpServletRequest request) {
934
935 return createServerStringBuffer(request.getScheme(),request.getServerName(),request.getServerPort());
936
937 }
938
939
940 /**
941 * <p>Return <code>StringBuffer</code> representing the scheme, server, and port number of
942 * the current request.</p>
943 *
944 * @param scheme The scheme name to use
945 * @param server The server name to use
946 * @param port The port value to use
947 *
948 * @return StringBuffer in the form scheme: server: port
949 * @since Struts 1.2.0
950 */
951 public static StringBuffer createServerStringBuffer(String scheme,String server,int port) {
952
953 StringBuffer url = new StringBuffer();
954 if (port < 0) {
955 port = 80; // Work around java.net.URL bug
956 }
957 url.append(scheme);
958 url.append("://");
959 url.append(server);
960 if ((scheme.equals("http") && (port != 80)) || (scheme.equals("https") && (port != 443))) {
961 url.append(':');
962 url.append(port);
963 }
964 return url;
965
966 }
967
968
969 /**
970 * <p>Return <code>StringBuffer</code> representing the scheme, server, and port number of
971 * the current request.</p>
972 *
973 * @param scheme The scheme name to use
974 * @param server The server name to use
975 * @param port The port value to use
976 * @param uri The uri value to use
977 *
978 * @return StringBuffer in the form scheme: server: port
979 * @since Struts 1.2.0
980 */
981 public static StringBuffer createServerUriStringBuffer(String scheme,String server,int port,String uri) {
982
983 StringBuffer serverUri = createServerStringBuffer(scheme,server,port);
984 serverUri.append(uri);
985 return serverUri;
986
987 }
988
989
990 // ------------------------------------- Deprecated in favor of ModuleUtils
991
992
993
994 /**
995 * <p>Select the module to which the specified request belongs, and
996 * add corresponding request attributes to this request.</p>
997 *
998 * @param prefix The module prefix of the desired module
999 * @param request The servlet request we are processing
1000 * @param context The ServletContext for this web application
1001 *
1002 * @since Struts 1.1
1003 * @deprecated Use {@link org.apache.struts.util.ModuleUtils#selectModule(String,HttpServletRequest,ServletContext)} instead.
1004 * This will be removed after Struts 1.2.
1005 */
1006 public static void selectModule(
1007 String prefix,
1008 HttpServletRequest request,
1009 ServletContext context) {
1010 // :TODO: Remove after Struts 1.2
1011
1012 ModuleUtils.getInstance().selectModule(prefix, request, context);
1013
1014 }
1015
1016
1017 /**
1018 * <p>Select the module to which the specified request belongs, and
1019 * add corresponding request attributes to this request.</p>
1020 *
1021 * @param request The servlet request we are processing
1022 * @param context The ServletContext for this web application
1023 *
1024 * @deprecated Use {@link org.apache.struts.util.ModuleUtils#selectModule(HttpServletRequest,ServletContext)} instead.
1025 * This will be removed after Struts 1.2.
1026 */
1027 public static void selectModule(HttpServletRequest request, ServletContext context) {
1028 // :TODO: Remove after Struts 1.2
1029
1030 ModuleUtils.getInstance().selectModule(request, context);
1031
1032 }
1033
1034
1035 /**
1036 * Get the module name to which the specified request belong.
1037 * @param request The servlet request we are processing
1038 * @param context The ServletContext for this web application
1039 * @return The module prefix or ""
1040 * @deprecated Use Use {@link org.apache.struts.util.ModuleUtils#getModuleName(HttpServletRequest,ServletContext)} instead.
1041 * This will be removed after Struts 1.2.
1042 */
1043 public static String getModuleName(HttpServletRequest request, ServletContext context) {
1044 // :TODO: Remove after Struts 1.2
1045
1046 return ModuleUtils.getInstance().getModuleName(request, context);
1047
1048 }
1049
1050
1051 /**
1052 * <p>Get the module name to which the specified uri belong.</p>
1053 *
1054 * @param matchPath The uri from which we want the module name.
1055 * @param context The ServletContext for this web application
1056 *
1057 * @return The module prefix or ""
1058 * @deprecated Use {@link org.apache.struts.util.ModuleUtils#getModuleName(String,ServletContext)} instead.
1059 * This will be removed after Struts 1.2.
1060 */
1061 public static String getModuleName(String matchPath, ServletContext context) {
1062 // :TODO: Remove after Struts 1.2
1063
1064 return ModuleUtils.getInstance().getModuleName(matchPath, context);
1065
1066 }
1067
1068
1069 /**
1070 * <p>Return the current <code>ModuleConfig</code> object stored in request,
1071 * if it exists, null otherwise.
1072 * This method can be used by a {@link org.apache.struts.action.PlugIn} to
1073 * retrieve the current module config object. If no moduleConfig is found,
1074 * this means that the request hasn't hit the server through the Struts servlet.
1075 * The appropriate module config can be set and found with
1076 * <code>{@link RequestUtils#selectModule(HttpServletRequest, ServletContext)} </code>.
1077 *
1078 * @param request The servlet request we are processing
1079 *
1080 * @return the ModuleConfig object from request, or null if none is set in
1081 * the request.
1082 * @since Struts 1.1
1083 * @deprecated Use {@link org.apache.struts.util.ModuleUtils#getModuleConfig(HttpServletRequest)} instead.
1084 * This will be removed after Struts 1.2.
1085 */
1086 public static ModuleConfig getRequestModuleConfig(HttpServletRequest request) {
1087 // :TODO: Remove after Struts 1.2
1088
1089 return ModuleUtils.getInstance().getModuleConfig(request);
1090
1091 }
1092
1093
1094 /**
1095 * <p>Return the ModuleConfig object is it exists, null otherwise.</p>
1096 *
1097 * @param request The servlet request we are processing
1098 * @param context The ServletContext for this web application
1099 *
1100 * @return the ModuleConfig object
1101 * @since Struts 1.1
1102 * @deprecated Use {@link org.apache.struts.util.ModuleUtils#getModuleConfig(HttpServletRequest,ServletContext)} instead.
1103 * This will be removed after Struts 1.2.
1104 */
1105 public static ModuleConfig getModuleConfig(
1106 HttpServletRequest request,
1107 ServletContext context) {
1108 // :TODO: Remove after Struts 1.2
1109
1110 return ModuleUtils.getInstance().getModuleConfig(request, context);
1111
1112 }
1113
1114
1115 /**
1116 * <p>Return the list of module prefixes that are defined for
1117 * this web application. <strong>NOTE</strong> -
1118 * the "" prefix for the default module is not included in this list.</p>
1119 *
1120 * @param context The ServletContext for this web application.
1121 *
1122 * @return An array of module prefixes.
1123 * @since Struts 1.1
1124 * @deprecated Use {@link org.apache.struts.util.ModuleUtils#getModulePrefixes(ServletContext)} instead.
1125 * This will be removed after Struts 1.2.
1126 */
1127 public static String[] getModulePrefixes(ServletContext context) {
1128 // :TODO: Remove after Struts 1.2
1129
1130 return ModuleUtils.getInstance().getModulePrefixes(context);
1131
1132 }
1133
1134
1135 // ---------------------------------------- Deprecated in favor of TagUtils
1136
1137
1138 /**
1139 * <p>Compute a set of query parameters that will be dynamically added to
1140 * a generated URL. The returned Map is keyed by parameter name, and the
1141 * values are either null (no value specified), a String (single value
1142 * specified), or a String[] array (multiple values specified). Parameter
1143 * names correspond to the corresponding attributes of the
1144 * <code><html:link></code> tag. If no query parameters are
1145 * identified, return <code>null</code>.</p>
1146 *
1147 * @param pageContext PageContext we are operating in
1148
1149 * @param paramId Single-value request parameter name (if any)
1150 * @param paramName Bean containing single-value parameter value
1151 * @param paramProperty Property (of bean named by <code>paramName</code>
1152 * containing single-value parameter value
1153 * @param paramScope Scope containing bean named by
1154 * <code>paramName</code>
1155 *
1156 * @param name Bean containing multi-value parameters Map (if any)
1157 * @param property Property (of bean named by <code>name</code>
1158 * containing multi-value parameters Map
1159 * @param scope Scope containing bean named by
1160 * <code>name</code>
1161 *
1162 * @param transaction Should we add our transaction control token?
1163 * @return Map of query parameters
1164 * @exception JspException if we cannot look up the required beans
1165 * @exception JspException if a class cast exception occurs on a
1166 * looked-up bean or property
1167 * @deprecated This will be removed after Struts 1.2.
1168 * Use {@link org.apache.struts.taglib.TagUtils#computeParameters(PageContext,String,String,String,String,String,String,String,boolean)} instead.
1169 */
1170 public static Map computeParameters(
1171 PageContext pageContext,
1172 String paramId,
1173 String paramName,
1174 String paramProperty,
1175 String paramScope,
1176 String name,
1177 String property,
1178 String scope,
1179 boolean transaction)
1180 throws JspException {
1181 // :TODO: Remove after Struts 1.2
1182
1183 return TagUtils.getInstance().computeParameters(pageContext, paramId, paramName, paramProperty, paramScope,
1184 name, property, scope, transaction);
1185
1186 }
1187
1188
1189 /**
1190 * <p>Compute a hyperlink URL based on the <code>forward</code>,
1191 * <code>href</code> or <code>page</code> parameter
1192 * that is not null.</p>
1193 *
1194 * @param pageContext PageContext for the tag making this call
1195 * @param forward Logical forward name for which to look up
1196 * the context-relative URI (if specified)
1197 * @param href URL to be utilized unmodified (if specified)
1198 * @param page Module-relative page for which a URL should
1199 * be created (if specified)
1200 * @param params Map of parameters to be dynamically included (if any)
1201 * @param anchor Anchor to be dynamically included (if any)
1202 * @param redirect Is this URL for a <code>response.sendRedirect()</code>?
1203
1204 * @return URL with session identifier
1205 * @exception MalformedURLException if a URL cannot be created
1206 * for the specified parameters
1207 * @deprecated This will be removed after Struts 1.2
1208 * Use {@link RequestUtils#computeURL(PageContext, String, String, String, String, Map, String, boolean)} instead.
1209 */
1210 public static String computeURL(
1211 PageContext pageContext,
1212 String forward,
1213 String href,
1214 String page,
1215 Map params,
1216 String anchor,
1217 boolean redirect)
1218 throws MalformedURLException {
1219 // :TODO: Remove after Struts 1.2
1220
1221 return (TagUtils.getInstance().computeURLWithCharEncoding(
1222 pageContext, forward, href, page, null, null, params, anchor, redirect, false));
1223 }
1224
1225
1226 /**
1227 * <p>Compute a hyperlink URL based on the <code>forward</code>,
1228 * <code>href</code>, <code>action</code> or <code>page</code> parameter
1229 * that is not null.
1230 * The returned URL will have already been passed to
1231 * <code>response.encodeURL()</code> for adding a session identifier.</p>
1232 *
1233 * @param pageContext PageContext for the tag making this call
1234 * @param forward Logical forward name for which to look up
1235 * the context-relative URI (if specified)
1236 * @param href URL to be utilized unmodified (if specified)
1237 * @param page Module-relative page for which a URL should
1238 * be created (if specified)
1239 * @param action Logical action name for which to look up
1240 * the context-relative URI (if specified)
1241 * @param params Map of parameters to be dynamically included (if any)
1242 * @param anchor Anchor to be dynamically included (if any)
1243 * @param redirect Is this URL for a <code>response.sendRedirect()</code>?
1244
1245 * @return URL with session identifier
1246 * @exception MalformedURLException if a URL cannot be created
1247 * for the specified parameters
1248 * @deprecated This will be removed after Struts 1.2.
1249 * Use {@link org.apache.struts.taglib.TagUtils#computeURL(PageContext,String,String,String,String,String,Map,String, boolean)} instead.
1250 */
1251 public static String computeURL(
1252 PageContext pageContext,
1253 String forward,
1254 String href,
1255 String page,
1256 String action,
1257 Map params,
1258 String anchor,
1259 boolean redirect)
1260 throws MalformedURLException {
1261 // :TODO: Remove after Struts 1.2
1262
1263 return TagUtils.getInstance().computeURL(
1264 pageContext,
1265 forward,
1266 href,
1267 page,
1268 action,
1269 null,
1270 params,
1271 anchor,
1272 redirect);
1273 }
1274
1275
1276 /**
1277 * <p>Compute a hyperlink URL based on the <code>forward</code>,
1278 * <code>href</code>, <code>action</code> or <code>page</code> parameter
1279 * that is not null.
1280 * The returned URL will have already been passed to
1281 * <code>response.encodeURL()</code> for adding a session identifier.
1282 * </p>
1283 *
1284 * @param pageContext PageContext for the tag making this call
1285 * @param forward Logical forward name for which to look up
1286 * the context-relative URI (if specified)
1287 * @param href URL to be utilized unmodified (if specified)
1288 * @param page Module-relative page for which a URL should
1289 * be created (if specified)
1290 * @param action Logical action name for which to look up
1291 * the context-relative URI (if specified)
1292 * @param params Map of parameters to be dynamically included (if any)
1293 * @param anchor Anchor to be dynamically included (if any)
1294 * @param redirect Is this URL for a <code>response.sendRedirect()</code>?
1295 * @param encodeSeparator This is only checked if redirect is set to false (never
1296 * encoded for a redirect). If true, query string parameter separators are encoded
1297 * as >amp;, else & is used.
1298
1299 * @return URL with session identifier
1300 * @exception MalformedURLException if a URL cannot be created
1301 * for the specified parameters
1302 * @deprecated This will be removed after Struts 1.2.
1303 * Use {@link org.apache.struts.taglib.TagUtils#computeURL(PageContext,String,String,String,String,String,Map,String,boolean,boolean)} instead.
1304 */
1305 public static String computeURL(
1306 PageContext pageContext,
1307 String forward,
1308 String href,
1309 String page,
1310 String action,
1311 Map params,
1312 String anchor,
1313 boolean redirect,
1314 boolean encodeSeparator)
1315 throws MalformedURLException {
1316 // :TODO: Remove after Struts 1.2
1317
1318 return (TagUtils.getInstance().computeURL(
1319 pageContext,
1320 forward,
1321 href,
1322 page,
1323 action,
1324 null,
1325 params,
1326 anchor,
1327 redirect,
1328 encodeSeparator));
1329 }
1330
1331
1332 /**
1333 * <p>Return the form action converted into an action mapping path. The
1334 * value of the <code>action</code> property is manipulated as follows in
1335 * computing the name of the requested mapping:</p>
1336 * <ul>
1337 * <li>Any filename extension is removed (on the theory that extension
1338 * mapping is being used to select the controller servlet).</li>
1339 * <li>If the resulting value does not start with a slash, then a
1340 * slash is prepended.</li>
1341 * </ul>
1342 * @deprecated This will be removed after Struts 1.2.
1343 * Use {@link org.apache.struts.taglib.TagUtils#getActionMappingName(String)} instead.
1344 */
1345 public static String getActionMappingName(String action) {
1346 // :TODO: Remove after Struts 1.2
1347
1348 return TagUtils.getInstance().getActionMappingName(action);
1349
1350 }
1351
1352
1353 /**
1354 * <p>Return the form action converted into a server-relative URL.</p>
1355 * @deprecated This will be removed after Struts 1.2.
1356 * Use {@link org.apache.struts.taglib.TagUtils#getActionMappingURL(String,PageContext)} instead.
1357 */
1358 public static String getActionMappingURL(
1359 String action,
1360 PageContext pageContext) {
1361 // :TODO: Remove after Struts 1.2
1362
1363 return TagUtils.getInstance().getActionMappingURL(action, pageContext);
1364
1365 }
1366
1367
1368 /**
1369 * <p>Locate and return the specified bean, from an optionally specified
1370 * scope, in the specified page context. If no such bean is found,
1371 * return <code>null</code> instead. If an exception is thrown, it will
1372 * have already been saved via a call to <code>saveException</code>.</p>
1373 *
1374 * @param pageContext Page context to be searched
1375 * @param name Name of the bean to be retrieved
1376 * @param scopeName Scope to be searched (page, request, session, application)
1377 * or <code>null</code> to use <code>findAttribute()</code> instead
1378 *
1379 * @return JavaBean in the specified page context
1380 * @exception JspException if an invalid scope name
1381 * is requested
1382 * @deprecated This will be removed after Struts 1.2.
1383 * Use {@link org.apache.struts.taglib.TagUtils#lookup(PageContext,String,String)} instead.
1384 */
1385 public static Object lookup(PageContext pageContext, String name, String scopeName)
1386 throws JspException {
1387 // :TODO: Remove after Struts 1.2
1388
1389 return TagUtils.getInstance().lookup(pageContext, name, scopeName);
1390
1391 }
1392
1393
1394 /**
1395 * <p>Converts the scope name into its corresponding PageContext constant value.</p>
1396 *
1397 * @param scopeName Can be "page", "request", "session", or "application" in any
1398 * case
1399 *
1400 * @return The constant representing the scope (ie. PageContext.REQUEST_SCOPE).
1401 * @throws JspException if the scopeName is not a valid name.
1402 * @since Struts 1.1
1403 * @deprecated This will be removed after Struts 1.2.
1404 * Use {@link org.apache.struts.taglib.TagUtils#getScope(String)} instead.
1405
1406 */
1407 public static int getScope(String scopeName) throws JspException {
1408 // :TODO: Remove after Struts 1.2
1409
1410 return TagUtils.getInstance().getScope(scopeName);
1411
1412 }
1413
1414
1415 /**
1416 * <p>Locate and return the specified property of the specified bean, from
1417 * an optionally specified scope, in the specified page context. If an
1418 * exception is thrown, it will have already been saved via a call to
1419 * <code>saveException</code>.</p>
1420 *
1421 * @param pageContext Page context to be searched
1422 * @param name Name of the bean to be retrieved
1423 * @param property Name of the property to be retrieved, or
1424 * <code>null</code> to retrieve the bean itself
1425 * @param scope Scope to be searched (page, request, session, application)
1426 * or <code>null</code> to use <code>findAttribute()</code> instead
1427 *
1428 * @return property of specified JavaBean
1429 * @exception JspException if an invalid scope name
1430 * is requested
1431 * @exception JspException if the specified bean is not found
1432 * @exception JspException if accessing this property causes an
1433 * IllegalAccessException, IllegalArgumentException,
1434 * InvocationTargetException, or NoSuchMethodException
1435 * @deprecated This will be removed after Struts 1.2.
1436 * Use {@link org.apache.struts.taglib.TagUtils#lookup(PageContext,String,String,String)} instead.
1437
1438 */
1439 public static Object lookup(
1440 PageContext pageContext,
1441 String name,
1442 String property,
1443 String scope)
1444 throws JspException {
1445 // :TODO: Remove after Struts 1.2
1446
1447 return TagUtils.getInstance().lookup(pageContext, name, property, scope);
1448
1449 }
1450
1451
1452 /**
1453 * <p>Look up and return current user locale, based on the specified parameters.</p>
1454 *
1455 * @param pageContext The PageContext associated with this request
1456 * @param locale Name of the session attribute for our user's Locale. If this is
1457 * <code>null</code>, the default locale key is used for the lookup.
1458 *
1459 * @return current user locale
1460 * @deprecated This will be removed after Struts 1.2.
1461 * Use {@link org.apache.struts.taglib.TagUtils#getUserLocale(PageContext,String)} instead.
1462 */
1463 public static Locale retrieveUserLocale(PageContext pageContext, String locale) {
1464 // :TODO: Remove after Struts 1.2
1465
1466 return TagUtils.getInstance().getUserLocale(pageContext, locale);
1467
1468 }
1469
1470
1471 /**
1472 * <p>Look up and return a message string, based on the specified parameters.</p>
1473 *
1474 * @param pageContext The PageContext associated with this request
1475 * @param bundle Name of the servlet context attribute for our
1476 * message resources bundle
1477 * @param locale Name of the session attribute for our user's Locale
1478 * @param key Message key to be looked up and returned
1479 *
1480 * @return message string
1481 * @exception JspException if a lookup error occurs (will have been
1482 * saved in the request already)
1483 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#message(PageContext,String,String,String)} instead.
1484 * This will be removed after Struts 1.2.
1485 */
1486 public static String message(
1487 PageContext pageContext,
1488 String bundle,
1489 String locale,
1490 String key)
1491 throws JspException {
1492 // :TODO: Remove afer Struts 1.2
1493
1494 return TagUtils.getInstance().message(pageContext, bundle, locale, key);
1495
1496 }
1497
1498
1499 /**
1500 * Look up and return a message string, based on the specified parameters.
1501 *
1502 * @param pageContext The PageContext associated with this request
1503 * @param bundle Name of the servlet context attribute for our
1504 * message resources bundle
1505 * @param locale Name of the session attribute for our user's Locale
1506 * @param key Message key to be looked up and returned
1507 * @param args Replacement parameters for this message
1508 * @return message string
1509 * @exception JspException if a lookup error occurs (will have been
1510 * saved in the request already)
1511 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#message(PageContext,String,String,String,Object[])} instead.
1512 * This will be removed after Struts 1.2.
1513 */
1514 public static String message(
1515 PageContext pageContext,
1516 String bundle,
1517 String locale,
1518 String key,
1519 Object args[])
1520 throws JspException {
1521 // :TODO: Remove afer Struts 1.2
1522
1523 return TagUtils.getInstance().message(
1524 pageContext,
1525 bundle,
1526 locale,
1527 key,
1528 args);
1529 }
1530
1531
1532 /**
1533 * <p>Return true if a message string for the specified message key
1534 * is present for the specified Locale.</p>
1535 *
1536 * @param pageContext The PageContext associated with this request
1537 * @param bundle Name of the servlet context attribute for our
1538 * message resources bundle
1539 * @param locale Name of the session attribute for our user's Locale
1540 * @param key Message key to be looked up and returned
1541 *
1542 * @return true if a message string for message key exists
1543 * @exception JspException if a lookup error occurs (will have been
1544 * saved in the request already)
1545 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#present(PageContext ,String,String,String)} instead.
1546 * This will be removed after Struts 1.2.
1547 */
1548 public static boolean present(
1549 PageContext pageContext,
1550 String bundle,
1551 String locale,
1552 String key)
1553 throws JspException {
1554 // :TODO: Remove after Struts 1.2
1555
1556 return TagUtils.getInstance().present(pageContext, bundle, locale, key);
1557
1558 }
1559
1560
1561 /**
1562 * <p>Return the context-relative URL that corresponds to the specified
1563 * <code>page</code> attribute value, calculated based on the
1564 * <code>pagePattern</code> property of the current module's
1565 * {@link ModuleConfig}.</p>
1566 *
1567 * @param request The servlet request we are processing
1568 * @param page The module-relative URL to be substituted in
1569 * to the <code>pagePattern</code> pattern for the current module
1570 * (<strong>MUST</strong> start with a slash)
1571
1572 * @return context-relative URL
1573 * @since Struts 1.1
1574 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#pageURL(HttpServletRequest request, String page, ModuleConfig moduleConfig)} instead.
1575 * This will be removed after Struts 1.2.
1576 */
1577 public static String pageURL(HttpServletRequest request, String page) {
1578 //load the current moduleConfig
1579 ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request);
1580
1581 return TagUtils.getInstance().pageURL(request, page, moduleConfig);
1582 //:TODO: Remove after Struts 1.2
1583
1584 }
1585
1586
1587 /**
1588 * <p>Save the specified exception as a request attribute for later use.</p>
1589 *
1590 * @param pageContext The PageContext for the current page
1591 * @param exception The exception to be saved
1592 *
1593 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#saveException(PageContext,Throwable)} instead.
1594 * This will be removed after Struts 1.2.
1595 */
1596 public static void saveException(PageContext pageContext, Throwable exception) {
1597
1598 TagUtils.getInstance().saveException(pageContext, exception);
1599 // :TODO: Remove after Struts 1.2
1600
1601 }
1602
1603
1604 /**
1605 * <p>Return the <code>ModuleConfig</code> object if it exists, null if otherwise.</p>
1606 *
1607 * @param pageContext The page context.
1608 *
1609 * @return the ModuleConfig object
1610 * @since Struts 1.1
1611 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#getModuleConfig(PageContext)} instead.
1612 * This will be removed after Struts 1.2.
1613 */
1614 public static ModuleConfig getModuleConfig(PageContext pageContext) {
1615 // :TODO: Remove after Struts 1.2
1616
1617 return TagUtils.getInstance().getModuleConfig(pageContext);
1618
1619 }
1620
1621
1622 /**
1623 * <p>Retrieves the value from request scope and if it isn't already an
1624 * <code>ActionMessages</code> some classes are converted to one.</p>
1625 *
1626 * @param pageContext The PageContext for the current page
1627 * @param paramName Key for parameter value
1628 *
1629 * @return ActionErros in page context.
1630 * @throws JspException
1631 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#getActionMessages(PageContext,String)} instead.
1632 * This will be removed after Struts 1.2.
1633 */
1634 public static ActionMessages getActionMessages(PageContext pageContext, String paramName)
1635 throws JspException {
1636 // :TODO: Remove after Struts 1.2
1637
1638 return TagUtils.getInstance().getActionMessages(pageContext, paramName);
1639 }
1640
1641
1642 /**
1643 * <p>Retrieves the value from request scope and if it isn't already an
1644 * <code>ErrorMessages</code> some classes are converted to one.</p>
1645 *
1646 * @param pageContext The PageContext for the current page
1647 * @param paramName Key for parameter value
1648 *
1649 *
1650 * @return ActionErrors from request scope
1651 * @exception JspException
1652 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#getActionErrors(PageContext,String)} instead.
1653 * This will be removed after Struts 1.2.
1654 */
1655 public static ActionErrors getActionErrors(PageContext pageContext, String paramName)
1656 throws JspException {
1657 // :TODO: Remove after Struts 1.2
1658
1659 return TagUtils.getInstance().getActionErrors(pageContext, paramName);
1660 }
1661
1662
1663 /**
1664 * <p>Use the new <code>URLEncoder.encode</code> method from Java 1.4 if available, else
1665 * use the old deprecated version. This method uses reflection to find the appropriate
1666 * method; if the reflection operations throw exceptions, this will return the url
1667 * encoded with the old <code>URLEncoder.encode</code> method.
1668 * @return String - the encoded url.
1669 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#encodeURL(String)} instead.
1670 * This will be removed after Struts 1.2.
1671 */
1672 public static String encodeURL(String url) {
1673 // :TODO: Remove after Struts 1.2
1674
1675 return TagUtils.getInstance().encodeURL(url);
1676
1677 }
1678
1679
1680 /**
1681 * <p>Returns true if the custom tags are in XHTML mode.</p>
1682 *
1683 * @since Struts 1.1
1684 * @deprecated Use {@link org.apache.struts.taglib.TagUtils#isXhtml(PageContext)} instead.
1685 * This will be removed after Struts 1.2.
1686 */
1687 public static boolean isXhtml(PageContext pageContext) {
1688 // :TODO: Remove after Struts 1.2
1689
1690 String xhtml =
1691 (String) pageContext.getAttribute(
1692 Globals.XHTML_KEY,
1693 PageContext.PAGE_SCOPE);
1694
1695 return "true".equalsIgnoreCase(xhtml);
1696
1697 }
1698
1699}