2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.test.mock;
19
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22
23 import javax.faces.application.Application;
24 import javax.faces.component.StateHolder;
25 import javax.faces.component.UIComponentBase;
26 import javax.faces.context.FacesContext;
27 import javax.faces.el.EvaluationException;
28 import javax.faces.el.MethodBinding;
29 import javax.faces.el.MethodNotFoundException;
30 import javax.faces.el.ReferenceSyntaxException;
31 import javax.faces.el.ValueBinding;
32
33 /***
34 * <p>Mock implementation of <code>MethodBinding</code>.</p>
35 *
36 * <p>This implementation is subject to the following restrictions:</p>
37 * <ul>
38 * <li>The portion of the method reference expression before the final
39 * "." must conform to the limitations of {@link MockValueBinding}.</li>
40 * <li>The name of the method to be executed cannot be delimited by "[]".</li>
41 * </ul>
42 */
43
44 public class MockMethodBinding extends MethodBinding implements StateHolder {
45
46
47
48
49 /***
50 * <p>Construct a default instance.</p>
51 */
52 public MockMethodBinding() {
53 }
54
55
56 /***
57 * <p>Construct a configured instance.</p>
58 *
59 * @param application Application instance for this application
60 * @param ref Method binding expression to be parsed
61 * @param args Signature of this method
62 */
63 public MockMethodBinding(Application application, String ref,
64 Class[] args) {
65
66 this.application = application;
67 this.args = args;
68 if (ref.startsWith("#{") && ref.endsWith("}")) {
69 ref = ref.substring(2, ref.length() - 1);
70 }
71 this.ref = ref;
72 int period = ref.lastIndexOf(".");
73 if (period < 0) {
74 throw new ReferenceSyntaxException(ref);
75 }
76 vb = application.createValueBinding(ref.substring(0, period));
77 name = ref.substring(period + 1);
78 if (name.length() < 1) {
79 throw new ReferenceSyntaxException(ref);
80 }
81
82 }
83
84
85
86
87
88 private Application application;
89 private Class args[];
90 private String name;
91 private String ref;
92 private ValueBinding vb;
93
94
95
96
97
98 /*** {@inheritDoc} */
99 public Object invoke(FacesContext context, Object[] params)
100 throws EvaluationException, MethodNotFoundException {
101
102 if (context == null) {
103 throw new NullPointerException();
104 }
105 Object base = vb.getValue(context);
106 if (base == null) {
107 throw new EvaluationException("Cannot find object via expression \""
108 + vb.getExpressionString() + "\"");
109 }
110 Method method = method(base);
111 try {
112 return (method.invoke(base, params));
113 } catch (IllegalAccessException e) {
114 throw new EvaluationException(e);
115 } catch (InvocationTargetException e) {
116 throw new EvaluationException(e.getTargetException());
117 }
118
119 }
120
121
122 /*** {@inheritDoc} */
123 public Class getType(FacesContext context) {
124
125 Object base = vb.getValue(context);
126 Method method = method(base);
127 Class returnType = method.getReturnType();
128 if ("void".equals(returnType.getName())) {
129 return (null);
130 } else {
131 return (returnType);
132 }
133
134 }
135
136 /*** {@inheritDoc} */
137 public String getExpressionString() {
138 return "#{" + ref + "}";
139 }
140
141
142
143
144 /*** {@inheritDoc} */
145 public Object saveState(FacesContext context) {
146 Object values[] = new Object[4];
147 values[0] = name;
148 values[1] = ref;
149 values[2] = UIComponentBase.saveAttachedState(context, vb);
150 values[3] = args;
151 return (values);
152 }
153
154
155 /*** {@inheritDoc} */
156 public void restoreState(FacesContext context, Object state) {
157 Object values[] = (Object[]) state;
158 name = (String) values[0];
159 ref = (String) values[1];
160 vb = (ValueBinding) UIComponentBase.restoreAttachedState(context,
161 values[2]);
162 args = (Class []) values[3];
163 }
164
165
166 /***
167 * <p>Flag indicating this is a transient instance.</p>
168 */
169 private boolean transientFlag = false;
170
171
172 /*** {@inheritDoc} */
173 public boolean isTransient() {
174 return (this.transientFlag);
175 }
176
177
178 /*** {@inheritDoc} */
179 public void setTransient(boolean transientFlag) {
180 this.transientFlag = transientFlag;
181 }
182
183 /*** {@inheritDoc} */
184 public int hashCode() {
185 if (ref == null) {
186 return 0;
187 } else {
188 return ref.hashCode();
189 }
190 }
191
192 /*** {@inheritDoc} */
193 public boolean equals(Object otherObj) {
194 MockMethodBinding other = null;
195
196 if (!(otherObj instanceof MockMethodBinding)) {
197 return false;
198 }
199 other = (MockMethodBinding) otherObj;
200
201 if (this.ref != other.ref) {
202
203 if (null != this.ref && null != other.ref) {
204 if (!this.ref.equals(other.ref)) {
205 return false;
206 }
207 }
208 return false;
209 }
210
211
212 if (this.args != other.args) {
213 if (this.args.length != other.args.length) {
214 return false;
215 }
216 for (int i = 0, len = this.args.length; i < len; i++) {
217 if (this.args[i] != other.args[i]) {
218 if (!this.ref.equals(other.ref)) {
219 return false;
220 }
221 }
222 }
223 }
224 return true;
225 }
226
227
228
229
230
231 /***
232 * <p>Return the <code>Method</code> to be called.</p>
233 *
234 * @param base Base object from which to extract the method reference
235 */
236 Method method(Object base) {
237
238 Class clazz = base.getClass();
239 try {
240 return (clazz.getMethod(name, args));
241 } catch (NoSuchMethodException e) {
242 throw new MethodNotFoundException(ref + ": " + e.getMessage());
243 }
244
245 }
246
247
248
249 }