View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
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  
17  package org.apache.struts.faces.renderer;
18  
19  
20  import java.beans.Beans;
21  import java.io.IOException;
22  import java.util.Iterator;
23  import java.util.Locale;
24  
25  import javax.faces.application.FacesMessage;
26  import javax.faces.component.UIComponent;
27  import javax.faces.context.FacesContext;
28  import javax.faces.context.ResponseWriter;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.struts.Globals;
33  import org.apache.struts.action.ActionMessages;
34  import org.apache.struts.action.ActionMessage;
35  import org.apache.struts.util.MessageResources;
36  
37  
38  /***
39   * <p><code>Renderer</code> implementation for the <code>errors</code> tag
40   * from the <em>Struts-Faces Integration Library</em>.</p>
41   *
42   * @version $Rev: 421138 $ $Date: 2006-07-11 22:41:40 -0700 (Tue, 11 Jul 2006) $
43   */
44  
45  public class ErrorsRenderer extends AbstractRenderer {
46  
47  
48      // -------------------------------------------------------- Static Variables
49  
50  
51      /***
52       * <p>The <code>Log</code> instance for this class.</p>
53       */
54      private static Log log = LogFactory.getLog(ErrorsRenderer.class);
55  
56  
57      /***
58       * The dummy message resources for this package.
59       */
60      protected static MessageResources dummy =
61        MessageResources.getMessageResources
62          ("org.apache.struts.faces.renderer.Dummy");
63  
64      // ---------------------------------------------------------- Public Methods
65  
66  
67      /***
68       * <p>Render a combination of error messages from JavaServer Faces
69       * <code>Validator</code>s, and Struts messages from form bean
70       * <code>validate()</code> methods and corresponding business logic
71       * error checks.</p>
72       *
73       * @param context FacesContext for the request we are processing
74       * @param component UIComponent to be rendered
75       *
76       * @exception IOException if an input/output error occurs while rendering
77       * @exception NullPointerException if <code>context</code>
78       *  or <code>component</code> is null
79       */
80      public void encodeEnd(FacesContext context, UIComponent component)
81          throws IOException {
82  
83          if ((context == null) || (component == null)) {
84              throw new NullPointerException();
85          }
86  
87          if (log.isDebugEnabled()) {
88              log.debug("encodeEnd() started");
89          }
90  
91          // Look up availability of our predefined resource keys
92          MessageResources resources = resources(context, component);
93          if (Beans.isDesignTime() && (resources == null)) {
94              resources = dummy;
95          }
96          Locale locale = context.getViewRoot().getLocale();
97          boolean headerPresent = resources.isPresent(locale, "errors.header");
98          boolean footerPresent = resources.isPresent(locale, "errors.footer");
99          boolean prefixPresent = resources.isPresent(locale, "errors.prefix");
100         boolean suffixPresent = resources.isPresent(locale, "errors.suffix");
101 
102         // Set up to render the error messages appropriately
103         boolean headerDone = false;
104         ResponseWriter writer = context.getResponseWriter();
105         String id = component.getId();
106         String property = (String) component.getAttributes().get("property");
107         if (id != null) {
108             writer.startElement("span", component);
109             if (id != null) {
110                 writer.writeAttribute("id", component.getClientId(context),
111                                       "id");
112             }
113         }
114 
115         // Render any JavaServer Faces messages
116         Iterator messages = context.getMessages(property);
117         while (messages.hasNext()) {
118             FacesMessage message = (FacesMessage) messages.next();
119             if (log.isTraceEnabled()) {
120                 log.trace("Processing FacesMessage: " + message.getSummary());
121             }
122             if (!headerDone) {
123                 if (headerPresent) {
124                     writer.write
125                         (resources.getMessage(locale, "errors.header"));
126                 }
127                 headerDone = true;
128             }
129             if (prefixPresent) {
130                 writer.write(resources.getMessage(locale, "errors.prefix"));
131             }
132             writer.write(message.getSummary());
133             if (suffixPresent) {
134                 writer.write(resources.getMessage(locale, "errors.suffix"));
135             }
136         }
137 
138         // Render any Struts messages
139         ActionMessages errors = (ActionMessages)
140             context.getExternalContext().getRequestMap().get
141             (Globals.ERROR_KEY);
142         if (errors != null) {
143             if (log.isTraceEnabled()) {
144                 log.trace("Processing Struts messages for property '" +
145                           property + "'");
146             }
147             Iterator reports = null;
148             if (property == null) {
149                 reports = errors.get();
150             } else {
151                 reports = errors.get(property);
152             }
153             while (reports.hasNext()) {
154                 ActionMessage report = (ActionMessage) reports.next();
155                 if (log.isTraceEnabled()) {
156                     log.trace("Processing Struts message key='" +
157                               report.getKey() + "'");
158                 }
159                 if (!headerDone) {
160                     writer = context.getResponseWriter();
161                     if (headerPresent) {
162                         writer.write
163                             (resources.getMessage(locale, "errors.header"));
164                     }
165                     headerDone = true;
166                 }
167                 if (prefixPresent) {
168                     writer.write
169                         (resources.getMessage(locale, "errors.prefix"));
170                 }
171                 writer.write(resources.getMessage(locale, report.getKey(),
172                                                   report.getValues()));
173                 if (suffixPresent) {
174                     writer.write
175                         (resources.getMessage(locale, "errors.suffix"));
176                 }
177             }
178         }
179 
180         // Append the list footer if needed
181         if (headerDone && footerPresent) {
182             writer.write(resources.getMessage(locale, "errors.footer"));
183         }
184         if (id != null) {
185             writer.endElement("span");
186         }
187 
188         if (log.isDebugEnabled()) {
189             log.debug("encodeEnd() finished");
190         }
191 
192     }
193 
194 
195 
196     // ------------------------------------------------------ Protected Methods
197 
198 
199     /***
200      * <p>Return the <code>MessageResources</code> bundle from which
201      * we should return any Struts based error messages.  If no such
202      * bundle can be located, return <code>null</code>.</p>
203      *
204      * @param context FacesContext for the request we are processing
205      * @param component UIComponent to be rendered
206      */
207     protected MessageResources resources(FacesContext context,
208                                          UIComponent component) {
209 
210         String bundle = (String) component.getAttributes().get("bundle");
211         if (bundle == null) {
212             bundle = Globals.MESSAGES_KEY;
213         }
214         return ((MessageResources)
215                 context.getExternalContext().getApplicationMap().get(bundle));
216 
217     }
218 
219 
220 }