1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package org.seasar.groovy;
48
49 import groovy.lang.Closure;
50
51 import groovy.util.BuilderSupport;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55
56 import org.seasar.framework.aop.Pointcut;
57 import org.seasar.framework.aop.impl.PointcutImpl;
58 import org.seasar.framework.container.ArgDef;
59 import org.seasar.framework.container.AspectDef;
60 import org.seasar.framework.container.ComponentDef;
61 import org.seasar.framework.container.DestroyMethodDef;
62 import org.seasar.framework.container.InitMethodDef;
63 import org.seasar.framework.container.MethodDef;
64 import org.seasar.framework.container.PropertyDef;
65 import org.seasar.framework.container.S2Container;
66 import org.seasar.framework.container.factory.S2ContainerFactory;
67 import org.seasar.framework.container.impl.ArgDefImpl;
68 import org.seasar.framework.container.impl.AspectDefImpl;
69 import org.seasar.framework.container.impl.ComponentDefImpl;
70 import org.seasar.framework.container.impl.DestroyMethodDefImpl;
71 import org.seasar.framework.container.impl.InitMethodDefImpl;
72 import org.seasar.framework.container.impl.PropertyDefImpl;
73 import org.seasar.framework.container.impl.S2ContainerImpl;
74 import org.seasar.framework.container.impl.SimpleComponentDef;
75 import org.seasar.framework.util.StringUtil;
76
77 import java.util.HashMap;
78 import java.util.Map;
79
80
81 /***
82 * GroovyMarkupによってS2コンテナーを作成するためのビルダー。
83 *
84 * @author takai
85 *
86 * @see groovy.util.BuilderSupport
87 */
88 public class SeasarBuilder
89 extends BuilderSupport
90 {
91 protected static final Log logger = LogFactory.getLog(SeasarBuilder.class);
92
93 public SeasarBuilder() {
94 }
95
96 protected void setParent(Object parent, Object child) {
97 }
98
99 /***
100 * @see groovy.util.BuilderSupport#createNode(java.lang.Object)
101 */
102 protected Object createNode(Object name) {
103 if (name.equals("container") || name.equals("components")) {
104 logger.debug("Create S2Container.");
105
106 return new S2ContainerImpl();
107 }
108
109 if (name.equals("arg")) {
110 logger.debug("Create ArgDef.");
111
112 return new ArgDefImpl();
113 }
114
115 throw new SeasarBuilderException("Unknown markup; " + name);
116 }
117
118 /***
119 * @see groovy.util.BuilderSupport#createNode(java.lang.Object,
120 * java.util.Map)
121 */
122 protected Object createNode(Object name, Map attributes) {
123 if (name.equals("component")) {
124 logger.debug("Create ComponentDef with attributes; " + attributes);
125
126 return setupComponentDef(attributes);
127 }
128
129 if (name.equals("prop")) {
130 logger.debug("Create PropertyDef with attributes; " + attributes);
131
132 return setupPropertyDef(attributes);
133 }
134
135 if (name.equals("arg")) {
136 logger.debug("Create ArgDef with attributes; " + attributes);
137
138 return setupArgDef(attributes);
139 }
140
141 if(name.equals("init")) {
142 logger.debug("Create InitMethodDef with attributes: " + attributes);
143 InitMethodDefImpl init = new InitMethodDefImpl();
144 init.setExpression((String) attributes.get("ognl"));
145
146 return init;
147 }
148
149 if (name.equals("aspect")) {
150 logger.debug("Create AspectDef with attributes; " + attributes);
151
152 return setupAspectDef(attributes);
153 }
154
155 throw new SeasarBuilderException("Unknown markup; " + name
156 + " with attributes; " + attributes);
157 }
158
159 /***
160 * @see groovy.util.BuilderSupport#createNode(java.lang.Object,
161 * java.lang.Object)
162 */
163 protected Object createNode(Object name, Object value) {
164 if (name.equals("container") || name.equals("components")) {
165 logger.debug("Create S2Container with namespace `" + value + "'.");
166
167 S2Container s2 = new S2ContainerImpl();
168 s2.setNamespace((String) value);
169
170 return s2;
171 }
172
173 if (name.equals("component")) {
174 Map attributes = new HashMap();
175
176 if (value instanceof Class) {
177 attributes.put("class", value);
178 } else {
179 attributes.put("obj", value);
180 }
181
182 return createNode(name, attributes);
183 }
184
185 if (name.equals("arg")) {
186 logger.debug("Create ArgDef with value; " + value);
187
188 return new ArgDefImpl(value);
189 }
190
191 if (name.equals("init")) {
192 logger.debug("Create InitMethodDef with value; " + value);
193
194 return new InitMethodDefImpl((String) value);
195 }
196
197 if (name.equals("destroy")) {
198 logger.debug("Create DestroyDef with value; " + value);
199
200 return new DestroyMethodDefImpl((String) value);
201 }
202
203 if (name.equals("include")) {
204 if (getCurrent() == null) {
205 throw new SeasarBuilderException("S2Container#include() is not defined.");
206 }
207
208 logger.debug("Include " + value);
209
210 return S2ContainerFactory.create((String) value);
211 }
212
213 throw new SeasarBuilderException("Unknown markup; " + name
214 + " with value; " + value);
215 }
216
217 /***
218 * @see groovy.util.BuilderSupport#nodeCompleted(java.lang.Object,
219 * java.lang.Object)
220 */
221 protected void nodeCompleted(Object parent, Object node) {
222 if ((parent == null) && node instanceof S2Container) {
223 return;
224 }
225
226 if (parent instanceof S2Container) {
227 setChildToS2Container((S2Container) parent, node);
228
229 return;
230 }
231
232 if (parent instanceof ComponentDef) {
233 setChildToComponent((ComponentDef) parent, node);
234
235 return;
236 }
237
238 if (parent instanceof ArgDef) {
239 setChildToArg((ArgDef) parent, node);
240
241 return;
242 }
243
244 if (parent instanceof MethodDef) {
245 setChildToMethod((MethodDef) parent, node);
246
247 return;
248 }
249
250 throw new SeasarBuilderException(parent + " can't be parent of " + node);
251 }
252
253 private void setChildToArg(ArgDef def, Object child) {
254 if (child instanceof ComponentDef) {
255 logger.debug("Setting " + child + " as child component for " + def);
256
257 def.setChildComponentDef((ComponentDef) child);
258 } else {
259 throw new SeasarBuilderException("ArgDef can't be parent of "
260 + child);
261 }
262 }
263
264 private void setChildToComponent(ComponentDef def, Object child) {
265 if (child instanceof PropertyDef) {
266 logger.debug("Adding " + child + " as PropertyDef to " + def);
267 def.addPropertyDef((PropertyDef) child);
268 } else if (child instanceof AspectDef) {
269 logger.debug("Adding " + child + " as AspectDef to " + def);
270 def.addAspectDef((AspectDef) child);
271 } else if (child instanceof ArgDef) {
272 logger.debug("Adding " + child + " as ArgDef to " + def);
273 def.addArgDef((ArgDef) child);
274 } else if (child instanceof InitMethodDef) {
275 logger.debug("Adding " + child + " as InitMethodDef to " + def);
276 def.addInitMethodDef((InitMethodDef) child);
277 } else if (child instanceof DestroyMethodDef) {
278 logger.debug("Adding " + child + " as DestroyMethod to " + def);
279 def.addDestroyMethodDef((DestroyMethodDef) child);
280 } else {
281 throw new SeasarBuilderException("ComponentDef can't be parent of "
282 + child);
283 }
284 }
285
286 private void setChildToMethod(MethodDef def, Object child) {
287 if (child instanceof ArgDef) {
288 logger.debug("Adding " + child + " as ArgDef to " + def);
289
290 def.addArgDef((ArgDef) child);
291 } else {
292 throw new SeasarBuilderException("MethodDef can't be parent of "
293 + child);
294 }
295 }
296
297 private void setChildToS2Container(S2Container container, Object child) {
298 if (child instanceof ComponentDef) {
299 logger.debug("Registering " + child + " as ComponentDef to "
300 + container);
301 container.register((ComponentDef) child);
302 } else if (child instanceof S2Container) {
303 logger.debug("Including " + child + " to " + container);
304 container.include((S2Container) child);
305 } else {
306 throw new SeasarBuilderException("S2Container can't be parent of "
307 + child);
308 }
309 }
310
311 private ArgDef setupArgDef(Map attributes) {
312 String referenceExpression = (String) attributes.get("ref");
313
314 ArgDef def = new ArgDefImpl();
315 def.setExpression(referenceExpression);
316
317 return def;
318 }
319
320 private AspectDef setupAspectDef(Map attributes) {
321 AspectDef def = null;
322 String method = (String) attributes.get("pointcut");
323
324 if (attributes.get("advice") instanceof String) {
325 if (method != null) {
326 Pointcut pointcut =
327 new PointcutImpl(StringUtil.split(method, ","));
328 def = new AspectDefImpl(pointcut);
329 } else {
330 def = new AspectDefImpl();
331 }
332
333 def.setExpression((String) attributes.get("advice"));
334 } else if (attributes.get("advice") instanceof Closure) {
335 ClosureAroundAdvice advice =
336 new ClosureAroundAdvice((Closure) attributes.get("advice"));
337
338 if (method != null) {
339 Pointcut pointcut =
340 new PointcutImpl(StringUtil.split(method, ","));
341 def = new AspectDefImpl(advice, pointcut);
342 } else {
343 def = new AspectDefImpl(advice);
344 }
345 } else {
346 throw new SeasarBuilderException("'advice' must be an expression string or a closure.");
347 }
348
349 return def;
350 }
351
352 private ComponentDef setupComponentDef(Map attributes) {
353 ComponentDef def = null;
354
355 Class cls = (Class) attributes.get("class");
356 Object obj = (Object) attributes.get("obj");
357 String name = (String) attributes.get("name");
358 String destroy = (String) attributes.get("destroy");
359 String instance = (String) attributes.get("instance");
360 String binding = (String) attributes.get("binding");
361
362 if ((cls == null) && (obj == null)) {
363 throw new SeasarBuilderException("Neither class nor object is pass, or null?");
364 }
365
366 if (name != null) {
367 if (cls != null) {
368 def = new ComponentDefImpl(cls, name);
369 } else {
370 def = new SimpleComponentDef(obj, name);
371 }
372 } else {
373 if (cls != null) {
374 def = new ComponentDefImpl(cls);
375 } else {
376 def = new SimpleComponentDef(obj);
377 }
378 }
379
380 if (instance != null) {
381 def.setInstanceMode(instance);
382 }
383
384 if (binding != null) {
385 def.setAutoBindingMode(binding);
386 }
387
388 return def;
389 }
390
391 private PropertyDef setupPropertyDef(Map attributes) {
392 String propertyName = (String) attributes.get("name");
393 Object propertyValue = attributes.get("value");
394 String referenceExpression = (String) attributes.get("ref");
395
396 boolean valIsNotNull = propertyValue != null;
397 boolean refIsNotNull = referenceExpression != null;
398
399 if (valIsNotNull && refIsNotNull) {
400 throw new SeasarBuilderException("'value' and 'ref' on 'prop' is mutually exclusive parameter.");
401 }
402
403 if (valIsNotNull) {
404 return new PropertyDefImpl(propertyName, propertyValue);
405 } else if (refIsNotNull) {
406 PropertyDef def = new PropertyDefImpl(propertyName);
407 def.setExpression(referenceExpression);
408
409 return def;
410 } else {
411 throw new SeasarBuilderException("'value' or 'ref' must be set.");
412 }
413 }
414
415 protected Object createNode(Object name, Map attributes, Object value) {
416 return null;
417 }
418 }