1 8 package org.apache.avalon.phoenix.components.classloader; 9 10 import java.io.File ; 11 import java.io.IOException ; 12 import java.net.JarURLConnection ; 13 import java.net.URL ; 14 import java.security.Policy ; 15 import java.util.ArrayList ; 16 import java.util.Arrays ; 17 import java.util.jar.Manifest ; 18 import org.apache.avalon.excalibur.extension.Extension; 19 import org.apache.avalon.excalibur.i18n.ResourceManager; 20 import org.apache.avalon.excalibur.i18n.Resources; 21 import org.apache.avalon.excalibur.packagemanager.ExtensionManager; 22 import org.apache.avalon.excalibur.packagemanager.OptionalPackage; 23 import org.apache.avalon.excalibur.packagemanager.PackageManager; 24 import org.apache.avalon.framework.configuration.Configuration; 25 import org.apache.avalon.framework.configuration.ConfigurationException; 26 import org.apache.avalon.framework.context.Context; 27 import org.apache.avalon.framework.context.ContextException; 28 import org.apache.avalon.framework.context.Contextualizable; 29 import org.apache.avalon.framework.logger.AbstractLogEnabled; 30 import org.apache.avalon.framework.service.ServiceException; 31 import org.apache.avalon.framework.service.ServiceManager; 32 import org.apache.avalon.framework.service.Serviceable; 33 import org.apache.avalon.phoenix.interfaces.ClassLoaderManager; 34 35 50 public class DefaultClassLoaderManager 51 extends AbstractLogEnabled 52 implements ClassLoaderManager, Contextualizable, Serviceable 53 { 54 private static final Resources REZ = 55 ResourceManager.getPackageResources( DefaultClassLoaderManager.class ); 56 57 62 private PackageManager m_packageManager; 63 64 68 private ClassLoader m_commonClassLoader; 69 70 81 public void contextualize( Context context ) 82 throws ContextException 83 { 84 m_commonClassLoader = (ClassLoader )context.get( "common.classloader" ); 85 } 86 87 public void service( final ServiceManager serviceManager ) 88 throws ServiceException 89 { 90 final ExtensionManager packageRepository = 91 (ExtensionManager)serviceManager.lookup( ExtensionManager.ROLE ); 92 m_packageManager = new PackageManager( packageRepository ); 93 } 94 95 109 public ClassLoader createClassLoader( final Configuration environment, 110 final File source, 111 final File homeDirectory, 112 final File workDirectory, 113 final String [] classPath ) 114 throws Exception 115 { 116 if( getLogger().isDebugEnabled() ) 117 { 118 final String message = 119 REZ.getString( "classpath-entries", 120 Arrays.asList( classPath ) ); 121 getLogger().debug( message ); 122 } 123 124 final Configuration policyConfig = environment.getChild( "policy" ); 126 final Policy policy = 127 configurePolicy( policyConfig, homeDirectory, workDirectory ); 128 129 final File [] extensions = getOptionalPackagesFor( classPath ); 130 if( getLogger().isDebugEnabled() ) 131 { 132 final String message = 133 REZ.getString( "optional-packages-added", Arrays.asList( extensions ) ); 134 getLogger().debug( message ); 135 } 136 137 final PolicyClassLoader classLoader = 138 new PolicyClassLoader( classPath, m_commonClassLoader, policy ); 139 setupLogger( classLoader, "classloader" ); 140 141 for( int i = 0; i < extensions.length; i++ ) 142 { 143 final URL url = extensions[ i ].toURL(); 144 classLoader.addURL( url ); 145 } 146 147 return classLoader; 148 } 149 150 157 private File [] getOptionalPackagesFor( final String [] classPath ) 158 throws Exception 159 { 160 final Manifest [] manifests = getManifests( classPath ); 161 final Extension[] available = Extension.getAvailable( manifests ); 162 final Extension[] required = Extension.getRequired( manifests ); 163 164 if( getLogger().isDebugEnabled() ) 165 { 166 final String message1 = 167 REZ.getString( "available-extensions", 168 Arrays.asList( available ) ); 169 getLogger().debug( message1 ); 170 final String message2 = 171 REZ.getString( "required-extensions", 172 Arrays.asList( required ) ); 173 getLogger().debug( message2 ); 174 } 175 176 final ArrayList dependencies = new ArrayList (); 177 final ArrayList unsatisfied = new ArrayList (); 178 179 m_packageManager.scanDependencies( required, 180 available, 181 dependencies, 182 unsatisfied ); 183 184 if( 0 != unsatisfied.size() ) 185 { 186 final int size = unsatisfied.size(); 187 for( int i = 0; i < size; i++ ) 188 { 189 final Extension extension = (Extension)unsatisfied.get( i ); 190 final Object [] params = new Object [] 191 { 192 extension.getExtensionName(), 193 extension.getSpecificationVendor(), 194 extension.getSpecificationVersion(), 195 extension.getImplementationVendor(), 196 extension.getImplementationVendorID(), 197 extension.getImplementationVersion(), 198 extension.getImplementationURL() 199 }; 200 final String message = REZ.format( "missing.extension", params ); 201 getLogger().warn( message ); 202 } 203 204 final String message = 205 REZ.getString( "unsatisfied.extensions", new Integer ( size ) ); 206 throw new Exception ( message ); 207 } 208 209 final OptionalPackage[] packages = 210 (OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] ); 211 return OptionalPackage.toFiles( packages ); 212 } 213 214 private Manifest [] getManifests( final String [] classPath ) 215 throws Exception 216 { 217 final ArrayList manifests = new ArrayList (); 218 219 for( int i = 0; i < classPath.length; i++ ) 220 { 221 final String element = classPath[ i ]; 222 223 if( element.endsWith( ".jar" ) ) 224 { 225 try 226 { 227 final URL url = new URL ( "jar:" + element + "!/" ); 228 final JarURLConnection connection = (JarURLConnection )url.openConnection(); 229 final Manifest manifest = connection.getManifest(); 230 if( null != manifest ) 231 { 232 manifests.add( manifest ); 233 } 234 } 235 catch( final IOException ioe ) 236 { 237 final String message = REZ.getString( "bad-classpath-entry", element ); 238 getLogger().warn( message ); 239 throw new Exception ( message ); 240 } 241 } 242 } 243 244 return (Manifest [])manifests.toArray( new Manifest [ 0 ] ); 245 } 246 247 254 private Policy configurePolicy( final Configuration configuration, 255 final File baseDirectory, 256 final File workDirectory ) 257 throws ConfigurationException 258 { 259 final DefaultPolicy policy = 260 new DefaultPolicy( baseDirectory, workDirectory ); 261 policy.enableLogging( getLogger() ); 262 policy.configure( configuration ); 263 return policy; 264 } 265 } 266 | Popular Tags |