1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.enhance; |
16 |
| |
17 |
| import java.lang.reflect.Modifier; |
18 |
| import java.util.Iterator; |
19 |
| |
20 |
| import org.apache.hivemind.ApplicationRuntimeException; |
21 |
| import org.apache.hivemind.ErrorLog; |
22 |
| import org.apache.hivemind.service.BodyBuilder; |
23 |
| import org.apache.hivemind.service.ClassFabUtils; |
24 |
| import org.apache.hivemind.service.MethodSignature; |
25 |
| import org.apache.hivemind.util.Defense; |
26 |
| import org.apache.tapestry.IBinding; |
27 |
| import org.apache.tapestry.IComponent; |
28 |
| import org.apache.tapestry.spec.IComponentSpecification; |
29 |
| import org.apache.tapestry.spec.IParameterSpecification; |
30 |
| |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| public class ParameterPropertyWorker implements EnhancementWorker |
38 |
| { |
39 |
| private ErrorLog _errorLog; |
40 |
| |
41 |
421
| public void performEnhancement(EnhancementOperation op, IComponentSpecification spec)
|
42 |
| { |
43 |
421
| Iterator i = spec.getParameterNames().iterator();
|
44 |
421
| while (i.hasNext())
|
45 |
| { |
46 |
1089
| String name = (String) i.next();
|
47 |
| |
48 |
1089
| IParameterSpecification ps = spec.getParameter(name);
|
49 |
| |
50 |
1089
| try
|
51 |
| { |
52 |
1089
| performEnhancement(op, name, ps);
|
53 |
| } |
54 |
| catch (RuntimeException ex) |
55 |
| { |
56 |
1
| _errorLog.error(EnhanceMessages.errorAddingProperty(ps.getPropertyName(), op
|
57 |
| .getBaseClass(), ex), ps.getLocation(), ex); |
58 |
| } |
59 |
| } |
60 |
| } |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
1089
| private void performEnhancement(EnhancementOperation op, String parameterName,
|
68 |
| IParameterSpecification ps) |
69 |
| { |
70 |
1089
| String propertyName = ps.getPropertyName();
|
71 |
1089
| String specifiedType = ps.getType();
|
72 |
1089
| boolean cache = ps.getCache();
|
73 |
| |
74 |
1089
| addParameter(op, parameterName, propertyName, specifiedType, cache);
|
75 |
| } |
76 |
| |
77 |
| |
78 |
| |
79 |
| |
80 |
| |
81 |
| |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
| |
88 |
| |
89 |
| |
90 |
| |
91 |
| |
92 |
| |
93 |
| |
94 |
| |
95 |
1089
| public void addParameter(EnhancementOperation op, String parameterName, String propertyName,
|
96 |
| String specifiedType, boolean cache) |
97 |
| { |
98 |
1089
| Defense.notNull(op, "op");
|
99 |
1089
| Defense.notNull(parameterName, "parameterName");
|
100 |
1089
| Defense.notNull(propertyName, "propertyName");
|
101 |
| |
102 |
1089
| Class propertyType = EnhanceUtils.extractPropertyType(op, propertyName, specifiedType);
|
103 |
| |
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
1088
| op.claimProperty(propertyName);
|
109 |
| |
110 |
| |
111 |
| |
112 |
| |
113 |
1088
| String fieldName = "_$" + propertyName;
|
114 |
1088
| String defaultFieldName = fieldName + "$Default";
|
115 |
1088
| String cachedFieldName = fieldName + "$Cached";
|
116 |
| |
117 |
1088
| op.addField(fieldName, propertyType);
|
118 |
1088
| op.addField(defaultFieldName, propertyType);
|
119 |
1088
| op.addField(cachedFieldName, boolean.class);
|
120 |
| |
121 |
1088
| buildAccessor(
|
122 |
| op, |
123 |
| parameterName, |
124 |
| propertyName, |
125 |
| propertyType, |
126 |
| fieldName, |
127 |
| defaultFieldName, |
128 |
| cachedFieldName, |
129 |
| cache); |
130 |
| |
131 |
1088
| buildMutator(
|
132 |
| op, |
133 |
| parameterName, |
134 |
| propertyName, |
135 |
| propertyType, |
136 |
| fieldName, |
137 |
| defaultFieldName, |
138 |
| cachedFieldName); |
139 |
| |
140 |
1088
| extendCleanupAfterRender(
|
141 |
| op, |
142 |
| parameterName, |
143 |
| propertyName, |
144 |
| propertyType, |
145 |
| fieldName, |
146 |
| defaultFieldName, |
147 |
| cachedFieldName); |
148 |
| } |
149 |
| |
150 |
1088
| private void extendCleanupAfterRender(EnhancementOperation op, String parameterName,
|
151 |
| String propertyName, Class propertyType, String fieldName, String defaultFieldName, |
152 |
| String cachedFieldName) |
153 |
| { |
154 |
1088
| BodyBuilder cleanupBody = new BodyBuilder();
|
155 |
| |
156 |
| |
157 |
| |
158 |
| |
159 |
| |
160 |
| |
161 |
1088
| String bindingName = propertyName + "Binding";
|
162 |
| |
163 |
1088
| addBindingReference(cleanupBody, bindingName, parameterName);
|
164 |
| |
165 |
1088
| cleanupBody.addln("if ({0} && ! {1}.isInvariant())", cachedFieldName, bindingName);
|
166 |
1088
| cleanupBody.begin();
|
167 |
1088
| cleanupBody.addln("{0} = false;", cachedFieldName);
|
168 |
1088
| cleanupBody.addln("{0} = {1};", fieldName, defaultFieldName);
|
169 |
1088
| cleanupBody.end();
|
170 |
| |
171 |
1088
| op.extendMethodImplementation(
|
172 |
| IComponent.class, |
173 |
| EnhanceUtils.CLEANUP_AFTER_RENDER_SIGNATURE, |
174 |
| cleanupBody.toString()); |
175 |
| } |
176 |
| |
177 |
3266
| private void addBindingReference(BodyBuilder builder, String localVariableName,
|
178 |
| String parameterName) |
179 |
| { |
180 |
3266
| builder.addln(
|
181 |
| "{0} {1} = getBinding(\"{2}\");", |
182 |
| IBinding.class.getName(), |
183 |
| localVariableName, |
184 |
| parameterName); |
185 |
| } |
186 |
| |
187 |
1088
| private void buildMutator(EnhancementOperation op, String parameterName, String propertyName,
|
188 |
| Class propertyType, String fieldName, String defaultFieldName, String cachedFieldName) |
189 |
| { |
190 |
1088
| BodyBuilder builder = new BodyBuilder();
|
191 |
1088
| builder.begin();
|
192 |
| |
193 |
| |
194 |
| |
195 |
| |
196 |
| |
197 |
1088
| builder.addln("if (! isInActiveState())");
|
198 |
1088
| builder.begin();
|
199 |
1088
| builder.addln("{0} = $1;", defaultFieldName);
|
200 |
1088
| builder.addln("return;");
|
201 |
1088
| builder.end();
|
202 |
| |
203 |
| |
204 |
| |
205 |
| |
206 |
1088
| addBindingReference(builder, "binding", parameterName);
|
207 |
| |
208 |
1088
| builder.addln("if (binding == null)");
|
209 |
1088
| builder.addln(
|
210 |
| " throw new {0}(\"Parameter ''{1}'' is not bound and can not be updated.\");", |
211 |
| ApplicationRuntimeException.class.getName(), |
212 |
| parameterName); |
213 |
| |
214 |
| |
215 |
| |
216 |
1088
| builder.addln("binding.setObject(($w) $1);");
|
217 |
| |
218 |
| |
219 |
| |
220 |
| |
221 |
| |
222 |
1088
| builder.addln("if (isRendering())");
|
223 |
1088
| builder.begin();
|
224 |
1088
| builder.addln("{0} = $1;", fieldName);
|
225 |
1088
| builder.addln("{0} = true;", cachedFieldName);
|
226 |
1088
| builder.end();
|
227 |
| |
228 |
1088
| builder.end();
|
229 |
| |
230 |
1088
| String mutatorMethodName = EnhanceUtils.createMutatorMethodName(propertyName);
|
231 |
| |
232 |
1088
| op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, mutatorMethodName,
|
233 |
| new Class[] |
234 |
| { propertyType }, null), builder.toString()); |
235 |
| } |
236 |
| |
237 |
| |
238 |
| |
239 |
1090
| void buildAccessor(EnhancementOperation op, String parameterName, String propertyName,
|
240 |
| Class propertyType, String fieldName, String defaultFieldName, String cachedFieldName, |
241 |
| boolean cache) |
242 |
| { |
243 |
1090
| BodyBuilder builder = new BodyBuilder();
|
244 |
1090
| builder.begin();
|
245 |
| |
246 |
1090
| builder.addln("if ({0}) return {1};", cachedFieldName, fieldName);
|
247 |
| |
248 |
1090
| addBindingReference(builder, "binding", parameterName);
|
249 |
| |
250 |
1090
| builder.addln("if (binding == null) return {0};", defaultFieldName);
|
251 |
| |
252 |
1090
| String javaTypeName = ClassFabUtils.getJavaClassName(propertyType);
|
253 |
| |
254 |
1090
| builder.addln("{0} result = {1};", javaTypeName, EnhanceUtils.createUnwrapExpression(
|
255 |
| op, |
256 |
| "binding", |
257 |
| propertyType)); |
258 |
| |
259 |
| |
260 |
| |
261 |
| |
262 |
| |
263 |
| |
264 |
1090
| String expression = cache ? "isRendering() || binding.isInvariant()"
|
265 |
| : "binding.isInvariant()"; |
266 |
| |
267 |
1090
| builder.addln("if ({0})", expression);
|
268 |
1090
| builder.begin();
|
269 |
1090
| builder.addln("{0} = result;", fieldName);
|
270 |
1090
| builder.addln("{0} = true;", cachedFieldName);
|
271 |
1090
| builder.end();
|
272 |
| |
273 |
1090
| builder.addln("return result;");
|
274 |
| |
275 |
1090
| builder.end();
|
276 |
| |
277 |
1090
| String accessorMethodName = op.getAccessorMethodName(propertyName);
|
278 |
| |
279 |
1090
| op.addMethod(Modifier.PUBLIC, new MethodSignature(propertyType, accessorMethodName, null,
|
280 |
| null), builder.toString()); |
281 |
| } |
282 |
| |
283 |
42
| public void setErrorLog(ErrorLog errorLog)
|
284 |
| { |
285 |
42
| _errorLog = errorLog;
|
286 |
| } |
287 |
| } |