View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.renderkit.html;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.logging.Level;
25  import java.util.logging.Logger;
26  
27  import javax.faces.component.UIComponent;
28  import javax.faces.component.ValueHolder;
29  import javax.faces.component.behavior.ClientBehavior;
30  import javax.faces.component.behavior.ClientBehaviorHolder;
31  import javax.faces.component.html.HtmlOutputLabel;
32  import javax.faces.context.FacesContext;
33  import javax.faces.context.ResponseWriter;
34  
35  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
36  import org.apache.myfaces.shared.component.EscapeCapable;
37  import org.apache.myfaces.shared.renderkit.JSFAttr;
38  import org.apache.myfaces.shared.renderkit.RendererUtils;
39  import org.apache.myfaces.shared.renderkit.html.CommonEventUtils;
40  import org.apache.myfaces.shared.renderkit.html.CommonPropertyUtils;
41  import org.apache.myfaces.shared.renderkit.html.HTML;
42  import org.apache.myfaces.shared.renderkit.html.HtmlRenderer;
43  import org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils;
44  import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
45  
46  /**
47   * 
48   * @author Thomas Spiegl (latest modification by $Author$)
49   * @author Anton Koinov
50   * @author Martin Marinschek
51   * @version $Revision$ $Date$
52   */
53  @JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Output", type = "javax.faces.Label")
54  public class HtmlLabelRenderer extends HtmlRenderer
55  {
56      //private static final Log log = LogFactory.getLog(HtmlLabelRenderer.class);
57      private static final Logger log = Logger.getLogger(HtmlLabelRenderer.class.getName());
58  
59      @Override
60      protected boolean isCommonPropertiesOptimizationEnabled(FacesContext facesContext)
61      {
62          return true;
63      }
64  
65      @Override
66      protected boolean isCommonEventsOptimizationEnabled(FacesContext facesContext)
67      {
68          return true;
69      }
70  
71      @Override
72      public void decode(FacesContext context, UIComponent component)
73      {
74          // Check for npe
75          super.decode(context, component);
76          
77          HtmlRendererUtils.decodeClientBehaviors(context, component);
78      }
79  
80      @Override
81      public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
82      {
83          super.encodeBegin(facesContext, uiComponent); // check for NP
84  
85          ResponseWriter writer = facesContext.getResponseWriter();
86  
87          Map<String, List<ClientBehavior>> behaviors = null;
88          if (uiComponent instanceof ClientBehaviorHolder)
89          {
90              behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
91              if (!behaviors.isEmpty())
92              {
93                  ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
94              }
95          }
96          
97          encodeBefore(facesContext, writer, uiComponent);
98  
99          writer.startElement(HTML.LABEL_ELEM, uiComponent);
100         if (uiComponent instanceof ClientBehaviorHolder)
101         {
102             if (!behaviors.isEmpty())
103             {
104                 HtmlRendererUtils.writeIdAndName(writer, uiComponent, facesContext);
105             }
106             else
107             {
108                 HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
109             }
110             long commonPropertiesMarked = 0L;
111             if (isCommonPropertiesOptimizationEnabled(facesContext))
112             {
113                 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
114             }
115             if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
116             {
117                 CommonPropertyUtils.renderEventProperties(writer, 
118                         commonPropertiesMarked, uiComponent);
119                 CommonPropertyUtils.renderFocusBlurEventProperties(writer,
120                         commonPropertiesMarked, uiComponent);
121             }
122             else
123             {
124                 if (isCommonEventsOptimizationEnabled(facesContext))
125                 {
126                     Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
127                     CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
128                             commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
129                     CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
130                         facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
131                 }
132                 else
133                 {
134                     HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
135                     HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
136                             facesContext, writer,
137                             uiComponent, behaviors);
138                 }
139             }
140             if (isCommonPropertiesOptimizationEnabled(facesContext))
141             {
142                 CommonPropertyUtils.renderLabelPassthroughPropertiesWithoutEvents(writer, 
143                         commonPropertiesMarked, uiComponent);
144             }
145             else
146             {
147                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
148                                                        HTML.LABEL_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
149             }
150         }
151         else
152         {
153             HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
154             if (isCommonPropertiesOptimizationEnabled(facesContext))
155             {
156                 CommonPropertyUtils.renderLabelPassthroughProperties(writer, 
157                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
158             }
159             else
160             {
161                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.LABEL_PASSTHROUGH_ATTRIBUTES);
162             }
163         }
164 
165         String forAttr = getFor(uiComponent);
166 
167         if (forAttr != null)
168         {
169             writer.writeAttribute(HTML.FOR_ATTR, getClientId(facesContext, uiComponent, forAttr), JSFAttr.FOR_ATTR);
170         }
171         else
172         {
173             if (log.isLoggable(Level.WARNING))
174             {
175                 log.warning("Attribute 'for' of label component with id " + uiComponent.getClientId(facesContext)
176                         + " is not defined");
177             }
178         }
179 
180         // MyFaces extension: Render a label text given by value
181         // TODO: Move to extended component
182         if (uiComponent instanceof ValueHolder)
183         {
184             String text = RendererUtils.getStringValue(facesContext, uiComponent);
185             if (text != null)
186             {
187                 boolean escape;
188                 if (uiComponent instanceof HtmlOutputLabel || uiComponent instanceof EscapeCapable)
189                 {
190                     escape = ((HtmlOutputLabel)uiComponent).isEscape();
191                 }
192                 else
193                 {
194                     escape = RendererUtils.getBooleanAttribute(uiComponent,
195                                                                org.apache.myfaces.shared.renderkit.JSFAttr.ESCAPE_ATTR,
196                                                                true); //default is to escape
197                 }                
198                 if (escape)
199                 {
200                     writer.writeText(text, org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
201                 }
202                 else
203                 {
204                     writer.write(text);
205                 }
206             }
207         }
208 
209         writer.flush(); // close start tag
210 
211         encodeAfterStart(facesContext, writer, uiComponent);
212     }
213 
214     /**
215      * @throws IOException  
216      */
217     protected void encodeAfterStart(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
218         throws IOException
219     {
220     }
221 
222     /**
223      * @throws IOException  
224      */
225     protected void encodeBefore(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
226         throws IOException
227     {
228     }
229 
230     protected String getFor(UIComponent component)
231     {
232         if (component instanceof HtmlOutputLabel)
233         {
234             return ((HtmlOutputLabel)component).getFor();
235         }
236 
237         return (String)component.getAttributes().get(JSFAttr.FOR_ATTR);
238 
239     }
240 
241     protected String getClientId(FacesContext facesContext, UIComponent uiComponent, String forAttr)
242     {
243         return RendererUtils.getClientId(facesContext, uiComponent, forAttr);
244     }
245 
246     @Override
247     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
248     {
249         super.encodeEnd(facesContext, uiComponent); // check for NP
250 
251         ResponseWriter writer = facesContext.getResponseWriter();
252 
253         encodeBeforeEnd(facesContext, writer, uiComponent);
254 
255         writer.endElement(HTML.LABEL_ELEM);
256 
257         encodeAfter(facesContext, writer, uiComponent);
258     }
259 
260     /**
261      * @throws IOException  
262      */
263     protected void encodeBeforeEnd(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
264         throws IOException
265     {
266     }
267 
268     /**
269      * @throws IOException  
270      */
271     protected void encodeAfter(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
272         throws IOException
273     {
274     }
275 }