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.JavascriptUtils;
45  import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
46  
47  /**
48   * 
49   * @author Thomas Spiegl (latest modification by $Author: lu4242 $)
50   * @author Anton Koinov
51   * @author Martin Marinschek
52   * @version $Revision: 1230370 $ $Date: 2012-01-11 21:07:58 -0500 (Wed, 11 Jan 2012) $
53   */
54  @JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Output", type = "javax.faces.Label")
55  public class HtmlLabelRenderer extends HtmlRenderer
56  {
57      //private static final Log log = LogFactory.getLog(HtmlLabelRenderer.class);
58      private static final Logger log = Logger.getLogger(HtmlLabelRenderer.class.getName());
59  
60      @Override
61      protected boolean isCommonPropertiesOptimizationEnabled(FacesContext facesContext)
62      {
63          return true;
64      }
65  
66      @Override
67      protected boolean isCommonEventsOptimizationEnabled(FacesContext facesContext)
68      {
69          return true;
70      }
71  
72      @Override
73      public void decode(FacesContext context, UIComponent component)
74      {
75          // Check for npe
76          super.decode(context, component);
77          
78          HtmlRendererUtils.decodeClientBehaviors(context, component);
79      }
80  
81      @Override
82      public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
83      {
84          super.encodeBegin(facesContext, uiComponent); // check for NP
85  
86          ResponseWriter writer = facesContext.getResponseWriter();
87  
88          Map<String, List<ClientBehavior>> behaviors = null;
89          if (uiComponent instanceof ClientBehaviorHolder)
90          {
91              behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
92              if (!behaviors.isEmpty())
93              {
94                  ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
95              }
96          }
97          
98          encodeBefore(facesContext, writer, uiComponent);
99  
100         writer.startElement(HTML.LABEL_ELEM, uiComponent);
101         if (uiComponent instanceof ClientBehaviorHolder
102             && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
103         {
104             if (!behaviors.isEmpty())
105             {
106                 HtmlRendererUtils.writeIdAndName(writer, uiComponent, facesContext);
107             }
108             else
109             {
110                 HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
111             }
112             long commonPropertiesMarked = 0L;
113             if (isCommonPropertiesOptimizationEnabled(facesContext))
114             {
115                 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
116             }
117             if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
118             {
119                 CommonPropertyUtils.renderEventProperties(writer, 
120                         commonPropertiesMarked, uiComponent);
121                 CommonPropertyUtils.renderFocusBlurEventProperties(writer,
122                         commonPropertiesMarked, uiComponent);
123             }
124             else
125             {
126                 if (isCommonEventsOptimizationEnabled(facesContext))
127                 {
128                     Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
129                     CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
130                             commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
131                     CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
132                         facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
133                 }
134                 else
135                 {
136                     HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
137                     HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
138                             facesContext, writer,
139                             uiComponent, behaviors);
140                 }
141             }
142             if (isCommonPropertiesOptimizationEnabled(facesContext))
143             {
144                 CommonPropertyUtils.renderLabelPassthroughPropertiesWithoutEvents(writer, 
145                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
146             }
147             else
148             {
149                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
150                                                        HTML.LABEL_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
151             }
152         }
153         else
154         {
155             HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
156             if (isCommonPropertiesOptimizationEnabled(facesContext))
157             {
158                 CommonPropertyUtils.renderLabelPassthroughProperties(writer, 
159                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
160             }
161             else
162             {
163                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.LABEL_PASSTHROUGH_ATTRIBUTES);
164             }
165         }
166 
167         String forAttr = getFor(uiComponent);
168 
169         if (forAttr != null)
170         {
171             writer.writeAttribute(HTML.FOR_ATTR, getClientId(facesContext, uiComponent, forAttr), JSFAttr.FOR_ATTR);
172         }
173         else
174         {
175             if (log.isLoggable(Level.WARNING))
176             {
177                 log.warning("Attribute 'for' of label component with id " + uiComponent.getClientId(facesContext)
178                         + " is not defined");
179             }
180         }
181 
182         // MyFaces extension: Render a label text given by value
183         // TODO: Move to extended component
184         if (uiComponent instanceof ValueHolder)
185         {
186             String text = RendererUtils.getStringValue(facesContext, uiComponent);
187             if (text != null)
188             {
189                 boolean escape;
190                 if (uiComponent instanceof HtmlOutputLabel || uiComponent instanceof EscapeCapable)
191                 {
192                     escape = ((HtmlOutputLabel)uiComponent).isEscape();
193                 }
194                 else
195                 {
196                     escape = RendererUtils.getBooleanAttribute(uiComponent,
197                                                                org.apache.myfaces.shared.renderkit.JSFAttr.ESCAPE_ATTR,
198                                                                true); //default is to escape
199                 }                
200                 if (escape)
201                 {
202                     writer.writeText(text, org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
203                 }
204                 else
205                 {
206                     writer.write(text);
207                 }
208             }
209         }
210 
211         writer.flush(); // close start tag
212 
213         encodeAfterStart(facesContext, writer, uiComponent);
214     }
215 
216     /**
217      * @throws IOException  
218      */
219     protected void encodeAfterStart(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
220         throws IOException
221     {
222     }
223 
224     /**
225      * @throws IOException  
226      */
227     protected void encodeBefore(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
228         throws IOException
229     {
230     }
231 
232     protected String getFor(UIComponent component)
233     {
234         if (component instanceof HtmlOutputLabel)
235         {
236             return ((HtmlOutputLabel)component).getFor();
237         }
238 
239         return (String)component.getAttributes().get(JSFAttr.FOR_ATTR);
240 
241     }
242 
243     protected String getClientId(FacesContext facesContext, UIComponent uiComponent, String forAttr)
244     {
245         return RendererUtils.getClientId(facesContext, uiComponent, forAttr);
246     }
247 
248     @Override
249     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
250     {
251         super.encodeEnd(facesContext, uiComponent); // check for NP
252 
253         ResponseWriter writer = facesContext.getResponseWriter();
254 
255         encodeBeforeEnd(facesContext, writer, uiComponent);
256 
257         writer.endElement(HTML.LABEL_ELEM);
258 
259         encodeAfter(facesContext, writer, uiComponent);
260     }
261 
262     /**
263      * @throws IOException  
264      */
265     protected void encodeBeforeEnd(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
266         throws IOException
267     {
268     }
269 
270     /**
271      * @throws IOException  
272      */
273     protected void encodeAfter(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent)
274         throws IOException
275     {
276     }
277 }