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