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.shared.renderkit.html;
20  
21  import org.apache.myfaces.shared.renderkit.JSFAttr;
22  import org.apache.myfaces.shared.renderkit.RendererUtils;
23  import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
24  import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
25  
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UIInput;
28  import javax.faces.component.UIOutput;
29  import javax.faces.component.behavior.ClientBehavior;
30  import javax.faces.component.behavior.ClientBehaviorHolder;
31  import javax.faces.component.html.HtmlInputSecret;
32  import javax.faces.context.FacesContext;
33  import javax.faces.context.ResponseWriter;
34  import javax.faces.convert.ConverterException;
35  import java.io.IOException;
36  import java.util.List;
37  import java.util.Map;
38  
39  
40  /**
41   * see Spec.1.0 EA - JSF.7.6.4 Renderer Types for UIInput Components
42   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
43   * @author Thomas Spiegl
44   * @author Anton Koinov
45   * @version $Revision: 1230371 $ $Date: 2012-01-12 02:09:45 +0000 (Thu, 12 Jan 2012) $
46   */
47  public class HtmlSecretRendererBase
48          extends HtmlRenderer
49  {
50      private static final String AUTOCOMPLETE_VALUE_OFF = "off";
51  
52      public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
53              throws IOException
54      {
55          RendererUtils.checkParamValidity(facesContext, uiComponent, UIInput.class);
56  
57          ResponseWriter writer = facesContext.getResponseWriter();
58          
59          Map<String, List<ClientBehavior>> behaviors = null;
60          if (uiComponent instanceof ClientBehaviorHolder)
61          {
62              behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
63              if (!behaviors.isEmpty())
64              {
65                  ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
66              }
67          }
68          
69          //allow subclasses to render custom attributes by separating rendering begin and end
70          renderInputBegin(facesContext, uiComponent);
71          renderInputEnd(facesContext, uiComponent);
72      }
73  
74  
75      //Subclasses can set the value of an attribute before, or can render a custom attribute after calling this method
76      protected void renderInputBegin(FacesContext facesContext,
77              UIComponent uiComponent) throws IOException
78      {
79          ResponseWriter writer = facesContext.getResponseWriter();
80          
81          writer.startElement(HTML.INPUT_ELEM, uiComponent);
82          writer.writeAttribute(HTML.TYPE_ATTR, org.apache.myfaces.shared.renderkit.html.HTML.INPUT_TYPE_PASSWORD, null);
83  
84          if (uiComponent instanceof ClientBehaviorHolder 
85                  && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext())
86                  && !((ClientBehaviorHolder) uiComponent).getClientBehaviors().isEmpty())
87          {
88              writer.writeAttribute(HTML.ID_ATTR, 
89                                    uiComponent.getClientId(facesContext), null);
90          }
91          else
92          {
93              HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
94          }
95          writer.writeAttribute(HTML.NAME_ATTR,
96                                uiComponent.getClientId(facesContext), null);
97  
98          boolean isRedisplay;
99          if (uiComponent instanceof HtmlInputSecret)
100         {
101             isRedisplay = ((HtmlInputSecret)uiComponent).isRedisplay();
102         }
103         else
104         {
105             isRedisplay = org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(uiComponent, 
106                     JSFAttr.REDISPLAY_ATTR, false);
107         }
108         if (isRedisplay)
109         {
110             String strValue = RendererUtils.getStringValue(facesContext, uiComponent);
111             writer.writeAttribute(HTML.VALUE_ATTR, strValue, JSFAttr.VALUE_ATTR);
112         }
113 
114         Map<String, List<ClientBehavior>> behaviors = null;
115         if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
116                 facesContext.getExternalContext()))
117         {
118             behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
119             
120             long commonPropertiesMarked = 0L;
121             if (isCommonPropertiesOptimizationEnabled(facesContext))
122             {
123                 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
124             }
125             if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
126             {
127                 CommonPropertyUtils.renderChangeEventProperty(writer, 
128                         commonPropertiesMarked, uiComponent);
129                 CommonPropertyUtils.renderEventProperties(writer, 
130                         commonPropertiesMarked, uiComponent);
131                 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer, 
132                         commonPropertiesMarked, uiComponent);
133             }
134             else
135             {
136                 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
137                 if (isCommonEventsOptimizationEnabled(facesContext))
138                 {
139                     Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
140                     CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
141                             commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
142                     CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
143                         facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
144                 }
145                 else
146                 {
147                     HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
148                     HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
149                             facesContext, writer, uiComponent, behaviors);
150                 }
151             }
152             if (isCommonPropertiesOptimizationEnabled(facesContext))
153             {
154                 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabledAndEvents(writer, 
155                         commonPropertiesMarked, uiComponent);
156             }
157             else
158             {
159                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, 
160                         HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
161             }
162         }
163         else
164         {
165             if (isCommonPropertiesOptimizationEnabled(facesContext))
166             {
167                 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabled(writer, 
168                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
169             }
170             else
171             {
172                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, 
173                         HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
174             }
175         }
176 
177         if (isDisabled(facesContext, uiComponent))
178         {
179             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
180         }
181 
182         if (isAutocompleteOff(facesContext, uiComponent))
183         {
184             writer.writeAttribute(HTML.AUTOCOMPLETE_ATTR, AUTOCOMPLETE_VALUE_OFF, HTML.AUTOCOMPLETE_ATTR);
185         }
186     }
187 
188     protected void renderInputEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
189     {
190         ResponseWriter writer = facesContext.getResponseWriter(); 
191 
192         writer.endElement(HTML.INPUT_ELEM);
193     }
194 
195     protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
196     {
197         //TODO: overwrite in extended HtmlSecretRenderer and check for enabledOnUserRole
198         if (uiComponent instanceof HtmlInputSecret)
199         {
200             return ((HtmlInputSecret)uiComponent).isDisabled();
201         }
202 
203         return RendererUtils.getBooleanAttribute(uiComponent, HTML.DISABLED_ATTR, false);
204     }
205 
206     /**
207      * If autocomplete is "on" or not set, do not render it
208      */
209     protected boolean isAutocompleteOff(FacesContext facesContext, UIComponent component)
210     {
211         if (component instanceof HtmlInputSecret)
212         {
213             String autocomplete = ((HtmlInputSecret)component).getAutocomplete();
214             if (autocomplete != null)
215             {
216                 return autocomplete.equals(AUTOCOMPLETE_VALUE_OFF);
217             }
218         }
219 
220         return false;
221     }
222 
223     public void decode(FacesContext facesContext, UIComponent component)
224     {
225         org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIInput.class);
226         HtmlRendererUtils.decodeUIInput(facesContext, component);
227         if (component instanceof ClientBehaviorHolder &&
228                 !HtmlRendererUtils.isDisabled(component))
229         {
230             HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
231         }
232     }
233 
234     public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue)
235         throws ConverterException
236     {
237         RendererUtils.checkParamValidity(facesContext, uiComponent, UIOutput.class);
238         return RendererUtils.getConvertedUIOutputValue(facesContext,
239                                                        (UIOutput)uiComponent,
240                                                        submittedValue);
241     }
242 
243 }