1 10 11 package org.nanocontainer; 12 13 import java.net.URL ; 14 import java.security.AccessController ; 15 import java.security.PermissionCollection ; 16 import java.security.PrivilegedAction ; 17 import java.util.ArrayList ; 18 import java.util.HashMap ; 19 import java.util.List ; 20 import java.util.Map ; 21 22 import org.nanocontainer.script.NanoContainerMarkupException; 23 import org.picocontainer.ComponentAdapter; 24 import org.picocontainer.MutablePicoContainer; 25 import org.picocontainer.Parameter; 26 import org.picocontainer.PicoIntrospectionException; 27 import org.picocontainer.PicoRegistrationException; 28 import org.picocontainer.defaults.BeanPropertyComponentAdapter; 29 import org.picocontainer.defaults.ConstantParameter; 30 import org.picocontainer.defaults.CustomPermissionsURLClassLoader; 31 import org.picocontainer.defaults.DefaultPicoContainer; 32 33 39 public class DefaultNanoContainer implements NanoContainer { 40 private static final Map primitiveNameToBoxedName = new HashMap (); 41 static { 42 primitiveNameToBoxedName.put("int", Integer .class.getName()); 43 primitiveNameToBoxedName.put("byte", Byte .class.getName()); 44 primitiveNameToBoxedName.put("short", Short .class.getName()); 45 primitiveNameToBoxedName.put("long", Long .class.getName()); 46 primitiveNameToBoxedName.put("float", Float .class.getName()); 47 primitiveNameToBoxedName.put("double", Double .class.getName()); 48 primitiveNameToBoxedName.put("boolean", Boolean .class.getName()); 49 } 50 51 private final List classPathElements = new ArrayList (); 52 private MutablePicoContainer picoContainer; 53 private final ClassLoader parentClassLoader; 54 55 private ClassLoader componentClassLoader; 56 private boolean componentClassLoaderLocked; 57 58 private static String getClassName(String primitiveOrClass) { 59 String fromMap = (String ) primitiveNameToBoxedName.get(primitiveOrClass); 60 return fromMap != null ? fromMap : primitiveOrClass; 61 } 62 63 public DefaultNanoContainer(ClassLoader parentClassLoader, MutablePicoContainer picoContainer) { 64 this.parentClassLoader = parentClassLoader; 65 if (picoContainer == null) { 66 throw new NullPointerException ("picoContainer"); 67 } 68 this.picoContainer = picoContainer; 69 } 70 71 public DefaultNanoContainer(ClassLoader parentClassLoader) { 72 this(parentClassLoader, new DefaultPicoContainer()); 73 } 74 75 public DefaultNanoContainer(MutablePicoContainer picoContainer) { 76 this(Thread.currentThread().getContextClassLoader(), picoContainer); 77 } 78 79 public DefaultNanoContainer(NanoContainer parent) { 80 this(parent.getComponentClassLoader(), new DefaultPicoContainer(parent.getPico())); 81 } 82 83 86 public DefaultNanoContainer() { 87 this(Thread.currentThread().getContextClassLoader(), new DefaultPicoContainer()); 88 } 89 90 public ComponentAdapter registerComponentImplementation(String componentImplementationClassName) throws PicoRegistrationException, ClassNotFoundException , PicoIntrospectionException { 91 return picoContainer.registerComponentImplementation(loadClass(componentImplementationClassName)); 92 } 93 94 public ComponentAdapter registerComponentImplementation(Object key, String componentImplementationClassName) throws ClassNotFoundException { 95 Class componentImplementation = loadClass(componentImplementationClassName); 96 if (key instanceof ClassNameKey) { 97 key = loadClass(((ClassNameKey) key).getClassName()); 98 } 99 return picoContainer.registerComponentImplementation(key, componentImplementation); 100 } 101 102 103 public ComponentAdapter registerComponentImplementation(Object key, String componentImplementationClassName, Parameter[] parameters) throws ClassNotFoundException { 104 Class componentImplementation = loadClass(componentImplementationClassName); 105 if (key instanceof ClassNameKey) { 106 key = loadClass(((ClassNameKey) key).getClassName()); 107 108 } 109 return picoContainer.registerComponentImplementation(key, componentImplementation, parameters); 110 } 111 112 public ComponentAdapter registerComponentImplementation(Object key, 113 String componentImplementationClassName, 114 String [] parameterTypesAsString, 115 String [] parameterValuesAsString) throws PicoRegistrationException, ClassNotFoundException , PicoIntrospectionException { 116 Class componentImplementation = getComponentClassLoader().loadClass(componentImplementationClassName); 117 if (key instanceof ClassNameKey) { 118 key = loadClass(((ClassNameKey) key).getClassName()); 119 120 } 121 return registerComponentImplementation(parameterTypesAsString, parameterValuesAsString, key, componentImplementation); 122 } 123 124 public ComponentAdapter registerComponentImplementation(String componentImplementationClassName, 125 String [] parameterTypesAsString, 126 String [] parameterValuesAsString) throws PicoRegistrationException, ClassNotFoundException , PicoIntrospectionException { 127 Class componentImplementation = getComponentClassLoader().loadClass(componentImplementationClassName); 128 return registerComponentImplementation(parameterTypesAsString, parameterValuesAsString, componentImplementation, componentImplementation); 129 } 130 131 private ComponentAdapter registerComponentImplementation(String [] parameterTypesAsString, String [] parameterValuesAsString, Object key, Class componentImplementation) throws ClassNotFoundException { 132 Parameter[] parameters = new Parameter[parameterTypesAsString.length]; 133 for (int i = 0; i < parameters.length; i++) { 134 Object value = BeanPropertyComponentAdapter.convert(parameterTypesAsString[i], parameterValuesAsString[i], getComponentClassLoader()); 135 parameters[i] = new ConstantParameter(value); 136 } 137 return picoContainer.registerComponentImplementation(key, componentImplementation, parameters); 138 } 139 140 private Class loadClass(final String className) throws ClassNotFoundException { 141 ClassLoader classLoader = getComponentClassLoader(); 142 String cn = getClassName(className); 143 return classLoader.loadClass(cn); 144 } 145 146 public ClassPathElement addClassLoaderURL(URL url) { 147 if (componentClassLoaderLocked) throw new IllegalStateException ("ClassLoader URLs cannot be added once this instance is locked"); 148 149 ClassPathElement classPathElement = new ClassPathElement(url); 150 classPathElements.add(classPathElement); 151 return classPathElement; 152 } 153 154 public ClassLoader getComponentClassLoader() { 155 if (componentClassLoader == null) { 156 componentClassLoaderLocked = true; 157 componentClassLoader = (ClassLoader ) AccessController.doPrivileged(new PrivilegedAction () { 158 public Object run() { 159 return new CustomPermissionsURLClassLoader(getURLs(classPathElements), makePermissions(), parentClassLoader); 160 } 161 }); 162 } 163 return componentClassLoader; 164 } 165 166 public MutablePicoContainer getPico() { 167 return picoContainer; 168 } 169 170 private Map makePermissions() { 171 Map permissionsMap = new HashMap (); 172 for (int i = 0; i < classPathElements.size(); i++) { 173 ClassPathElement cpe = (ClassPathElement) classPathElements.get(i); 174 PermissionCollection permissionCollection = cpe.getPermissionCollection(); 175 permissionsMap.put(cpe.getUrl(), permissionCollection); 176 } 177 return permissionsMap; 178 } 179 180 private URL [] getURLs(List classPathElemelements) { 181 final URL [] urls = new URL [classPathElemelements.size()]; 182 for(int i = 0; i < urls.length; i++) { 183 urls[i] = ((ClassPathElement) classPathElemelements.get(i)).getUrl(); 184 } 185 return urls; 186 } 187 188 public Object getComponentInstanceOfType(String componentType) { 189 try { 190 Class compType = getComponentClassLoader().loadClass(componentType); 191 return picoContainer.getComponentInstanceOfType(compType); 192 } catch (ClassNotFoundException e) { 193 throw new NanoContainerMarkupException("Can't resolve class as type '" + componentType + "'"); 194 } 195 } 196 197 public MutablePicoContainer addDecoratingPicoContainer(Class picoContainerClass) { 198 DefaultPicoContainer pico = new DefaultPicoContainer(); 199 pico.registerComponentImplementation(MutablePicoContainer.class, picoContainerClass, new Parameter[] { new ConstantParameter(picoContainer) }); 200 picoContainer = (MutablePicoContainer) pico.getComponentInstanceOfType(MutablePicoContainer.class); 201 return picoContainer; 202 } 203 204 } 205 | Popular Tags |