View Javadoc

1   /*
2    * Copyright 2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.myfaces.taglib;
17  
18  import org.apache.myfaces.el.SimpleActionMethodBinding;
19  import org.apache.myfaces.renderkit.JSFAttr;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import javax.faces.component.*;
25  import javax.faces.context.FacesContext;
26  import javax.faces.convert.Converter;
27  import javax.faces.el.MethodBinding;
28  import javax.faces.el.ValueBinding;
29  import javax.faces.event.ActionEvent;
30  import javax.faces.event.ValueChangeEvent;
31  import javax.faces.webapp.UIComponentTag;
32  
33  /***
34   * @author Manfred Geiler (latest modification by $Author: imario $)
35   * @version $Revision: 379833 $ $Date: 2006-02-22 18:28:08 +0000 (Wed, 22 Feb 2006) $
36   */
37  public class UIComponentTagUtils
38  {
39      private static final Log log = LogFactory.getLog(UIComponentTagUtils.class);
40  
41      private static final Class[] VALIDATOR_ARGS = {FacesContext.class,
42                                                     UIComponent.class,
43                                                     Object.class};
44      private static final Class[] ACTION_LISTENER_ARGS = {ActionEvent.class};
45      private static final Class[] VALUE_LISTENER_ARGS = {ValueChangeEvent.class};
46  
47      private UIComponentTagUtils() {}    //util class, no instantiation allowed
48  
49  
50      public static boolean isValueReference(String v)
51      {
52          return UIComponentTag.isValueReference(v);
53      }
54  
55  
56      public static void setIntegerProperty(FacesContext context,
57                                            UIComponent component,
58                                            String propName,
59                                            String value)
60      {
61          if (value != null)
62          {
63              if (isValueReference(value))
64              {
65                  ValueBinding vb = context.getApplication().createValueBinding(value);
66                  component.setValueBinding(propName, vb);
67              }
68              else
69              {
70                  //FIXME: should use converter maybe?
71                  component.getAttributes().put(propName, Integer.valueOf(value));
72              }
73          }
74      }
75  
76      public static void setLongProperty(FacesContext context, 
77                                         UIComponent component,
78                                         String propName, 
79                                         String value)
80      {
81          if (value != null)
82          {
83              if (isValueReference(value))
84              {
85                  ValueBinding vb = context.getApplication().createValueBinding(value);
86                  component.setValueBinding(propName, vb);
87              }
88              else
89              {
90                  //FIXME: should use converter maybe?
91                  component.getAttributes().put(propName, Long.valueOf(value));
92              }
93          }
94      }
95  
96      public static void setStringProperty(FacesContext context,
97                                       UIComponent component,
98                                       String propName,
99                                       String value)
100     {
101         if (value != null)
102         {
103             if (isValueReference(value))
104             {
105                 ValueBinding vb = context.getApplication().createValueBinding(value);
106                 component.setValueBinding(propName, vb);
107             }
108             else
109             {
110                 //TODO: Warning if component has no such property (with reflection)
111                 component.getAttributes().put(propName, value);
112             }
113         }
114     }
115 
116 
117     public static void setBooleanProperty(FacesContext context,
118                                       UIComponent component,
119                                       String propName,
120                                       String value)
121     {
122         if (value != null)
123         {
124             if (isValueReference(value))
125             {
126                 ValueBinding vb = context.getApplication().createValueBinding(value);
127                 component.setValueBinding(propName, vb);
128             }
129             else
130             {
131                 //TODO: More sophisticated way to convert boolean value (yes/no, 1/0, on/off, etc.)
132                 component.getAttributes().put(propName, Boolean.valueOf(value));
133             }
134         }
135     }
136 
137 
138     public static void setValueProperty(FacesContext context,
139                                         UIComponent component,
140                                         String value)
141     {
142         if (value != null)
143         {
144             if (isValueReference(value))
145             {
146                 ValueBinding vb = context.getApplication().createValueBinding(value);
147                 component.setValueBinding(JSFAttr.VALUE_ATTR, vb);
148             }
149             else if (component instanceof UICommand)
150             {
151                 ((UICommand)component).setValue(value);
152             }
153             else if (component instanceof UIParameter)
154             {
155                 ((UIParameter)component).setValue(value);
156             }
157             else if (component instanceof UISelectBoolean)
158             {
159                 ((UISelectBoolean)component).setValue(Boolean.valueOf(value));
160             }
161             else if (component instanceof UIGraphic)
162             {
163                 ((UIGraphic)component).setValue(value);
164             }
165             //Since many input components are ValueHolders the special components
166             //must come first, ValueHolder is the last resort.
167             else if (component instanceof ValueHolder)
168             {
169                 ((ValueHolder)component).setValue(value);
170             }
171             else
172             {
173                 log.error("Component " + component.getClass().getName() + " is no ValueHolder, cannot set value.");
174             }
175         }
176     }
177 
178 
179     public static void setConverterProperty(FacesContext context,
180                                         UIComponent component,
181                                         String value)
182     {
183         if (value != null)
184         {
185             if (component instanceof ValueHolder)
186             {
187                 if (isValueReference(value))
188                 {
189                     ValueBinding vb = context.getApplication().createValueBinding(value);
190                     component.setValueBinding(JSFAttr.CONVERTER_ATTR, vb);
191                 }
192                 else
193                 {
194                     FacesContext facesContext = FacesContext.getCurrentInstance();
195                     Converter converter = facesContext.getApplication().createConverter(value);
196                     ((ValueHolder)component).setConverter(converter);
197                 }
198             }
199             else
200             {
201                 log.error("Component " + component.getClass().getName() + " is no ValueHolder, cannot set value.");
202             }
203         }
204     }
205 
206 
207     public static void setValidatorProperty(FacesContext context,
208                                             UIComponent component,
209                                             String validator)
210     {
211         if (validator != null)
212         {
213             if (!(component instanceof EditableValueHolder))
214             {
215                 throw new IllegalArgumentException("Component " + component.getClientId(context) + " is no EditableValueHolder");
216             }
217             if (isValueReference(validator))
218             {
219                 MethodBinding mb = context.getApplication().createMethodBinding(validator,
220                                                                                 VALIDATOR_ARGS);
221                 ((EditableValueHolder)component).setValidator(mb);
222             }
223             else
224             {
225                 log.error("Component " + component.getClientId(context) + " has invalid validation expression " + validator);
226             }
227         }
228     }
229 
230     public static void setValueBinding(FacesContext context,
231                                        UIComponent component,
232                                        String propName,
233                                        String value)
234     {
235         if (value != null)
236         {
237             if (isValueReference(value))
238             {
239                 ValueBinding vb = context.getApplication().createValueBinding(value);
240                 component.setValueBinding(propName, vb);
241             }
242             else
243             {
244                 throw new IllegalArgumentException("Component " + component.getClientId(context) + " attribute " + propName + " must be a value reference, was " + value);
245             }
246         }
247     }
248 
249     public static void setActionProperty(FacesContext context,
250                                          UIComponent component,
251                                          String action)
252     {
253         if (action != null)
254         {
255             if (!(component instanceof ActionSource))
256             {
257                 throw new IllegalArgumentException("Component " + component.getClientId(context) + " is no ActionSource");
258             }
259             MethodBinding mb;
260             if (isValueReference(action))
261             {
262                 mb = context.getApplication().createMethodBinding(action, null);
263             }
264             else
265             {
266                 mb = new SimpleActionMethodBinding(action);
267             }
268             ((ActionSource)component).setAction(mb);
269         }
270     }
271 
272     public static void setActionListenerProperty(FacesContext context,
273                                                  UIComponent component,
274                                                  String actionListener)
275     {
276         if (actionListener != null)
277         {
278             if (!(component instanceof ActionSource))
279             {
280                 throw new IllegalArgumentException("Component " + component.getClientId(context) + " is no ActionSource");
281             }
282             if (isValueReference(actionListener))
283             {
284                 MethodBinding mb = context.getApplication().createMethodBinding(actionListener,
285                                                                                 ACTION_LISTENER_ARGS);
286 
287                 /***
288                 if(! Void.class.equals(mb.getType(context)))
289                 {
290                     throw new IllegalArgumentException(
291                             actionListener +
292                             " : Return types for action listeners must be void, see JSF spec. 3.2.1.1");
293                 }
294                 */
295 
296                 ((ActionSource)component).setActionListener(mb);
297             }
298             else
299             {
300                 log.error("Component " + component.getClientId(context) + " has invalid actionListener value: " + actionListener);
301             }
302         }
303     }
304 
305     public static void setValueChangedListenerProperty(FacesContext context,
306                                                        UIComponent component,
307                                                        String valueChangedListener)
308     {
309         if (valueChangedListener != null)
310         {
311             if (!(component instanceof EditableValueHolder))
312             {
313                 throw new IllegalArgumentException("Component " + component.getClientId(context) + " is no EditableValueHolder");
314             }
315             if (isValueReference(valueChangedListener))
316             {
317                 MethodBinding mb = context.getApplication().createMethodBinding(valueChangedListener,
318                                                                                 VALUE_LISTENER_ARGS);
319                 /***
320                 if(! Void.class.equals(mb.getType(context)))
321                 {
322                     throw new IllegalArgumentException(
323                             valueChangedListener + 
324                             " : Return types for value change listeners must be void, see JSF spec. 3.2.5.1");
325                 }
326                 */
327 
328                 ((EditableValueHolder)component).setValueChangeListener(mb);
329             }
330             else
331             {
332                 log.error("Component " + component.getClientId(context) + " has invalid valueChangedListener expression " + valueChangedListener);
333             }
334         }
335     }
336 
337 }