View Javadoc

1   /*
2    *
3    * The Seasar Software License, Version 1.1
4    *
5    * Copyright (c) 2003-2004 The Seasar Project. All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or
8    * without modification, are permitted provided that the following
9    * conditions are met:
10   *
11   * 1. Redistributions of source code must retain the above
12   *    copyrightnotice, this list of conditions and the following
13   *    disclaimer.
14   *
15   * 2. Redistributions in binary form must reproduce the above
16   *    copyright notice, this list of conditions and the following
17   *    disclaimer in the documentation and/or other materials provided
18   *    with the distribution.
19   *
20   * 3. The end-user documentation included with the redistribution,
21   *    if any, must include the following acknowledgement:
22   *    "This product includes software developed by the
23   *    Seasar Project (http://www.seasar.org/)."
24   *    Alternately, this acknowledgement may appear in the software
25   *    itself, if and wherever such third-party acknowledgements
26   *    normally appear.
27   *
28   * 4. Neither the names "The Seasar Project" nor the name of its
29   *    contributors ay be used to endour or promote products derived
30   *    from this software without specific prior written permission of
31   *    the Seasar Project.
32   *
33   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR
34   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35   * WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE SEASER PROJECT
37   * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
38   * INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42   * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING
43   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
44   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 }