1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.facelets.tag;
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23
24 import javax.el.MethodExpression;
25 import javax.faces.el.MethodBinding;
26 import javax.faces.view.facelets.FaceletContext;
27 import javax.faces.view.facelets.MetaRule;
28 import javax.faces.view.facelets.Metadata;
29 import javax.faces.view.facelets.MetadataTarget;
30 import javax.faces.view.facelets.TagAttribute;
31 import javax.faces.view.facelets.TagAttributeException;
32
33
34
35
36
37
38
39 public final class MethodRule extends MetaRule
40 {
41
42 private final String methodName;
43
44 private final String propertyName;
45
46 private final Class<?> returnTypeClass;
47
48 private final Class<?>[] params;
49
50 public MethodRule(String methodName, Class<?> returnTypeClass,
51 Class<?>[] params)
52 {
53 this.methodName = methodName;
54 this.propertyName = methodName;
55 this.returnTypeClass = returnTypeClass;
56 this.params = params;
57 }
58
59 public MethodRule(String methodName, String propertyName, Class<?> returnTypeClass,
60 Class<?>[] params)
61 {
62 this.methodName = methodName;
63 this.propertyName = propertyName;
64 this.returnTypeClass = returnTypeClass;
65 this.params = params;
66 }
67
68 public Metadata applyRule(String name, TagAttribute attribute,
69 MetadataTarget meta)
70 {
71 if (false == name.equals(this.methodName))
72 return null;
73
74 if (MethodExpression.class.equals(meta.getPropertyType(propertyName)))
75 {
76 Method method = meta.getWriteMethod(propertyName);
77 if (method != null)
78 {
79 return new MethodExpressionMetadata(method, attribute,
80 this.returnTypeClass, this.params);
81 }
82 }
83 else if (MethodBinding.class.equals(meta.getPropertyType(propertyName)))
84 {
85 Method method = meta.getWriteMethod(propertyName);
86 if (method != null)
87 {
88 return new MethodBindingMetadata(method, attribute,
89 this.returnTypeClass, this.params);
90 }
91 }
92
93 return null;
94 }
95
96 private class MethodBindingMetadata extends Metadata
97 {
98 private final Method _method;
99
100 private final TagAttribute _attribute;
101
102 private Class[] _paramList;
103
104 private Class _returnType;
105
106 public MethodBindingMetadata(Method method, TagAttribute attribute,
107 Class returnType, Class[] paramList)
108 {
109 _method = method;
110 _attribute = attribute;
111 _paramList = paramList;
112 _returnType = returnType;
113 }
114
115 public void applyMetadata(FaceletContext ctx, Object instance)
116 {
117 MethodExpression expr = _attribute.getMethodExpression(ctx,
118 _returnType, _paramList);
119
120 try
121 {
122 _method.invoke(instance,
123 new Object[] { new LegacyMethodBinding(expr) });
124 }
125 catch (InvocationTargetException e)
126 {
127 throw new TagAttributeException(_attribute, e.getCause());
128 }
129 catch (Exception e)
130 {
131 throw new TagAttributeException(_attribute, e);
132 }
133 }
134 }
135
136 private class MethodExpressionMetadata extends Metadata
137 {
138 private final Method _method;
139
140 private final TagAttribute _attribute;
141
142 private Class<?>[] _paramList;
143
144 private Class<?> _returnType;
145
146 public MethodExpressionMetadata(Method method, TagAttribute attribute,
147 Class<?> returnType, Class<?>[] paramList)
148 {
149 _method = method;
150 _attribute = attribute;
151 _paramList = paramList;
152 _returnType = returnType;
153 }
154
155 public void applyMetadata(FaceletContext ctx, Object instance)
156 {
157 MethodExpression expr = _attribute.getMethodExpression(ctx,
158 _returnType, _paramList);
159
160 try
161 {
162 _method.invoke(instance, new Object[] { expr });
163 }
164 catch (InvocationTargetException e)
165 {
166 throw new TagAttributeException(_attribute, e.getCause());
167 }
168 catch (Exception e)
169 {
170 throw new TagAttributeException(_attribute, e);
171 }
172 }
173 }
174 }