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.trinidad.facelets;
20  
21  import java.io.Serializable;
22  
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  
26  import javax.el.ELException;
27  import javax.el.MethodExpression;
28  
29  import javax.faces.context.FacesContext;
30  import javax.faces.el.EvaluationException;
31  import javax.faces.el.MethodBinding;
32  
33  import javax.faces.el.MethodNotFoundException;
34  import javax.faces.view.facelets.FaceletContext;
35  import javax.faces.view.facelets.MetaRule;
36  import javax.faces.view.facelets.Metadata;
37  import javax.faces.view.facelets.MetadataTarget;
38  import javax.faces.view.facelets.TagAttribute;
39  import javax.faces.view.facelets.TagAttributeException;
40  
41  /**
42   * Optional Rule for binding Method[Binding|Expression] properties
43   *
44   * @author Mike Kienenberger
45   * @author Jacob Hookom
46   * 
47   * Implementation copied from Facelets 1.1.14, as it got hidden by JSF 2.0
48   */
49  public class MethodRule extends MetaRule {
50  
51      private final String methodName;
52  
53      private final Class returnTypeClass;
54  
55      private final Class[] params;
56  
57      public MethodRule(String methodName, Class returnTypeClass,
58                        Class[] params) {
59          this.methodName = methodName;
60          this.returnTypeClass = returnTypeClass;
61          this.params = params;
62      }
63  
64      public Metadata applyRule(String name, TagAttribute attribute,
65                                MetadataTarget meta) {
66          if (false == name.equals(this.methodName))
67              return null;
68  
69          if (MethodBinding.class.equals(meta.getPropertyType(name))) {
70              Method method = meta.getWriteMethod(name);
71              if (method != null) {
72                  return new MethodBindingMetadata(method, attribute,
73                                                   this.returnTypeClass,
74                                                   this.params);
75              }
76          } else if (MethodExpression.class.equals(meta.getPropertyType(name))) {
77              Method method = meta.getWriteMethod(name);
78              if (method != null) {
79                  return new MethodExpressionMetadata(method, attribute,
80                                                      this.returnTypeClass,
81                                                      this.params);
82              }
83          }
84  
85          return null;
86      }
87  
88      private static class MethodBindingMetadata extends Metadata {
89          private final Method _method;
90  
91          private final TagAttribute _attribute;
92  
93          private Class[] _paramList;
94  
95          private Class _returnType;
96  
97          public MethodBindingMetadata(Method method, TagAttribute attribute,
98                                       Class returnType, Class[] paramList) {
99              _method = method;
100             _attribute = attribute;
101             _paramList = paramList;
102             _returnType = returnType;
103         }
104 
105         public void applyMetadata(FaceletContext ctx, Object instance) {
106             MethodExpression expr =
107                 _attribute.getMethodExpression(ctx, _returnType, _paramList);
108 
109             try {
110                 _method.invoke(instance,
111                                new Object[] { new LegacyMethodBinding(expr) });
112             } catch (InvocationTargetException e) {
113                 throw new TagAttributeException(_attribute, e.getCause());
114             } catch (Exception e) {
115                 throw new TagAttributeException(_attribute, e);
116             }
117         }
118     }
119 
120     private static class MethodExpressionMetadata extends Metadata {
121         private final Method _method;
122 
123         private final TagAttribute _attribute;
124 
125         private Class[] _paramList;
126 
127         private Class _returnType;
128 
129         public MethodExpressionMetadata(Method method, TagAttribute attribute,
130                                         Class returnType, Class[] paramList) {
131             _method = method;
132             _attribute = attribute;
133             _paramList = paramList;
134             _returnType = returnType;
135         }
136 
137         public void applyMetadata(FaceletContext ctx, Object instance) {
138             MethodExpression expr =
139                 _attribute.getMethodExpression(ctx, _returnType, _paramList);
140 
141             try {
142                 _method.invoke(instance, new Object[] { expr });
143             } catch (InvocationTargetException e) {
144                 throw new TagAttributeException(_attribute, e.getCause());
145             } catch (Exception e) {
146                 throw new TagAttributeException(_attribute, e);
147             }
148         }
149     }
150     
151 
152     private static class LegacyMethodBinding extends MethodBinding implements Serializable {
153 
154         private static final long serialVersionUID = 1L;
155 
156         private final MethodExpression m;
157 
158         public LegacyMethodBinding(MethodExpression m) {
159             this.m = m;
160         }
161 
162         /*
163        * (non-Javadoc)
164        *
165        * @see javax.faces.el.MethodBinding#getType(javax.faces.context.FacesContext)
166        */
167 
168         public Class getType(FacesContext context) throws MethodNotFoundException {
169             try {
170                 return m.getMethodInfo(context.getELContext()).getReturnType();
171             } catch (javax.el.MethodNotFoundException e) {
172                 throw new MethodNotFoundException(e.getMessage(),
173                                                   e.getCause());
174             } catch (ELException e) {
175                 throw new EvaluationException(e.getMessage(), e.getCause());
176             }
177         }
178 
179         /*
180        * (non-Javadoc)
181        *
182        * @see javax.faces.el.MethodBinding#invoke(javax.faces.context.FacesContext,
183        *      java.lang.Object[])
184        */
185 
186         public Object invoke(FacesContext context,
187                              Object[] params) throws EvaluationException,
188                                                      MethodNotFoundException {
189             try {
190                 return m.invoke(context.getELContext(), params);
191             } catch (javax.el.MethodNotFoundException e) {
192                 throw new MethodNotFoundException(e.getMessage(),
193                                                   e.getCause());
194             } catch (ELException e) {
195                 throw new EvaluationException(e.getMessage(), e.getCause());
196             }
197         }
198 
199         public String getExpressionString() {
200             return m.getExpressionString();
201         }
202     }
203 }