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