KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nanocontainer > script > groovy > buildernodes > ChildContainerNode


1 /*****************************************************************************
2  * Copyright (C) NanoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  * Original code by James Strachan *
9  *****************************************************************************/

10
11 package org.nanocontainer.script.groovy.buildernodes;
12
13 import java.util.Map JavaDoc;
14 import org.nanocontainer.NanoContainer;
15 import org.nanocontainer.script.NanoContainerMarkupException;
16 import org.picocontainer.defaults.DefaultPicoContainer;
17 import java.security.PrivilegedAction JavaDoc;
18 import org.picocontainer.defaults.ComponentAdapterFactory;
19 import java.security.AccessController JavaDoc;
20 import org.picocontainer.defaults.DefaultComponentAdapterFactory;
21 import org.picocontainer.MutablePicoContainer;
22 import org.picocontainer.PicoContainer;
23 import org.nanocontainer.DefaultNanoContainer;
24 import org.nanocontainer.script.NodeBuilderDecorationDelegate;
25 import org.picocontainer.ComponentMonitor;
26 import org.picocontainer.defaults.DelegatingComponentMonitor;
27 import org.picocontainer.defaults.ComponentMonitorStrategy;
28
29 /**
30  * Creates a new NanoContainer node. There may or may not be a parent
31  * container involved.
32  * @author James Strachan
33  * @author Paul Hammant
34  * @author Aslak Hellesøy
35  * @author Michael Rimov
36  * @author Mauro Talevi
37  * @version $Revision: 2695 $
38  */

39 public class ChildContainerNode extends AbstractBuilderNode {
40
41     /**
42      * Node name.
43      */

44     public static final String JavaDoc NODE_NAME = "container";
45
46     /**
47      * Supported Attribute: 'class' Reference to a classname of the container
48      * to use.
49      */

50     private static final String JavaDoc CLASS = "class";
51
52     /**
53      * The node decoration delegate.
54      */

55     private final NodeBuilderDecorationDelegate decorationDelegate;
56
57     /**
58      * Attribute: 'componentAdapterFactory' a reference to an instance of a
59      * component adapter factory.
60      */

61     private static final String JavaDoc COMPONENT_ADAPTER_FACTORY = "componentAdapterFactory";
62
63     /**
64      * Attribute: 'componentMonitor' a reference to an instance of a component monitor.
65      */

66     private static final String JavaDoc COMPONENT_MONITOR = "componentMonitor";
67
68
69     /**
70      * Attribute that exists in test cases, but not necessarily used?
71      *
72      */

73     private static final String JavaDoc SCOPE = "scope";
74
75
76     /**
77      * Attribute: 'parent' a reference to the parent for this new container.
78      */

79     private static final String JavaDoc PARENT = "parent";
80
81
82     /**
83      * Constructs a child container node. It requires a <tt>NodeBuilderDecorationDelegate</tt>
84      * for construction.
85      * @param delegate NodeBuilderDecorationDelegate
86      */

87     public ChildContainerNode(NodeBuilderDecorationDelegate delegate) {
88         super(NODE_NAME);
89         decorationDelegate = delegate;
90
91         this.addAttribute(CLASS)
92             .addAttribute(COMPONENT_ADAPTER_FACTORY)
93             .addAttribute(COMPONENT_MONITOR)
94             .addAttribute(PARENT)
95             .addAttribute(SCOPE);
96
97
98     }
99
100     /**
101      * Creates a new container. There may or may not be a parent to this container.
102      * Supported attributes are
103      * <p>{@inheritDoc}</p>
104      * @param current NanoContainer
105      * @param attributes Map
106      * @return Object
107      * @throws NanoContainerMarkupException
108      */

109     public Object JavaDoc createNewNode(Object JavaDoc current, Map JavaDoc attributes) throws
110         NanoContainerMarkupException {
111
112         return createChildContainer(attributes,(NanoContainer) current);
113     }
114
115     /**
116      * Retrieve the decoration delegate.
117      * @return NodeBuilderDecorationDelegate
118      */

119     private NodeBuilderDecorationDelegate getDecorationDelegate() {
120         return decorationDelegate;
121     }
122
123
124
125     /**
126      * Creates a new container. There may or may not be a parent to this container.
127      * Supported attributes are:
128      * <ul>
129      * <li><tt>componentAdapterFactory</tt>: The ComponentAdapterFactory used for new container</li>
130      * <li><tt>componentMonitor</tt>: The ComponentMonitor used for new container</li>
131      * </ul>
132      * @param attributes Map Attributes defined by the builder in the script.
133      * @param parent The parent container
134      * @return The NanoContainer
135      */

136     protected NanoContainer createChildContainer(Map JavaDoc attributes, NanoContainer parent) {
137
138         ClassLoader JavaDoc parentClassLoader = null;
139         MutablePicoContainer childContainer = null;
140         if (parent != null) {
141             parentClassLoader = parent.getComponentClassLoader();
142             if ( isAttribute(attributes, COMPONENT_ADAPTER_FACTORY) ) {
143                 ComponentAdapterFactory componentAdapterFactory = createComponentAdapterFactory(attributes);
144                 childContainer = new DefaultPicoContainer(
145                         getDecorationDelegate().decorate(componentAdapterFactory, attributes), parent.getPico());
146                 if ( isAttribute(attributes, COMPONENT_MONITOR) ) {
147                     changeComponentMonitor(childContainer, createComponentMonitor(attributes));
148                 }
149                 parent.getPico().addChildContainer(childContainer);
150             } else if ( isAttribute(attributes, COMPONENT_MONITOR) ) {
151                 ComponentAdapterFactory componentAdapterFactory = new DefaultComponentAdapterFactory(
152                                                     createComponentMonitor(attributes));
153                 childContainer = new DefaultPicoContainer(
154                         getDecorationDelegate().decorate(componentAdapterFactory, attributes), parent.getPico());
155             } else {
156                 childContainer = parent.getPico().makeChildContainer();
157             }
158         } else {
159             parentClassLoader = (ClassLoader JavaDoc) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
160                 public Object JavaDoc run() {
161                     return PicoContainer.class.getClassLoader();
162                 }
163             });
164             ComponentAdapterFactory componentAdapterFactory = createComponentAdapterFactory(attributes);
165             childContainer = new DefaultPicoContainer(
166                     getDecorationDelegate().decorate(componentAdapterFactory, attributes));
167             if ( isAttribute(attributes, COMPONENT_MONITOR) ) {
168                 changeComponentMonitor(childContainer, createComponentMonitor(attributes));
169             }
170         }
171
172         MutablePicoContainer decoratedPico = getDecorationDelegate().decorate(childContainer);
173         if ( isAttribute(attributes, CLASS) ) {
174             Class JavaDoc clazz = (Class JavaDoc) attributes.get(CLASS);
175             return createNanoContainer(clazz, decoratedPico, parentClassLoader);
176         } else {
177             return new DefaultNanoContainer(parentClassLoader, decoratedPico);
178         }
179     }
180
181     private void changeComponentMonitor(MutablePicoContainer childContainer, ComponentMonitor monitor) {
182         if ( childContainer instanceof ComponentMonitorStrategy ){
183             ((ComponentMonitorStrategy)childContainer).changeMonitor(monitor);
184         }
185     }
186
187     private NanoContainer createNanoContainer(Class JavaDoc clazz, MutablePicoContainer decoratedPico, ClassLoader JavaDoc parentClassLoader) {
188         DefaultPicoContainer instantiatingContainer = new DefaultPicoContainer();
189         instantiatingContainer.registerComponentInstance(ClassLoader JavaDoc.class, parentClassLoader);
190         instantiatingContainer.registerComponentInstance(MutablePicoContainer.class, decoratedPico);
191         instantiatingContainer.registerComponentImplementation(NanoContainer.class, clazz);
192         Object JavaDoc componentInstance = instantiatingContainer.getComponentInstance(NanoContainer.class);
193         return (NanoContainer) componentInstance;
194     }
195
196     private ComponentAdapterFactory createComponentAdapterFactory(Map JavaDoc attributes) {
197         final ComponentAdapterFactory factory = (ComponentAdapterFactory) attributes.remove(COMPONENT_ADAPTER_FACTORY);
198         if ( factory == null ){
199             return new DefaultComponentAdapterFactory();
200         }
201         return factory;
202     }
203
204     private ComponentMonitor createComponentMonitor(Map JavaDoc attributes) {
205         final ComponentMonitor monitor = (ComponentMonitor) attributes.remove(COMPONENT_MONITOR);
206         if ( monitor == null ){
207             return new DelegatingComponentMonitor();
208         }
209         return monitor;
210     }
211
212
213 }
214
Popular Tags