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 javax.faces.component;
20  
21  
22  import javax.el.ValueExpression;
23  import javax.faces.context.FacesContext;
24  import javax.faces.convert.Converter;
25  
26  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
27  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
28  
29  /**
30   * Displays a value to the user.
31   */
32  @JSFComponent(defaultRendererType = "javax.faces.Text")
33  public class UIOutput extends UIComponentBase implements ValueHolder
34  {
35      public static final String COMPONENT_TYPE = "javax.faces.Output";
36      public static final String COMPONENT_FAMILY = "javax.faces.Output";
37  
38      private Converter _converter;
39  
40      /**
41       * Construct an instance of the UIOutput.
42       */
43      public UIOutput()
44      {
45          setRendererType("javax.faces.Text");
46      }
47  
48      @Override
49      public String getFamily()
50      {
51          return COMPONENT_FAMILY;
52      }
53  
54      public Object getLocalValue()
55      {
56          return  getStateHelper().get(PropertyKeys.value);
57      }
58  
59      /**
60       * Gets The initial value of this component.
61       * 
62       * @return the new value value
63       */
64      @JSFProperty
65      public Object getValue()
66      {
67          return  getStateHelper().eval(PropertyKeys.value);
68      }
69  
70      /**
71       * The initial value of this component.
72       */
73      public void setValue(Object value)
74      {
75          getStateHelper().put(PropertyKeys.value, value );
76      }
77  
78      /**
79       * An expression that specifies the Converter for this component.
80       * <p>
81       * The value can either be a static value (ID) or an EL expression. When a static id is
82       * specified, an instance of the converter type registered with that id is used. When this
83       * is an EL expression, the result of evaluating the expression must be an object that
84       * implements the Converter interface.
85       * </p>
86       */
87      @JSFProperty(partialStateHolder=true)
88      public Converter getConverter()
89      {
90          if (_converter != null)
91          {
92              return _converter;
93          }
94          ValueExpression expression = getValueExpression("converter");
95          if (expression != null)
96          {
97              return (Converter) expression.getValue(getFacesContext().getELContext());
98          }
99          return null;
100     }
101 
102     public void setConverter(Converter converter)
103     {
104         this._converter = converter;
105         if (initialStateMarked())
106         {
107             getStateHelper().put(PropertyKeys.converterSet,Boolean.TRUE);
108         }
109         // The argument converter must be inspected for the presence of the ResourceDependency annotation.
110         //_handleAnnotations(FacesContext.getCurrentInstance(), converter);
111     }
112     
113     private boolean _isSetConverter()
114     {
115         Boolean value = (Boolean) getStateHelper().get(PropertyKeys.converterSet);
116         return value == null ? false : value;
117     }
118     
119     public void markInitialState()
120     {
121         super.markInitialState();
122         if (_converter != null && 
123             _converter instanceof PartialStateHolder)
124         {
125             ((PartialStateHolder)_converter).markInitialState();
126         }
127     }
128     
129     public void clearInitialState()
130     {
131         if (initialStateMarked())
132         {
133             super.clearInitialState();
134             if (_converter != null && 
135                 _converter instanceof PartialStateHolder)
136             {
137                 ((PartialStateHolder)_converter).clearInitialState();
138             }
139         }
140     }
141     
142     enum PropertyKeys
143     {
144          value
145         , converterSet
146     }
147 
148     @Override
149     public Object saveState(FacesContext facesContext)
150     {
151         if (initialStateMarked())
152         {
153             Object parentSaved = super.saveState(facesContext);
154             Object converterSaved = null;
155             boolean nullDelta = true;
156             if (!_isSetConverter() &&
157                 _converter != null && 
158                 _converter instanceof PartialStateHolder)
159             {
160                 //Delta
161                 StateHolder holder = (StateHolder) _converter;
162                 if (!holder.isTransient())
163                 {
164                     Object attachedState = holder.saveState(facesContext);
165                     if (attachedState != null)
166                     {
167                         nullDelta = false;
168                         converterSaved = new _AttachedDeltaWrapper(_converter.getClass(),
169                             attachedState);
170                     }
171                 }
172                 else
173                 {
174                     nullDelta = false;
175                     converterSaved = null;
176                 }
177             }
178             else if (_isSetConverter() || _converter != null)
179             {
180                 // A converter that does not implement StateHolder does not need
181                 // to save/restore the state, so we can consider it inmutable.
182                 // If Call saveAttachedState(), keep the value, but do not set
183                 // nullDelta only if the converter was not set after markInitialState(),
184                 // so if the parent returns null, this part will return
185                 // null and when is restored, it will return null, but it prevents
186                 // add the attached object into the state.
187                 if (!_isSetConverter() && _converter != null &&
188                     !(_converter instanceof StateHolder))
189                 {
190                     //No op. Note converterSaved is not taken into account if
191                     //nullDelta is true.
192                 }
193                 else
194                 {
195                     //Full
196                     converterSaved = saveAttachedState(facesContext,_converter);
197                     // If _converter == null, setConverter() was called after
198                     // markInitialState(), set nullDelta to false and save the
199                     // null spot.
200                     nullDelta = false;
201                 }
202             }
203 
204             if (parentSaved == null && nullDelta)
205             {
206                 //No values
207                 return null;
208             }
209             else if (parentSaved != null && nullDelta)
210             {
211                 return new Object[]{parentSaved};
212             }
213             return new Object[]{parentSaved, converterSaved};
214         }
215         else
216         {
217             Object[] values = new Object[2];
218             values[0] = super.saveState(facesContext);
219             values[1] = saveAttachedState(facesContext,_converter);
220             return values;
221         } 
222     }
223 
224     @Override
225     public void restoreState(FacesContext facesContext, Object state)
226     {
227         if (state == null)
228         {
229             return;
230         }
231         
232         Object[] values = (Object[])state;
233         super.restoreState(facesContext,values[0]);
234         // Have values.length == 1 considers _converter is nullDelta, in that
235         // case, there is no need to do any changes, but note this will only work
236         // if UIOutput does not have any more StateHolder properties!.
237         if (values.length == 2)
238         {
239             if (values[1] instanceof _AttachedDeltaWrapper)
240             {
241                 //Delta
242                 ((StateHolder)_converter).restoreState(facesContext,
243                         ((_AttachedDeltaWrapper) values[1]).getWrappedStateObject());
244             }
245             else
246             {
247                 //Full
248                 _converter = (javax.faces.convert.Converter) restoreAttachedState(facesContext,values[1]);
249             }
250         }
251     }
252     
253     /*
254     void _handleAnnotations(FacesContext context, Object inspected)
255     {
256         if (inspected == null) {
257             return;
258         }
259         
260         ResourceDependency annotation = inspected.getClass().getAnnotation(ResourceDependency.class);
261         
262         if (annotation == null)
263         {
264             // If the ResourceDependency annotation is not present, the argument must be inspected for the presence 
265             // of the ResourceDependencies annotation. 
266             ResourceDependencies dependencies = inspected.getClass().getAnnotation(ResourceDependencies.class);
267             if (dependencies != null)
268             {
269                 // If the ResourceDependencies annotation is present, the action described in ResourceDependencies 
270                 // must be taken.
271                 for (ResourceDependency dependency : dependencies.value())
272                 {
273                     _handleResourceDependency(context, dependency);
274                 }
275             }
276         }
277         else
278         {
279             // If the ResourceDependency annotation is present, the action described in ResourceDependency must be 
280             // taken. 
281             _handleResourceDependency(context, annotation);
282         }
283     }
284     
285     private void _handleResourceDependency(FacesContext context, ResourceDependency annotation)
286     {
287         // If this annotation is not present on the class in question, no action must be taken. 
288         if (annotation != null)
289         {
290             Application application = context.getApplication();
291             
292             // Create a UIOutput instance by passing javax.faces.Output. to 
293             // Application.createComponent(java.lang.String).
294             UIOutput output = (UIOutput) application.createComponent(COMPONENT_TYPE);
295             
296             // Get the annotation instance from the class and obtain the values of the name, library, and 
297             // target attributes.
298             String name = annotation.name();
299             
300             // Obtain the renderer-type for the resource name by passing name to 
301             // ResourceHandler.getRendererTypeForResourceName(java.lang.String).
302             String rendererType = application.getResourceHandler().getRendererTypeForResourceName(name);
303             
304             // Call setRendererType on the UIOutput instance, passing the renderer-type.
305             output.setRendererType(rendererType);
306             
307             // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes().
308             Map<String, Object> attributes = output.getAttributes();
309             
310             // Store the name into the attributes Map under the key "name".
311             attributes.put("name", name);
312             
313             // If library is the empty string, let library be null.
314             String library = annotation.library();
315             if (library != null && library.length() > 0)
316             {
317                 // If library is non-null, store it under the key "library".
318                 attributes.put("library", library);
319             }
320             
321             // If target is the empty string, let target be null.
322             String target = annotation.target();
323             if (target != null && target.length() > 0)
324             {
325                 // If target is non-null, store it under the key "target".
326                 attributes.put("target", target);
327             }
328             else
329             {
330                 // Otherwise, if target is null, call UIViewRoot.addComponentResource(javax.faces.context.FacesContext, 
331                 // javax.faces.component.UIComponent), passing the UIOutput instance as the second argument.
332                 context.getViewRoot().addComponentResource(context, output);
333             }
334         }
335     }
336     */
337 }