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