KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > taglib > core > html > MessagesTag


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.blandware.atleap.webapp.taglib.core.html;
17
18 import com.blandware.atleap.webapp.util.core.ApplicationResources;
19 import com.blandware.atleap.webapp.util.core.WebappConstants;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.commons.beanutils.PropertyUtils;
23 import org.apache.struts.Globals;
24 import org.apache.struts.action.ActionMessage;
25 import org.apache.struts.action.ActionMessages;
26 import org.apache.struts.taglib.TagUtils;
27
28 import javax.servlet.http.HttpServletRequest JavaDoc;
29 import javax.servlet.jsp.JspException JavaDoc;
30 import javax.servlet.jsp.PageContext JavaDoc;
31 import javax.servlet.jsp.tagext.SimpleTagSupport JavaDoc;
32 import java.io.PrintWriter JavaDoc;
33 import java.io.StringWriter JavaDoc;
34 import java.util.Iterator JavaDoc;
35
36 /**
37  * <p>Displays set of ActionMessages on the page. This tag behaviour is like the
38  * Struts ErrorsTag, except of some features. <br />
39  * The first difference is an algorithm of obtaining messages/errors. It firstly
40  * tries to obtain messages by <code>WebappConstants.MESSAGE_KEY</code>: firstly
41  * from request and, if not found, from session; if nothing was found for that
42  * key, then trying to obtain them from request by Struts key
43  * (<code>Globals.MESSAGE_KEY</code>). If no messages were found, then errors
44  * are searched: in session and (if not found) request by
45  * <code>WebappConstants.ERROR_KEY</code> key and further in request by
46  * <code>Globals.ERROR_KEY</code>. <br />
47  * If there are no action errors or messages, this tag simply does nothing.
48  * After displaying tag removes attributes from request and session, so errors
49  * will be displayed only once and will not be redisplayed on page reload. <br />
50  * The second difference is that this tag does not accept String or String array
51  * as a set of action errors - only ActionMessages object.
52  * </p>
53  * <p>
54  * This tag also accepts standard keys such as <code>errors.header</code>,
55  * <code>errors.footer</code> etc. and if they present, they will be used to
56  * display.
57  * </p>
58  * <p>
59  * Allowed attributes are:
60  * <ul>
61  * <li>
62  * <b>property</b> - property to display ActionMessage for. If not specified,
63  * all errors will be displayed.
64  * </li>
65  * <li>
66  * <b>stackTraceVar</b> - name of variable to save stack trace of exception in.
67  * If specified and exception is found, stack trace of this exception will be
68  * printed to string and saved in specified variable. Otherwise, it will be
69  * enclosed in &lt;pre&gt;&lt;/pre&gt; tags and printed to JSP out.
70  * </li>
71  * <li>
72  * <b>stackTraceVarScope</b> - scope to save variable that holds stack trace of
73  * exception
74  * </li>
75  * </ul>
76  * </p>
77  * <p><a HREF="MessagesTag.java.htm"><i>View Source</i></a></p>
78  *
79  * @author Sergey Zubtcovskii <a HREF="mailto:sergey.zubtcovskii@blandware.com">&lt;sergey.zubtcovskii@blandware.com&gt;</a>
80  * @version $Revision: 1.8 $ $Date: 2005/10/31 07:19:35 $
81  * @jsp.tag name="messages"
82  * body-content="empty"
83  * @see org.apache.struts.taglib.html.ErrorsTag
84  * @see org.apache.struts.action.ActionMessages
85  * @see org.apache.struts.taglib.html.BaseTag
86  */

87 public class MessagesTag extends SimpleTagSupport JavaDoc {
88
89     protected transient final Log log = LogFactory.getLog(MessagesTag.class);
90
91     /**
92      * Property to display ActionMessage for. If not specified, all errors will be displayed.
93      */

94     protected String JavaDoc property;
95
96     /**
97      * Variable to save stack trace of exception in. If specified and exception is found,
98      * stack trace of this exception will be printed to string and saved in specified variable.
99      * Otherwise, it will be enclosed in &lt;pre&gt;&lt;/pre&gt; tags and printed to JSP out
100      */

101     protected String JavaDoc stackTraceVar;
102
103     /**
104      * Scope to save variable that holds stack trace of exception
105      */

106     protected String JavaDoc stackTraceVarScope;
107
108     /**
109      * Returns property name
110      *
111      * @return property name
112      * @see #property
113      * @jsp.attribute required="false"
114      * rtexprvalue="true"
115      * type="java.lang.String"
116      * description="The server name to use"
117      */

118     public String JavaDoc getProperty() {
119         return property;
120     }
121
122     /**
123      * Sets property name
124      *
125      * @param property property name to set
126      * @see #property
127      */

128     public void setProperty(String JavaDoc property) {
129         this.property = property;
130     }
131
132     /**
133      * Returns stack trace variable name
134      *
135      * @return stack trace variable name
136      * @see #stackTraceVar
137      * @jsp.attribute required="false"
138      * rtexprvalue="true"
139      * type="java.lang.String"
140      * description="Variable to save stack trace of exception in"
141      */

142     public String JavaDoc getStackTraceVar() {
143         return stackTraceVar;
144     }
145
146     /**
147      * Sets stack trace variable name
148      *
149      * @param stackTraceVar stack trace variable name to set
150      * @see #stackTraceVar
151      */

152     public void setStackTraceVar(String JavaDoc stackTraceVar) {
153         this.stackTraceVar = stackTraceVar;
154     }
155
156     /**
157      * Returns stack trace variable scope
158      *
159      * @return stack trace variable scope
160      * @see #stackTraceVarScope
161      * @jsp.attribute required="false"
162      * rtexprvalue="true"
163      * type="java.lang.String"
164      * description="Scope to save variable that holds stack trace of exception"
165      */

166     public String JavaDoc getStackTraceVarScope() {
167         return stackTraceVarScope;
168     }
169
170     /**
171      * Sets stack trace variable scope
172      *
173      * @param stackTraceVarScope stack trace variable scope to set
174      * @see #stackTraceVarScope
175      */

176     public void setStackTraceVarScope(String JavaDoc stackTraceVarScope) {
177         this.stackTraceVarScope = stackTraceVarScope;
178     }
179
180     /**
181      * Processes the tag
182      *
183      * @throws JspException
184      */

185     public void doTag() throws JspException JavaDoc {
186
187         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
188
189         boolean messagesPresent = true;
190
191         // first search for messages
192
ActionMessages messages = (ActionMessages) pageContext.getAttribute(WebappConstants.MESSAGE_KEY, PageContext.REQUEST_SCOPE);
193         if ( !containRequestedMessage(messages) ) {
194             messages = (ActionMessages) pageContext.getAttribute(WebappConstants.MESSAGE_KEY, PageContext.SESSION_SCOPE);
195             if ( !containRequestedMessage(messages) ) {
196                 messages = (ActionMessages) pageContext.getAttribute(Globals.MESSAGE_KEY, PageContext.REQUEST_SCOPE);
197             } else {
198                 pageContext.setAttribute(WebappConstants.MESSAGE_KEY, messages, PageContext.REQUEST_SCOPE);
199                 pageContext.removeAttribute(WebappConstants.MESSAGE_KEY, PageContext.SESSION_SCOPE);
200             }
201         }
202
203         // if not found, search for errors
204
if ( !containRequestedMessage(messages) ) {
205             messagesPresent = false;
206             messages = (ActionMessages) pageContext.getAttribute(WebappConstants.ERROR_KEY, PageContext.REQUEST_SCOPE);
207             if ( !containRequestedMessage(messages) ) {
208                 messages = (ActionMessages) pageContext.getAttribute(WebappConstants.ERROR_KEY, PageContext.SESSION_SCOPE);
209                 if ( !containRequestedMessage(messages) ) {
210                     messages = (ActionMessages) pageContext.getAttribute(Globals.ERROR_KEY, PageContext.REQUEST_SCOPE);
211                     if ( !containRequestedMessage(messages) ) {
212                         messages = new ActionMessages();
213                     }
214                 } else {
215                     pageContext.setAttribute(WebappConstants.ERROR_KEY, messages, PageContext.REQUEST_SCOPE);
216                     pageContext.removeAttribute(WebappConstants.ERROR_KEY, PageContext.SESSION_SCOPE);
217                 }
218             }
219         }
220
221
222         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
223         TagUtils tagUtils = TagUtils.getInstance();
224         ApplicationResources applicationResources = ApplicationResources.getInstance(pageContext.getServletContext());
225         StringBuffer JavaDoc exceptionBuffer = null;
226
227         // if property is not specified, put exception from tags and/or actions
228
if ( property == null ) {
229             // search for exceptions from tags or actions and write them to the output
230
Throwable JavaDoc t = (Throwable JavaDoc) pageContext.findAttribute("javax.servlet.error.exception");
231             if ( t == null ) {
232                 t = (Throwable JavaDoc) pageContext.findAttribute("javax.servlet.error.jspException");
233                 if ( t == null ) {
234                     t = (Throwable JavaDoc) pageContext.findAttribute(Globals.EXCEPTION_KEY);
235                 }
236             }
237
238             if ( t != null ) {
239                 // get stack trace
240

241                 // look for 'rootCause' property
242
// if it exists, process it instead of caught throwable
243
try {
244                     Throwable JavaDoc rootCause = (Throwable JavaDoc) PropertyUtils.getProperty(t, "rootCause");
245                     if ( rootCause != null ) {
246                         t = rootCause;
247                     }
248                 } catch ( Exception JavaDoc e ) {
249                     // ignore it
250
}
251                 StringWriter JavaDoc sw = new StringWriter JavaDoc();
252                 t.printStackTrace(new PrintWriter JavaDoc(sw));
253                 exceptionBuffer = new StringBuffer JavaDoc(sw.toString());
254
255                 logException(t);
256             }
257         }
258
259         if ( messages != null && !messages.isEmpty() ) {
260
261             // messages are present and not empty
262

263             String JavaDoc headerKey = messagesPresent ? "core.commons.messages.header" : "core.commons.errors.header";
264             String JavaDoc footerKey = messagesPresent ? "core.commons.messages.footer" : "core.commons.errors.footer";
265             String JavaDoc prefixKey = messagesPresent ? "core.commons.messages.prefix" : "core.commons.errors.prefix";
266             String JavaDoc suffixKey = messagesPresent ? "core.commons.messages.suffix" : "core.commons.errors.suffix";
267
268             String JavaDoc header = applicationResources.getMessage(request, headerKey);
269             String JavaDoc footer = applicationResources.getMessage(request, footerKey);
270             String JavaDoc prefix = applicationResources.getMessage(request, prefixKey);
271             String JavaDoc suffix = applicationResources.getMessage(request, suffixKey);
272
273             Iterator JavaDoc reports = property == null ? messages.get() : messages.get(property);
274
275             StringBuffer JavaDoc results = new StringBuffer JavaDoc();
276             if ( header != null && property == null ) {
277                 results.append(header);
278             }
279             while ( reports.hasNext() ) {
280                 ActionMessage report = (ActionMessage) reports.next();
281                 if ( report == null ) {
282                     continue;
283                 }
284                 if ( prefix != null ) {
285                     results.append(prefix);
286                 }
287
288                 String JavaDoc message = applicationResources.getMessage(request, report.getKey(), report.getValues());
289                 if ( message != null ) {
290                     results.append(message);
291                 }
292
293                 if ( suffix != null ) {
294                     results.append(suffix);
295                 }
296
297             }
298
299             if ( header != null && footer != null && property == null ) {
300                 results.append(footer);
301             }
302
303             tagUtils.write(pageContext, results.toString());
304         }
305
306         if ( exceptionBuffer != null ) {
307             if ( stackTraceVar != null ) {
308                 int varScope = PageContext.PAGE_SCOPE;
309                 if ( stackTraceVarScope != null ) {
310                     varScope = tagUtils.getScope(stackTraceVarScope);
311                 }
312                 pageContext.setAttribute(stackTraceVar, exceptionBuffer.toString(), varScope);
313             } else {
314                 tagUtils.write(pageContext, new StringBuffer JavaDoc("<pre>").append(exceptionBuffer).append("</pre>").toString());
315             }
316         }
317     }
318
319     /**
320      * Returns <code>true</code> if specified ActionMessages object is not null and is not empty
321      *
322      * @param messages ActionMessages object to check
323      * @return <code>true</code> if specified ActionMessages object is not null and is not empty
324      */

325     protected boolean containRequestedMessage(ActionMessages messages) {
326         if ( messages == null ) {
327             return false;
328         }
329
330         Iterator JavaDoc reports = null;
331         if ( property == null ) {
332             reports = messages.get();
333         } else {
334             reports = messages.get(property);
335         }
336         return reports != null && reports.hasNext();
337     }
338
339     /**
340      * Logs the thrown exception
341      *
342      * @param t exception to log
343      */

344     protected void logException(Throwable JavaDoc t) {
345         StringWriter JavaDoc sw = new StringWriter JavaDoc();
346         t.printStackTrace(new PrintWriter JavaDoc(sw));
347         if ( log.isErrorEnabled() ) {
348             log.error(sw.toString());
349         }
350     }
351
352 }
353
Popular Tags