View Javadoc

1   /*
2    * $Id: MessagesTag.java 376841 2006-02-10 21:01:28Z husted $
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  package org.apache.struts.taglib.html;
19  
20  import org.apache.struts.Globals;
21  import org.apache.struts.action.ActionMessage;
22  import org.apache.struts.action.ActionMessages;
23  import org.apache.struts.taglib.TagUtils;
24  import org.apache.struts.util.MessageResources;
25  
26  import javax.servlet.jsp.JspException;
27  import javax.servlet.jsp.tagext.BodyTagSupport;
28  
29  import java.util.Iterator;
30  
31  /***
32   * Custom tag that iterates the elements of a message collection. It defaults
33   * to retrieving the messages from <code>Globals.ERROR_KEY</code>, but if the
34   * message attribute is set to true then the messages will be retrieved from
35   * <code>Globals.MESSAGE_KEY</code>. This is an alternative to the default
36   * <code>ErrorsTag</code>.
37   *
38   * @version $Rev: 376841 $ $Date: 2005-11-08 23:50:53 -0500 (Tue, 08 Nov 2005)
39   *          $
40   * @since Struts 1.1
41   */
42  public class MessagesTag extends BodyTagSupport {
43      /***
44       * The message resources for this package.
45       */
46      protected static MessageResources messageResources =
47          MessageResources.getMessageResources(Constants.Package
48              + ".LocalStrings");
49  
50      /***
51       * Iterator of the elements of this error collection, while we are
52       * actually running.
53       */
54      protected Iterator iterator = null;
55  
56      /***
57       * Whether or not any error messages have been processed.
58       */
59      protected boolean processed = false;
60  
61      /***
62       * The name of the scripting variable to be exposed.
63       */
64      protected String id = null;
65  
66      /***
67       * The servlet context attribute key for our resources.
68       */
69      protected String bundle = null;
70  
71      /***
72       * The session attribute key for our locale.
73       */
74      protected String locale = Globals.LOCALE_KEY;
75  
76      /***
77       * The request attribute key for our error messages (if any).
78       */
79      protected String name = Globals.ERROR_KEY;
80  
81      /***
82       * The name of the property for which error messages should be returned,
83       * or <code>null</code> to return all errors.
84       */
85      protected String property = null;
86  
87      /***
88       * The message resource key for errors header.
89       */
90      protected String header = null;
91  
92      /***
93       * The message resource key for errors footer.
94       */
95      protected String footer = null;
96  
97      /***
98       * If this is set to 'true', then the <code>Globals.MESSAGE_KEY</code>
99       * will be used to retrieve the messages from scope.
100      */
101     protected String message = null;
102 
103     public String getId() {
104         return (this.id);
105     }
106 
107     public void setId(String id) {
108         this.id = id;
109     }
110 
111     public String getBundle() {
112         return (this.bundle);
113     }
114 
115     public void setBundle(String bundle) {
116         this.bundle = bundle;
117     }
118 
119     public String getLocale() {
120         return (this.locale);
121     }
122 
123     public void setLocale(String locale) {
124         this.locale = locale;
125     }
126 
127     public String getName() {
128         return (this.name);
129     }
130 
131     public void setName(String name) {
132         this.name = name;
133     }
134 
135     public String getProperty() {
136         return (this.property);
137     }
138 
139     public void setProperty(String property) {
140         this.property = property;
141     }
142 
143     public String getHeader() {
144         return (this.header);
145     }
146 
147     public void setHeader(String header) {
148         this.header = header;
149     }
150 
151     public String getFooter() {
152         return (this.footer);
153     }
154 
155     public void setFooter(String footer) {
156         this.footer = footer;
157     }
158 
159     public String getMessage() {
160         return (this.message);
161     }
162 
163     public void setMessage(String message) {
164         this.message = message;
165     }
166 
167     /***
168      * Construct an iterator for the specified collection, and begin looping
169      * through the body once per element.
170      *
171      * @throws JspException if a JSP exception has occurred
172      */
173     public int doStartTag() throws JspException {
174         // Initialize for a new request.
175         processed = false;
176 
177         // Were any messages specified?
178         ActionMessages messages = null;
179 
180         // Make a local copy of the name attribute that we can modify.
181         String name = this.name;
182 
183         if ((message != null) && "true".equalsIgnoreCase(message)) {
184             name = Globals.MESSAGE_KEY;
185         }
186 
187         try {
188             messages =
189                 TagUtils.getInstance().getActionMessages(pageContext, name);
190         } catch (JspException e) {
191             TagUtils.getInstance().saveException(pageContext, e);
192             throw e;
193         }
194 
195         // Acquire the collection we are going to iterate over
196         this.iterator =
197             (property == null) ? messages.get() : messages.get(property);
198 
199         // Store the first value and evaluate, or skip the body if none
200         if (!this.iterator.hasNext()) {
201             return SKIP_BODY;
202         }
203 
204         // process the first message
205         processMessage((ActionMessage) iterator.next());
206 
207         if ((header != null) && (header.length() > 0)) {
208             String headerMessage =
209                 TagUtils.getInstance().message(pageContext, bundle, locale,
210                     header);
211 
212             if (headerMessage != null) {
213                 TagUtils.getInstance().write(pageContext, headerMessage);
214             }
215         }
216 
217         // Set the processed variable to true so the
218         // doEndTag() knows processing took place
219         processed = true;
220 
221         return (EVAL_BODY_TAG);
222     }
223 
224     /***
225      * Make the next collection element available and loop, or finish the
226      * iterations if there are no more elements.
227      *
228      * @throws JspException if a JSP exception has occurred
229      */
230     public int doAfterBody() throws JspException {
231         // Render the output from this iteration to the output stream
232         if (bodyContent != null) {
233             TagUtils.getInstance().writePrevious(pageContext,
234                 bodyContent.getString());
235             bodyContent.clearBody();
236         }
237 
238         // Decide whether to iterate or quit
239         if (iterator.hasNext()) {
240             processMessage((ActionMessage) iterator.next());
241 
242             return (EVAL_BODY_TAG);
243         } else {
244             return (SKIP_BODY);
245         }
246     }
247 
248     /***
249      * Process a message.
250      */
251     private void processMessage(ActionMessage report)
252         throws JspException {
253         String msg = null;
254 
255         if (report.isResource()) {
256             msg = TagUtils.getInstance().message(pageContext, bundle, locale,
257                     report.getKey(), report.getValues());
258 
259             if (msg == null) {
260                 String bundleName = (bundle == null) ? "default" : bundle;
261 
262                 msg = messageResources.getMessage("messagesTag.notfound",
263                         report.getKey(), bundleName);
264             }
265         } else {
266             msg = report.getKey();
267         }
268 
269         if (msg == null) {
270             pageContext.removeAttribute(id);
271         } else {
272             pageContext.setAttribute(id, msg);
273         }
274     }
275 
276     /***
277      * Clean up after processing this enumeration.
278      *
279      * @throws JspException if a JSP exception has occurred
280      */
281     public int doEndTag() throws JspException {
282         if (processed && (footer != null) && (footer.length() > 0)) {
283             String footerMessage =
284                 TagUtils.getInstance().message(pageContext, bundle, locale,
285                     footer);
286 
287             if (footerMessage != null) {
288                 TagUtils.getInstance().write(pageContext, footerMessage);
289             }
290         }
291 
292         return EVAL_PAGE;
293     }
294 
295     /***
296      * Release all allocated resources.
297      */
298     public void release() {
299         super.release();
300         iterator = null;
301         processed = false;
302         id = null;
303         bundle = null;
304         locale = Globals.LOCALE_KEY;
305         name = Globals.ERROR_KEY;
306         property = null;
307         header = null;
308         footer = null;
309         message = null;
310     }
311 }