1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
43
44
45
46
47
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
164
165
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
181
182
183
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 }