KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > taglib > TagUtils


1 /*
2  * $Id: TagUtils.java 164747 2005-04-26 05:47:48Z hrabago $
3  *
4  * Copyright 1999-2005 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.taglib;
20
21 import java.io.IOException JavaDoc;
22 import java.lang.reflect.InvocationTargetException JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Locale JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import javax.servlet.http.HttpServletRequest JavaDoc;
30 import javax.servlet.http.HttpServletResponse JavaDoc;
31 import javax.servlet.http.HttpSession JavaDoc;
32 import javax.servlet.jsp.JspException JavaDoc;
33 import javax.servlet.jsp.JspWriter JavaDoc;
34 import javax.servlet.jsp.PageContext JavaDoc;
35 import javax.servlet.jsp.tagext.BodyContent JavaDoc;
36
37 import org.apache.commons.beanutils.PropertyUtils;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.apache.struts.Globals;
41 import org.apache.struts.action.ActionErrors;
42 import org.apache.struts.action.ActionMessage;
43 import org.apache.struts.action.ActionMessages;
44 import org.apache.struts.config.ForwardConfig;
45 import org.apache.struts.config.ModuleConfig;
46 import org.apache.struts.taglib.html.Constants;
47 import org.apache.struts.util.MessageResources;
48 import org.apache.struts.util.ModuleUtils;
49 import org.apache.struts.util.RequestUtils;
50 import org.apache.struts.util.ResponseUtils;
51
52 /**
53  * Provides helper methods for JSP tags.
54  *
55  * @version $Rev: 164747 $
56  * @since Struts 1.2
57  */

58 public class TagUtils {
59
60     /**
61      * The Singleton instance.
62      */

63     private static final TagUtils instance = new TagUtils();
64
65     /**
66      * Commons logging instance.
67      */

68     private static final Log log = LogFactory.getLog(TagUtils.class);
69
70     /**
71      * The message resources for this package.
72      * TODO We need to move the relevant messages out of this properties file.
73      */

74     private static final MessageResources messages =
75             MessageResources.getMessageResources("org.apache.struts.taglib.LocalStrings");
76
77     /**
78      * Maps lowercase JSP scope names to their PageContext integer constant
79      * values.
80      */

81     private static final Map JavaDoc scopes = new HashMap JavaDoc();
82
83     /**
84      * Initialize the scope names map.
85      */

86     static {
87         scopes.put("page", new Integer JavaDoc(PageContext.PAGE_SCOPE));
88         scopes.put("request", new Integer JavaDoc(PageContext.REQUEST_SCOPE));
89         scopes.put("session", new Integer JavaDoc(PageContext.SESSION_SCOPE));
90         scopes.put("application", new Integer JavaDoc(PageContext.APPLICATION_SCOPE));
91     }
92
93     /**
94      * Constructor for TagUtils.
95      */

96     protected TagUtils() {
97         super();
98     }
99
100     /**
101      * Returns the Singleton instance of TagUtils.
102      */

103     public static TagUtils getInstance() {
104         return instance;
105     }
106
107     /**
108      * Compute a set of query parameters that will be dynamically added to
109      * a generated URL. The returned Map is keyed by parameter name, and the
110      * values are either null (no value specified), a String (single value
111      * specified), or a String[] array (multiple values specified). Parameter
112      * names correspond to the corresponding attributes of the
113      * <code>&lt;html:link&gt;</code> tag. If no query parameters are
114      * identified, return <code>null</code>.
115      *
116      * @param pageContext PageContext we are operating in
117
118      * @param paramId Single-value request parameter name (if any)
119      * @param paramName Bean containing single-value parameter value
120      * @param paramProperty Property (of bean named by <code>paramName</code>
121      * containing single-value parameter value
122      * @param paramScope Scope containing bean named by
123      * <code>paramName</code>
124      *
125      * @param name Bean containing multi-value parameters Map (if any)
126      * @param property Property (of bean named by <code>name</code>
127      * containing multi-value parameters Map
128      * @param scope Scope containing bean named by
129      * <code>name</code>
130      *
131      * @param transaction Should we add our transaction control token?
132      * @return Map of query parameters
133      * @exception JspException if we cannot look up the required beans
134      * @exception JspException if a class cast exception occurs on a
135      * looked-up bean or property
136      */

137     public Map JavaDoc computeParameters(
138             PageContext JavaDoc pageContext,
139             String JavaDoc paramId,
140             String JavaDoc paramName,
141             String JavaDoc paramProperty,
142             String JavaDoc paramScope,
143             String JavaDoc name,
144             String JavaDoc property,
145             String JavaDoc scope,
146             boolean transaction)
147             throws JspException JavaDoc {
148
149         // Short circuit if no parameters are specified
150
if ((paramId == null) && (name == null) && !transaction) {
151             return (null);
152         }
153
154         // Locate the Map containing our multi-value parameters map
155
Map JavaDoc map = null;
156         try {
157             if (name != null) {
158                 map =
159                         (Map JavaDoc) TagUtils.getInstance().lookup(
160                                 pageContext,
161                                 name,
162                                 property,
163                                 scope);
164             }
165         } catch (ClassCastException JavaDoc e) {
166             saveException(pageContext, e);
167             throw new JspException JavaDoc(
168                     messages.getMessage("parameters.multi", name, property, scope));
169
170         } catch (JspException JavaDoc e) {
171             saveException(pageContext, e);
172             throw e;
173         }
174
175         // Create a Map to contain our results from the multi-value parameters
176
Map JavaDoc results = null;
177         if (map != null) {
178             results = new HashMap JavaDoc(map);
179         } else {
180             results = new HashMap JavaDoc();
181         }
182
183         // Add the single-value parameter (if any)
184
if ((paramId != null) && (paramName != null)) {
185
186             Object JavaDoc paramValue = null;
187             try {
188                 paramValue =
189                         TagUtils.getInstance().lookup(
190                                 pageContext,
191                                 paramName,
192                                 paramProperty,
193                                 paramScope);
194
195             } catch (JspException JavaDoc e) {
196                 saveException(pageContext, e);
197                 throw e;
198             }
199
200             if (paramValue != null) {
201
202                 String JavaDoc paramString = null;
203                 if (paramValue instanceof String JavaDoc) {
204                     paramString = (String JavaDoc) paramValue;
205                 } else {
206                     paramString = paramValue.toString();
207                 }
208
209                 Object JavaDoc mapValue = results.get(paramId);
210                 if (mapValue == null) {
211                     results.put(paramId, paramString);
212
213                 } else if (mapValue instanceof String JavaDoc[]) {
214                     String JavaDoc oldValues[] = (String JavaDoc[]) mapValue;
215                     String JavaDoc newValues[] = new String JavaDoc[oldValues.length + 1];
216                     System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
217                     newValues[oldValues.length] = paramString;
218                     results.put(paramId, newValues);
219
220                 } else {
221                     String JavaDoc newValues[] = new String JavaDoc[2];
222                     newValues[0] = mapValue.toString();
223                     newValues[1] = paramString;
224                     results.put(paramId, newValues);
225                 }
226
227             }
228
229         }
230
231         // Add our transaction control token (if requested)
232
if (transaction) {
233             HttpSession JavaDoc session = pageContext.getSession();
234             String JavaDoc token = null;
235             if (session != null) {
236                 token = (String JavaDoc) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
237             }
238
239             if (token != null) {
240                 results.put(Constants.TOKEN_KEY, token);
241             }
242         }
243
244         // Return the completed Map
245
return (results);
246
247     }
248
249     public String JavaDoc computeURL(
250             PageContext JavaDoc pageContext,
251             String JavaDoc forward,
252             String JavaDoc href,
253             String JavaDoc page,
254             String JavaDoc action,
255             String JavaDoc module,
256             Map JavaDoc params,
257             String JavaDoc anchor,
258             boolean redirect)
259             throws MalformedURLException JavaDoc {
260             return this.computeURLWithCharEncoding(
261                                 pageContext,
262                                 forward,
263                                 href,
264                                 page,
265                                 action,
266                                 module,
267                                 params,
268                                 anchor,
269                                 redirect,
270                                 false);
271     }
272
273     /**
274      * Compute a hyperlink URL based on the <code>forward</code>,
275      * <code>href</code>, <code>action</code> or <code>page</code> parameter
276      * that is not null.
277      * The returned URL will have already been passed to
278      * <code>response.encodeURL()</code> for adding a session identifier.
279      *
280      * @param pageContext PageContext for the tag making this call
281      *
282      * @param forward Logical forward name for which to look up
283      * the context-relative URI (if specified)
284      * @param href URL to be utilized unmodified (if specified)
285      * @param page Module-relative page for which a URL should
286      * be created (if specified)
287      * @param action Logical action name for which to look up
288      * the context-relative URI (if specified)
289      *
290      * @param params Map of parameters to be dynamically included (if any)
291      * @param anchor Anchor to be dynamically included (if any)
292      *
293      * @param redirect Is this URL for a <code>response.sendRedirect()</code>?
294      * @return URL with session identifier
295      * @exception java.net.MalformedURLException if a URL cannot be created
296      * for the specified parameters
297      */

298     public String JavaDoc computeURLWithCharEncoding(
299             PageContext JavaDoc pageContext,
300             String JavaDoc forward,
301             String JavaDoc href,
302             String JavaDoc page,
303             String JavaDoc action,
304             String JavaDoc module,
305             Map JavaDoc params,
306             String JavaDoc anchor,
307             boolean redirect,
308             boolean useLocalEncoding)
309             throws MalformedURLException JavaDoc {
310
311         return computeURLWithCharEncoding(
312                 pageContext,
313                 forward,
314                 href,
315                 page,
316                 action,
317                 module,
318                 params,
319                 anchor,
320                 redirect,
321                 true,
322                 useLocalEncoding);
323     }
324
325     public String JavaDoc computeURL(
326             PageContext JavaDoc pageContext,
327             String JavaDoc forward,
328             String JavaDoc href,
329             String JavaDoc page,
330             String JavaDoc action,
331             String JavaDoc module,
332             Map JavaDoc params,
333             String JavaDoc anchor,
334             boolean redirect,
335             boolean encodeSeparator)
336             throws MalformedURLException JavaDoc {
337                 return computeURLWithCharEncoding(
338                 pageContext,
339                 forward,
340                 href,
341                 page,
342                 action,
343                 module,
344                 params,
345                 anchor,
346                 redirect,
347                 encodeSeparator,
348                 false
349                 );
350     }
351
352     /**
353      * Compute a hyperlink URL based on the <code>forward</code>,
354      * <code>href</code>, <code>action</code> or <code>page</code> parameter
355      * that is not null.
356      * The returned URL will have already been passed to
357      * <code>response.encodeURL()</code> for adding a session identifier.
358      *
359      * @param pageContext PageContext for the tag making this call
360      *
361      * @param forward Logical forward name for which to look up
362      * the context-relative URI (if specified)
363      * @param href URL to be utilized unmodified (if specified)
364      * @param page Module-relative page for which a URL should
365      * be created (if specified)
366      * @param action Logical action name for which to look up
367      * the context-relative URI (if specified)
368      *
369      * @param params Map of parameters to be dynamically included (if any)
370      * @param anchor Anchor to be dynamically included (if any)
371      *
372      * @param redirect Is this URL for a <code>response.sendRedirect()</code>?
373      * @param encodeSeparator This is only checked if redirect is set to false (never
374      * encoded for a redirect). If true, query string parameter separators are encoded
375      * as &gt;amp;, else &amp; is used.
376      * @param useLocalEncoding If set to true, urlencoding is done on the bytes of
377      * character encoding from ServletResponse#getCharacterEncoding. Use UTF-8
378      * otherwise.
379      * @return URL with session identifier
380      * @exception java.net.MalformedURLException if a URL cannot be created
381      * for the specified parameters
382      */

383     public String JavaDoc computeURLWithCharEncoding(
384             PageContext JavaDoc pageContext,
385             String JavaDoc forward,
386             String JavaDoc href,
387             String JavaDoc page,
388             String JavaDoc action,
389             String JavaDoc module,
390             Map JavaDoc params,
391             String JavaDoc anchor,
392             boolean redirect,
393             boolean encodeSeparator,
394             boolean useLocalEncoding)
395             throws MalformedURLException JavaDoc {
396        String JavaDoc charEncoding = "UTF-8";
397        if(useLocalEncoding){
398         charEncoding = pageContext.getResponse().getCharacterEncoding();
399        }
400
401         // TODO All the computeURL() methods need refactoring!
402

403         // Validate that exactly one specifier was included
404
int n = 0;
405         if (forward != null) {
406             n++;
407         }
408         if (href != null) {
409             n++;
410         }
411         if (page != null) {
412             n++;
413         }
414         if (action != null) {
415             n++;
416         }
417         if (n != 1) {
418             throw new MalformedURLException JavaDoc(messages.getMessage("computeURL.specifier"));
419         }
420
421         // Look up the module configuration for this request
422
ModuleConfig moduleConfig = instance.getModuleConfig(module, pageContext);
423
424         // Calculate the appropriate URL
425
StringBuffer JavaDoc url = new StringBuffer JavaDoc();
426         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
427         if (forward != null) {
428             ForwardConfig forwardConfig = moduleConfig.findForwardConfig(forward);
429             if (forwardConfig == null) {
430                 throw new MalformedURLException JavaDoc(messages.getMessage("computeURL.forward", forward));
431             }
432             if (forwardConfig.getRedirect()) {
433                 redirect = true;
434             }
435             if (forwardConfig.getPath().startsWith("/")) {
436                 url.append(request.getContextPath());
437                 url.append(RequestUtils.forwardURL(request, forwardConfig, moduleConfig));
438             } else {
439                 url.append(forwardConfig.getPath());
440             }
441         } else if (href != null) {
442             url.append(href);
443         } else if (action != null) {
444             url.append(instance.getActionMappingURL(action, module, pageContext, false));
445
446         } else /* if (page != null) */ {
447             url.append(request.getContextPath());
448             url.append(this.pageURL(request, page, moduleConfig));
449         }
450
451         // Add anchor if requested (replacing any existing anchor)
452
if (anchor != null) {
453             String JavaDoc temp = url.toString();
454             int hash = temp.indexOf('#');
455             if (hash >= 0) {
456                 url.setLength(hash);
457             }
458             url.append('#');
459             url.append(this.encodeURL(anchor, charEncoding));
460         }
461
462         // Add dynamic parameters if requested
463
if ((params != null) && (params.size() > 0)) {
464
465             // Save any existing anchor
466
String JavaDoc temp = url.toString();
467             int hash = temp.indexOf('#');
468             if (hash >= 0) {
469                 anchor = temp.substring(hash + 1);
470                 url.setLength(hash);
471                 temp = url.toString();
472             } else {
473                 anchor = null;
474             }
475
476             // Define the parameter separator
477
String JavaDoc separator = null;
478             if (redirect) {
479                 separator = "&";
480             } else if (encodeSeparator) {
481                 separator = "&amp;";
482             } else {
483                 separator = "&";
484             }
485
486             // Add the required request parameters
487
boolean question = temp.indexOf('?') >= 0;
488             Iterator JavaDoc keys = params.keySet().iterator();
489             while (keys.hasNext()) {
490                 String JavaDoc key = (String JavaDoc) keys.next();
491                 Object JavaDoc value = params.get(key);
492                 if (value == null) {
493                     if (!question) {
494                         url.append('?');
495                         question = true;
496                     } else {
497                         url.append(separator);
498                     }
499                     url.append(this.encodeURL(key, charEncoding));
500                     url.append('='); // Interpret null as "no value"
501
} else if (value instanceof String JavaDoc) {
502                     if (!question) {
503                         url.append('?');
504                         question = true;
505                     } else {
506                         url.append(separator);
507                     }
508                     url.append(this.encodeURL(key, charEncoding));
509                     url.append('=');
510                     url.append(this.encodeURL((String JavaDoc) value, charEncoding));
511                 } else if (value instanceof String JavaDoc[]) {
512                     String JavaDoc values[] = (String JavaDoc[]) value;
513                     for (int i = 0; i < values.length; i++) {
514                         if (!question) {
515                             url.append('?');
516                             question = true;
517                         } else {
518                             url.append(separator);
519                         }
520                         url.append(this.encodeURL(key, charEncoding));
521                         url.append('=');
522                         url.append(this.encodeURL(values[i], charEncoding));
523                     }
524                 } else /* Convert other objects to a string */ {
525                     if (!question) {
526                         url.append('?');
527                         question = true;
528                     } else {
529                         url.append(separator);
530                     }
531                     url.append(this.encodeURL(key, charEncoding));
532                     url.append('=');
533                     url.append(this.encodeURL(value.toString(), charEncoding));
534                 }
535             }
536
537             // Re-add the saved anchor (if any)
538
if (anchor != null) {
539                 url.append('#');
540                 url.append(this.encodeURL(anchor, charEncoding));
541             }
542
543         }
544
545         // Perform URL rewriting to include our session ID (if any)
546
// but only if url is not an external URL
547
if (( href == null ) && ( pageContext.getSession() != null )) {
548             HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) pageContext.getResponse();
549             if (redirect) {
550                 return (response.encodeRedirectURL(url.toString()));
551             } else {
552                 return (response.encodeURL(url.toString()));
553             }
554         } else {
555             return (url.toString());
556         }
557
558     }
559
560
561     /**
562      * URLencodes a string assuming the character encoding is UTF-8.
563      *
564      * @param url
565      * @return String The encoded url in UTF-8
566      */

567     public String JavaDoc encodeURL(String JavaDoc url) {
568         return encodeURL(url, "UTF-8");
569     }
570
571     /**
572      * Use the new URLEncoder.encode() method from Java 1.4 if available, else
573      * use the old deprecated version. This method uses reflection to find the
574      * appropriate method; if the reflection operations throw exceptions, this
575      * will return the url encoded with the old URLEncoder.encode() method.
576      * @param enc The character encoding the urlencode is performed on.
577      * @return String The encoded url.
578      */

579     public String JavaDoc encodeURL(String JavaDoc url, String JavaDoc enc) {
580         return ResponseUtils.encodeURL(url, enc);
581     }
582
583     /**
584      * Filter the specified string for characters that are sensitive to
585      * HTML interpreters, returning the string with these characters replaced
586      * by the corresponding character entities.
587      *
588      * @param value The string to be filtered and returned
589      */

590     public String JavaDoc filter(String JavaDoc value) {
591         return ResponseUtils.filter(value);
592     }
593
594     /**
595      * Retrieves the value from request scope and if it isn't already an
596      * <code>ErrorMessages</code> some classes are converted to one.
597      *
598      * @param pageContext The PageContext for the current page
599      * @param paramName Key for parameter value
600      * @return ActionErrors from request scope
601      * @exception JspException
602      * @deprecated Use getActionMessages() instead. This will be removed
603      * after Struts 1.2.
604      */

605     public ActionErrors getActionErrors(PageContext JavaDoc pageContext, String JavaDoc paramName)
606             throws JspException JavaDoc {
607
608         ActionErrors errors = new ActionErrors();
609
610         Object JavaDoc value = pageContext.findAttribute(paramName);
611         if (value != null) {
612             try {
613                 if (value instanceof String JavaDoc) {
614                     errors.add(
615                             ActionMessages.GLOBAL_MESSAGE,
616                             new ActionMessage((String JavaDoc) value));
617
618                 } else if (value instanceof String JavaDoc[]) {
619                     String JavaDoc keys[] = (String JavaDoc[]) value;
620                     for (int i = 0; i < keys.length; i++) {
621                         errors.add(
622                                 ActionMessages.GLOBAL_MESSAGE,
623                                 new ActionMessage(keys[i]));
624                     }
625
626                 } else if (value instanceof ActionErrors) {
627                     errors = (ActionErrors) value;
628
629                 } else {
630                     throw new JspException JavaDoc(
631                             messages.getMessage(
632                                     "actionErrors.errors",
633                                     value.getClass().getName()));
634                 }
635
636             } catch (JspException JavaDoc e) {
637                 throw e;
638
639             } catch (Exception JavaDoc e) {
640                 log.debug(e, e);
641             }
642         }
643         return errors;
644     }
645
646     /**
647      * Return the form action converted into an action mapping path. The
648      * value of the <code>action</code> property is manipulated as follows in
649      * computing the name of the requested mapping:
650      * <ul>
651      * <li>Any filename extension is removed (on the theory that extension
652      * mapping is being used to select the controller servlet).</li>
653      * <li>If the resulting value does not start with a slash, then a
654      * slash is prepended.</li>
655      * </ul>
656      */

657     public String JavaDoc getActionMappingName(String JavaDoc action) {
658
659         String JavaDoc value = action;
660         int question = action.indexOf("?");
661         if (question >= 0) {
662             value = value.substring(0, question);
663         }
664
665         int slash = value.lastIndexOf("/");
666         int period = value.lastIndexOf(".");
667         if ((period >= 0) && (period > slash)) {
668             value = value.substring(0, period);
669         }
670
671         return value.startsWith("/") ? value : ("/" + value);
672     }
673
674
675     /**
676      * Return the form action converted into a server-relative URL.
677      */

678     public String JavaDoc getActionMappingURL(String JavaDoc action, PageContext JavaDoc pageContext) {
679         return getActionMappingURL(action,null,pageContext,false);
680     }
681
682
683     /**
684      * Return the form action converted into a server-relative URL.
685      */

686     public String JavaDoc getActionMappingURL(String JavaDoc action, String JavaDoc module, PageContext JavaDoc pageContext, boolean contextRelative) {
687
688         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
689
690         String JavaDoc contextPath = request.getContextPath();
691         StringBuffer JavaDoc value = new StringBuffer JavaDoc();
692         // Avoid setting two slashes at the beginning of an action:
693
// the length of contextPath should be more than 1
694
// in case of non-root context, otherwise length==1 (the slash)
695
if (contextPath.length() > 1) value.append(contextPath);
696
697         ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(module, request, pageContext.getServletContext());
698
699         if ((moduleConfig != null) && (!contextRelative)) {
700             value.append(moduleConfig.getPrefix());
701         }
702
703         // Use our servlet mapping, if one is specified
704
String JavaDoc servletMapping =
705                 (String JavaDoc) pageContext.getAttribute(
706                         Globals.SERVLET_KEY,
707                         PageContext.APPLICATION_SCOPE);
708
709         if (servletMapping != null) {
710
711             String JavaDoc queryString = null;
712             int question = action.indexOf("?");
713             if (question >= 0) {
714                 queryString = action.substring(question);
715             }
716
717             String JavaDoc actionMapping = getActionMappingName(action);
718             if (servletMapping.startsWith("*.")) {
719                 value.append(actionMapping);
720                 value.append(servletMapping.substring(1));
721
722             } else if (servletMapping.endsWith("/*")) {
723                 value.append(
724                         servletMapping.substring(0, servletMapping.length() - 2));
725                 value.append(actionMapping);
726
727             } else if (servletMapping.equals("/")) {
728                 value.append(actionMapping);
729             }
730             if (queryString != null) {
731                 value.append(queryString);
732             }
733         }
734
735         // Otherwise, assume extension mapping is in use and extension is
736
// already included in the action property
737
else {
738             if (!action.startsWith("/")) {
739                 value.append("/");
740             }
741             value.append(action);
742         }
743
744         return value.toString();
745     }
746
747     /**
748      * Retrieves the value from request scope and if it isn't already an
749      * <code>ActionMessages</code>, some classes are converted to one.
750      *
751      * @param pageContext The PageContext for the current page
752      * @param paramName Key for parameter value
753      * @return ActionErrors in page context.
754      * @throws JspException
755      */

756     public ActionMessages getActionMessages(
757             PageContext JavaDoc pageContext,
758             String JavaDoc paramName)
759             throws JspException JavaDoc {
760
761         ActionMessages am = new ActionMessages();
762
763         Object JavaDoc value = pageContext.findAttribute(paramName);
764         if (value != null) {
765             try {
766                if (value instanceof String JavaDoc) {
767                     am.add(
768                             ActionMessages.GLOBAL_MESSAGE,
769                             new ActionMessage((String JavaDoc) value));
770
771                 } else if (value instanceof String JavaDoc[]) {
772                     String JavaDoc keys[] = (String JavaDoc[]) value;
773                     for (int i = 0; i < keys.length; i++) {
774                         am.add(
775                                 ActionMessages.GLOBAL_MESSAGE,
776                                 new ActionMessage(keys[i]));
777                     }
778
779                 } else if (value instanceof ActionErrors) {
780                     ActionMessages m = (ActionMessages) value;
781                     am.add(m);
782
783                 } else if (value instanceof ActionMessages) {
784                     am = (ActionMessages) value;
785
786                 } else {
787                     throw new JspException JavaDoc(
788                             messages.getMessage(
789                                     "actionMessages.errors",
790                                     value.getClass().getName()));
791                 }
792
793             } catch (JspException JavaDoc e) {
794                 throw e;
795
796             } catch (Exception JavaDoc e) {
797                 log.warn("Unable to retieve ActionMessage for paramName : "+paramName,e);
798             }
799         }
800         return am;
801     }
802
803     /**
804      * Return the ModuleConfig object if it exists, null if otherwise.
805      * @param pageContext The page context.
806      * @return the ModuleConfig object
807      */

808     public ModuleConfig getModuleConfig(PageContext JavaDoc pageContext) {
809         return getModuleConfig(
810                 null,
811                 pageContext);
812     }
813
814     /**
815      * Return the ModuleConfig object for the given prefix if it exists, null if otherwise.
816      * @param module The module prefix
817      * @param pageContext The page context.
818      * @return the ModuleConfig object
819      */

820     public ModuleConfig getModuleConfig(String JavaDoc module, PageContext JavaDoc pageContext) {
821         return ModuleUtils.getInstance().getModuleConfig(
822                 module,
823                 (HttpServletRequest JavaDoc) pageContext.getRequest(),
824                 pageContext.getServletContext());
825     }
826
827     /**
828      * Converts the scope name into its corresponding PageContext constant value.
829      * @param scopeName Can be "page", "request", "session", or "application" in any
830      * case.
831      * @return The constant representing the scope (ie. PageContext.REQUEST_SCOPE).
832      * @throws JspException if the scopeName is not a valid name.
833      */

834     public int getScope(String JavaDoc scopeName) throws JspException JavaDoc {
835         Integer JavaDoc scope = (Integer JavaDoc) scopes.get(scopeName.toLowerCase());
836
837         if (scope == null) {
838             throw new JspException JavaDoc(messages.getMessage("lookup.scope", scope));
839         }
840
841         return scope.intValue();
842     }
843
844     /**
845      * Look up and return current user locale, based on the specified parameters.
846      *
847      * @param pageContext The PageContext associated with this request
848      * @param locale Name of the session attribute for our user's Locale. If this is
849      * <code>null</code>, the default locale key is used for the lookup.
850      * @return current user locale
851      */

852     public Locale JavaDoc getUserLocale(PageContext JavaDoc pageContext, String JavaDoc locale) {
853         return RequestUtils.getUserLocale(
854                 (HttpServletRequest JavaDoc) pageContext.getRequest(),
855                 locale);
856     }
857
858     /**
859      * Returns true if the custom tags are in XHTML mode.
860      */

861     public boolean isXhtml(PageContext JavaDoc pageContext) {
862         String JavaDoc xhtml =
863                 (String JavaDoc) pageContext.getAttribute(
864                         Globals.XHTML_KEY,
865                         PageContext.PAGE_SCOPE);
866
867         return "true".equalsIgnoreCase(xhtml);
868     }
869
870     /**
871      * Locate and return the specified bean, from an optionally specified
872      * scope, in the specified page context. If no such bean is found,
873      * return <code>null</code> instead. If an exception is thrown, it will
874      * have already been saved via a call to <code>saveException()</code>.
875      *
876      * @param pageContext Page context to be searched
877      * @param name Name of the bean to be retrieved
878      * @param scopeName Scope to be searched (page, request, session, application)
879      * or <code>null</code> to use <code>findAttribute()</code> instead
880      * @return JavaBean in the specified page context
881      * @exception JspException if an invalid scope name
882      * is requested
883      */

884     public Object JavaDoc lookup(PageContext JavaDoc pageContext, String JavaDoc name, String JavaDoc scopeName)
885             throws JspException JavaDoc {
886
887         if (scopeName == null) {
888             return pageContext.findAttribute(name);
889         }
890
891         try {
892             return pageContext.getAttribute(name, instance.getScope(scopeName));
893
894         } catch (JspException JavaDoc e) {
895             saveException(pageContext, e);
896             throw e;
897         }
898
899     }
900
901     /**
902      * Locate and return the specified property of the specified bean, from
903      * an optionally specified scope, in the specified page context. If an
904      * exception is thrown, it will have already been saved via a call to
905      * <code>saveException()</code>.
906      *
907      * @param pageContext Page context to be searched
908      * @param name Name of the bean to be retrieved
909      * @param property Name of the property to be retrieved, or
910      * <code>null</code> to retrieve the bean itself
911      * @param scope Scope to be searched (page, request, session, application)
912      * or <code>null</code> to use <code>findAttribute()</code> instead
913      * @return property of specified JavaBean
914      *
915      * @exception JspException if an invalid scope name
916      * is requested
917      * @exception JspException if the specified bean is not found
918      * @exception JspException if accessing this property causes an
919      * IllegalAccessException, IllegalArgumentException,
920      * InvocationTargetException, or NoSuchMethodException
921      */

922     public Object JavaDoc lookup(
923             PageContext JavaDoc pageContext,
924             String JavaDoc name,
925             String JavaDoc property,
926             String JavaDoc scope)
927             throws JspException JavaDoc {
928
929         // Look up the requested bean, and return if requested
930
Object JavaDoc bean = lookup(pageContext, name, scope);
931         if (bean == null) {
932             JspException JavaDoc e = null;
933             if (scope == null) {
934                 e = new JspException JavaDoc(messages.getMessage("lookup.bean.any", name));
935             } else {
936                 e =
937                         new JspException JavaDoc(
938                                 messages.getMessage("lookup.bean", name, scope));
939             }
940             saveException(pageContext, e);
941             throw e;
942         }
943
944         if (property == null) {
945             return bean;
946         }
947
948         // Locate and return the specified property
949
try {
950             return PropertyUtils.getProperty(bean, property);
951
952         } catch (IllegalAccessException JavaDoc e) {
953             saveException(pageContext, e);
954             throw new JspException JavaDoc(
955                     messages.getMessage("lookup.access", property, name));
956
957         } catch (IllegalArgumentException JavaDoc e) {
958             saveException(pageContext, e);
959             throw new JspException JavaDoc(
960                     messages.getMessage("lookup.argument", property, name));
961
962         } catch (InvocationTargetException JavaDoc e) {
963             Throwable JavaDoc t = e.getTargetException();
964             if (t == null) {
965                 t = e;
966             }
967             saveException(pageContext, t);
968             throw new JspException JavaDoc(
969                     messages.getMessage("lookup.target", property, name));
970
971         } catch (NoSuchMethodException JavaDoc e) {
972             saveException(pageContext, e);
973             throw new JspException JavaDoc(
974                     messages.getMessage("lookup.method", property, name));
975         }
976
977     }
978
979     /**
980      * Look up and return a message string, based on the specified parameters.
981      *
982      * @param pageContext The PageContext associated with this request
983      * @param bundle Name of the servlet context attribute for our
984      * message resources bundle
985      * @param locale Name of the session attribute for our user's Locale
986      * @param key Message key to be looked up and returned
987      * @return message string
988      *
989      * @exception JspException if a lookup error occurs (will have been
990      * saved in the request already)
991      */

992     public String JavaDoc message(
993             PageContext JavaDoc pageContext,
994             String JavaDoc bundle,
995             String JavaDoc locale,
996             String JavaDoc key)
997             throws JspException JavaDoc {
998
999         return message(pageContext, bundle, locale, key, null);
1000
1001    }
1002
1003    /**
1004     * Look up and return a message string, based on the specified parameters.
1005     *
1006     * @param pageContext The PageContext associated with this request
1007     * @param bundle Name of the servlet context attribute for our
1008     * message resources bundle
1009     * @param locale Name of the session attribute for our user's Locale
1010     * @param key Message key to be looked up and returned
1011     * @param args Replacement parameters for this message
1012     * @return message string
1013     * @exception JspException if a lookup error occurs (will have been
1014     * saved in the request already)
1015     */

1016    public String JavaDoc message(
1017            PageContext JavaDoc pageContext,
1018            String JavaDoc bundle,
1019            String JavaDoc locale,
1020            String JavaDoc key,
1021            Object JavaDoc args[])
1022            throws JspException JavaDoc {
1023
1024        MessageResources resources =
1025                retrieveMessageResources(pageContext, bundle, false);
1026
1027        Locale JavaDoc userLocale = getUserLocale(pageContext, locale);
1028        String JavaDoc message = null;
1029        if (args == null) {
1030            message = resources.getMessage(userLocale, key);
1031        } else {
1032            message = resources.getMessage(userLocale, key, args);
1033        }
1034        if ((message == null) && log.isDebugEnabled()) {
1035            // log missing key to ease debugging
1036
log.debug(resources.getMessage("message.resources", key, bundle, locale));
1037        }
1038        return message;
1039    }
1040
1041    /**
1042     * <p>Return the context-relative URL that corresponds to the specified
1043     * <code>page</code> attribute value, calculated based on the
1044     * <code>pagePattern</code> property of the current module's
1045     * {@link ModuleConfig}.</p>
1046     *
1047     * @param request The servlet request we are processing
1048     * @param page The module-relative URL to be substituted in
1049     * to the <code>pagePattern</code> pattern for the current module
1050     * (<strong>MUST</strong> start with a slash)
1051     * @return context-relative URL
1052     */

1053    public String JavaDoc pageURL(HttpServletRequest JavaDoc request, String JavaDoc page, ModuleConfig moduleConfig) {
1054
1055        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1056        String JavaDoc pagePattern = moduleConfig.getControllerConfig().getPagePattern();
1057
1058        if (pagePattern == null) {
1059            sb.append(moduleConfig.getPrefix());
1060            sb.append(page);
1061
1062        } else {
1063            boolean dollar = false;
1064            for (int i = 0; i < pagePattern.length(); i++) {
1065                char ch = pagePattern.charAt(i);
1066                if (dollar) {
1067                    switch (ch) {
1068                        case 'M':
1069                            sb.append(moduleConfig.getPrefix());
1070                            break;
1071                        case 'P':
1072                            sb.append(page);
1073                            break;
1074                        case '$':
1075                            sb.append('$');
1076                            break;
1077                        default :
1078                            ; // Silently swallow
1079
}
1080                    dollar = false;
1081                    continue;
1082
1083                } else if (ch == '$') {
1084                    dollar = true;
1085
1086                } else {
1087                    sb.append(ch);
1088                }
1089            }
1090        }
1091
1092        return sb.toString();
1093    }
1094
1095    /**
1096     * Return true if a message string for the specified message key
1097     * is present for the specified Locale.
1098     *
1099     * @param pageContext The PageContext associated with this request
1100     * @param bundle Name of the servlet context attribute for our
1101     * message resources bundle
1102     * @param locale Name of the session attribute for our user's Locale
1103     * @param key Message key to be looked up and returned
1104     * @return true if a message string for message key exists
1105     * @exception JspException if a lookup error occurs (will have been
1106     * saved in the request already)
1107     */

1108    public boolean present(
1109            PageContext JavaDoc pageContext,
1110            String JavaDoc bundle,
1111            String JavaDoc locale,
1112            String JavaDoc key)
1113            throws JspException JavaDoc {
1114
1115        MessageResources resources =
1116                retrieveMessageResources(pageContext, bundle, true);
1117
1118        Locale JavaDoc userLocale = getUserLocale(pageContext, locale);
1119
1120        return resources.isPresent(userLocale, key);
1121    }
1122
1123    /**
1124     * Returns the appropriate MessageResources object for the current module and
1125     * the given bundle.
1126     *
1127     * @param pageContext Search the context's scopes for the resources.
1128     * @param bundle The bundle name to look for. If this is <code>null</code>, the
1129     * default bundle name is used.
1130     * @return MessageResources The bundle's resources stored in some scope.
1131     * @throws JspException if the MessageResources object could not be found.
1132     */

1133    public MessageResources retrieveMessageResources(
1134            PageContext JavaDoc pageContext,
1135            String JavaDoc bundle,
1136            boolean checkPageScope)
1137            throws JspException JavaDoc {
1138
1139        MessageResources resources = null;
1140
1141        if (bundle == null) {
1142            bundle = Globals.MESSAGES_KEY;
1143        }
1144
1145        if (checkPageScope) {
1146            resources =
1147                    (MessageResources) pageContext.getAttribute(
1148                            bundle,
1149                            PageContext.PAGE_SCOPE);
1150        }
1151
1152        if (resources == null) {
1153            resources =
1154                    (MessageResources) pageContext.getAttribute(
1155                            bundle,
1156                            PageContext.REQUEST_SCOPE);
1157        }
1158
1159        if (resources == null) {
1160            ModuleConfig moduleConfig = getModuleConfig(pageContext);
1161            resources =
1162                    (MessageResources) pageContext.getAttribute(
1163                            bundle + moduleConfig.getPrefix(),
1164                            PageContext.APPLICATION_SCOPE);
1165        }
1166
1167        if (resources == null) {
1168            resources =
1169                    (MessageResources) pageContext.getAttribute(
1170                            bundle,
1171                            PageContext.APPLICATION_SCOPE);
1172        }
1173
1174        if (resources == null) {
1175            JspException JavaDoc e =
1176                    new JspException JavaDoc(messages.getMessage("message.bundle", bundle));
1177            saveException(pageContext, e);
1178            throw e;
1179        }
1180
1181        return resources;
1182    }
1183
1184    /**
1185     * Save the specified exception as a request attribute for later use.
1186     *
1187     * @param pageContext The PageContext for the current page
1188     * @param exception The exception to be saved
1189     */

1190    public void saveException(PageContext JavaDoc pageContext, Throwable JavaDoc exception) {
1191
1192        pageContext.setAttribute(
1193                Globals.EXCEPTION_KEY,
1194                exception,
1195                PageContext.REQUEST_SCOPE);
1196
1197    }
1198
1199    /**
1200     * Write the specified text as the response to the writer associated with
1201     * this page. <strong>WARNING</strong> - If you are writing body content
1202     * from the <code>doAfterBody()</code> method of a custom tag class that
1203     * implements <code>BodyTag</code>, you should be calling
1204     * <code>writePrevious()</code> instead.
1205     *
1206     * @param pageContext The PageContext object for this page
1207     * @param text The text to be written
1208     *
1209     * @exception JspException if an input/output error occurs (already saved)
1210     */

1211    public void write(PageContext JavaDoc pageContext, String JavaDoc text)
1212            throws JspException JavaDoc {
1213
1214        JspWriter JavaDoc writer = pageContext.getOut();
1215
1216        try {
1217            writer.print(text);
1218
1219        } catch (IOException JavaDoc e) {
1220            TagUtils.getInstance().saveException(pageContext, e);
1221            throw new JspException JavaDoc
1222                    (messages.getMessage("write.io", e.toString()));
1223        }
1224
1225    }
1226
1227
1228    /**
1229     * Write the specified text as the response to the writer associated with
1230     * the body content for the tag within which we are currently nested.
1231     *
1232     * @param pageContext The PageContext object for this page
1233     * @param text The text to be written
1234     *
1235     * @exception JspException if an input/output error occurs (already saved)
1236     */

1237    public void writePrevious(PageContext JavaDoc pageContext, String JavaDoc text)
1238            throws JspException JavaDoc {
1239
1240        JspWriter JavaDoc writer = pageContext.getOut();
1241        if (writer instanceof BodyContent JavaDoc) {
1242            writer = ((BodyContent JavaDoc) writer).getEnclosingWriter();
1243        }
1244
1245        try {
1246            writer.print(text);
1247
1248        } catch (IOException JavaDoc e) {
1249            TagUtils.getInstance().saveException(pageContext, e);
1250            throw new JspException JavaDoc
1251                    (messages.getMessage("write.io", e.toString()));
1252        }
1253
1254    }
1255
1256}
1257
Popular Tags