1 10 11 package org.nanocontainer.script.groovy.buildernodes; 12 13 import java.util.Map ; 14 import org.nanocontainer.NanoContainer; 15 import org.nanocontainer.script.NanoContainerMarkupException; 16 import org.picocontainer.defaults.DefaultPicoContainer; 17 import java.security.PrivilegedAction ; 18 import org.picocontainer.defaults.ComponentAdapterFactory; 19 import java.security.AccessController ; 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 39 public class ChildContainerNode extends AbstractBuilderNode { 40 41 44 public static final String NODE_NAME = "container"; 45 46 50 private static final String CLASS = "class"; 51 52 55 private final NodeBuilderDecorationDelegate decorationDelegate; 56 57 61 private static final String COMPONENT_ADAPTER_FACTORY = "componentAdapterFactory"; 62 63 66 private static final String COMPONENT_MONITOR = "componentMonitor"; 67 68 69 73 private static final String SCOPE = "scope"; 74 75 76 79 private static final String PARENT = "parent"; 80 81 82 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 109 public Object createNewNode(Object current, Map attributes) throws 110 NanoContainerMarkupException { 111 112 return createChildContainer(attributes,(NanoContainer) current); 113 } 114 115 119 private NodeBuilderDecorationDelegate getDecorationDelegate() { 120 return decorationDelegate; 121 } 122 123 124 125 136 protected NanoContainer createChildContainer(Map attributes, NanoContainer parent) { 137 138 ClassLoader 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 ) AccessController.doPrivileged(new PrivilegedAction () { 160 public Object 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 clazz = (Class ) 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 clazz, MutablePicoContainer decoratedPico, ClassLoader parentClassLoader) { 188 DefaultPicoContainer instantiatingContainer = new DefaultPicoContainer(); 189 instantiatingContainer.registerComponentInstance(ClassLoader .class, parentClassLoader); 190 instantiatingContainer.registerComponentInstance(MutablePicoContainer.class, decoratedPico); 191 instantiatingContainer.registerComponentImplementation(NanoContainer.class, clazz); 192 Object componentInstance = instantiatingContainer.getComponentInstance(NanoContainer.class); 193 return (NanoContainer) componentInstance; 194 } 195 196 private ComponentAdapterFactory createComponentAdapterFactory(Map 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 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 |