KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > loom > components > classloader > DefaultClassLoaderManager


1 /* ====================================================================
2  * Loom Software License, version 1.1
3  *
4  * Copyright (c) 2003, Loom Group. All rights reserved.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * 3. Neither the name of the Loom Group nor the name "Loom" nor
18  * the names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior
20  * written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * ====================================================================
36  *
37  * Loom includes code from the Apache Software Foundation
38  *
39  * ====================================================================
40  * The Apache Software License, Version 1.1
41  *
42  * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
43  * reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  *
49  * 1. Redistributions of source code must retain the above copyright
50  * notice, this list of conditions and the following disclaimer.
51  *
52  * 2. Redistributions in binary form must reproduce the above copyright
53  * notice, this list of conditions and the following disclaimer in
54  * the documentation and/or other materials provided with the
55  * distribution.
56  *
57  * 3. The end-user documentation included with the redistribution,
58  * if any, must include the following acknowledgment:
59  * "This product includes software developed by the
60  * Apache Software Foundation (http://www.apache.org/)."
61  * Alternately, this acknowledgment may appear in the software
62  * itself, if and wherever such third-party acknowledgments
63  * normally appear.
64  *
65  * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
66  * must not be used to endorse or promote products derived from this
67  * software without prior written permission. For written
68  * permission, please contact apache@apache.org.
69  *
70  * 5. Products derived from this software may not be called "Apache",
71  * nor may "Apache" appear in their name, without prior written
72  * permission of the Apache Software Foundation.
73  *
74  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
75  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
76  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
78  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
79  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
80  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
81  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
82  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
83  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
84  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85  * SUCH DAMAGE.
86  */

87 package org.codehaus.loom.components.classloader;
88
89 import java.io.File JavaDoc;
90 import java.net.URL JavaDoc;
91 import java.security.Policy JavaDoc;
92 import java.util.Collections JavaDoc;
93 import java.util.HashMap JavaDoc;
94 import java.util.Map JavaDoc;
95
96 import org.codehaus.loom.classman.builder.LoaderBuilder;
97 import org.codehaus.loom.classman.builder.LoaderResolver;
98 import org.codehaus.loom.classman.metadata.ClassLoaderMetaData;
99 import org.codehaus.loom.classman.metadata.ClassLoaderSetMetaData;
100 import org.codehaus.loom.classman.metadata.FileSetMetaData;
101 import org.codehaus.loom.classman.metadata.JoinMetaData;
102 import org.codehaus.loom.classman.reader.ClassLoaderSetReader;
103 import org.codehaus.loom.classman.verifier.ClassLoaderVerifier;
104 import org.codehaus.loom.components.extensions.pkgmgr.ExtensionManager;
105 import org.codehaus.loom.components.extensions.pkgmgr.PackageManager;
106 import org.codehaus.loom.extension.Extension;
107 import org.codehaus.loom.interfaces.ClassLoaderManager;
108 import org.codehaus.loom.interfaces.ClassLoaderSet;
109 import org.codehaus.loom.xmlpolicy.builder.PolicyBuilder;
110 import org.codehaus.loom.xmlpolicy.metadata.PolicyMetaData;
111 import org.codehaus.loom.xmlpolicy.reader.PolicyReader;
112 import org.codehaus.spice.configkit.PropertyExpander;
113 import org.codehaus.dna.AbstractLogEnabled;
114 import org.codehaus.dna.Active;
115 import org.codehaus.dna.Composable;
116 import org.codehaus.dna.Configuration;
117 import org.codehaus.dna.ConfigurationException;
118 import org.codehaus.dna.MissingResourceException;
119 import org.codehaus.dna.ResourceLocator;
120 import org.codehaus.dna.impl.ConfigurationUtil;
121 import org.w3c.dom.Element JavaDoc;
122
123 /**
124  * Component that creates and manages the {@link ClassLoader} for an application
125  * loaded out of a <tt>.sar</tt> deployment.
126  *
127  * <p>Currently it creates a policy based on the policy declaration in the
128  * configuration. It then just creates a URLClassLoader and populates it with
129  * the specified codebase {@link URL}s.</p>
130  *
131  * <p>In the future this class will scan the manifests for "Optional Packages"
132  * formely called "Extensions" which it will add to the {@link ClassLoader}</p>
133  *
134  * @author Peter Donald
135  * @see ClassLoaderManager
136  */

137 public class DefaultClassLoaderManager
138     extends AbstractLogEnabled
139     implements ClassLoaderManager, Composable, Active
140 {
141     /**
142      * Constant for name of element that indicates custom classloader tree to
143      * define.
144      */

145     private static final String JavaDoc CLASSLOADERS_ELEMENT = "classloaders";
146
147     /**
148      * Component to manage "Optional Packages" aka Extensions to allow programs
149      * to declare dependencies on such extensions.
150      */

151     private PackageManager m_packageManager;
152
153     /**
154      * Parent ClassLoader for all applications aka as the "common" classloader.
155      */

156     private ClassLoader JavaDoc m_commonClassLoader;
157
158     /**
159      * The utility class used to verify {@link ClassLoaderMetaData} objects.
160      */

161     private final ClassLoaderVerifier m_verifier = new ClassLoaderVerifier();
162
163     /**
164      * Utility class to build map of {@link ClassLoader} objects.
165      */

166     private final LoaderBuilder m_builder = new LoaderBuilder();
167
168     /**
169      * Utility class to read {@link ClassLoaderSetMetaData} objects from XML
170      * trees.
171      */

172     private final ClassLoaderSetReader m_reader = new ClassLoaderSetReader();
173
174     /**
175      * The map of predefined ClassLoaders. In the current incarnation this only
176      * contains the system classloader.
177      */

178     private Map JavaDoc m_predefinedLoaders;
179
180     /**
181      * The contextdata used in interpolation of the policy configuration file.
182      */

183     private final Map JavaDoc m_data = new HashMap JavaDoc();
184
185     /**
186      * The property expander that will expand properties in the policy
187      * configuraiton file.
188      */

189     private final PropertyExpander m_expander = new PropertyExpander();
190
191     /**
192      * @dna.dependency type="ExtensionManager"
193      * @dna.dependency type="ClassLoader/common"
194      */

195     public void compose( final ResourceLocator locator )
196         throws MissingResourceException
197     {
198         final ExtensionManager extensionManager = (ExtensionManager) locator.lookup(
199             ExtensionManager.class.getName() );
200         m_packageManager = new PackageManager( extensionManager );
201         m_commonClassLoader = (ClassLoader JavaDoc) locator.lookup(
202             ClassLoader JavaDoc.class.getName() + "/common" );
203     }
204
205     /**
206      * Setup the map of predefined classloaders.
207      *
208      * @throws Exception if unable to setup map
209      */

210     public void initialize() throws Exception JavaDoc
211     {
212         m_data.putAll( System.getProperties() );
213
214         final Map JavaDoc defined = new HashMap JavaDoc();
215         defined.put( "*system*", ClassLoader.getSystemClassLoader() );
216         defined.put( "*common*", m_commonClassLoader );
217         defined.put( "*shared*", m_commonClassLoader );
218         m_predefinedLoaders = Collections.unmodifiableMap( defined );
219     }
220
221     public void dispose() throws Exception JavaDoc
222     {
223     }
224
225     /**
226      * Create a {@link ClassLoader} for a specific application. See Class
227      * Javadoc for description of technique for creating {@link ClassLoader}.
228      *
229      * @param environment the configuration "environment.xml" for the
230      * application
231      * @param homeDirectory the base directory of application
232      * @param workDirectory the work directory of application
233      * @return the ClassLoader created
234      * @throws Exception if an error occurs
235      */

236     public ClassLoaderSet createClassLoaderSet(
237         final Configuration environment,
238         final Map JavaDoc data,
239         final File JavaDoc homeDirectory,
240         final File JavaDoc workDirectory ) throws Exception JavaDoc
241     {
242         //Configure policy
243
final Configuration policyConfig = environment.getChild( "policy" );
244         final Policy JavaDoc policy = configurePolicy( policyConfig,
245                                                data,
246                                                homeDirectory,
247                                                workDirectory );
248
249         final ClassLoaderSetMetaData metaData = getLoaderMetaData( environment );
250
251         m_verifier.verifyClassLoaderSet( metaData );
252
253         final LoaderResolver resolver = new SarLoaderResolver(
254             m_packageManager, policy, homeDirectory, workDirectory );
255         setupLogger( resolver );
256         final Map JavaDoc map = m_builder.buildClassLoaders( metaData,
257                                                      resolver,
258                                                      m_predefinedLoaders );
259         final ClassLoader JavaDoc defaultClassLoader = (ClassLoader JavaDoc) map.get(
260             metaData.getDefault() );
261         return new ClassLoaderSet( defaultClassLoader, map );
262     }
263
264     /**
265      * Extract the {@link ClassLoaderMetaData} from the environment
266      * configuration. If no &lt;classloader/&gt; section is defined in the
267      * config file then a default metadata will be created.
268      *
269      * @param environment the environment configuration
270      * @return the {@link ClassLoaderMetaData} object
271      */

272     private ClassLoaderSetMetaData getLoaderMetaData(
273         final Configuration environment ) throws Exception JavaDoc
274     {
275         final boolean loaderDefined = isClassLoaderDefined( environment );
276         if( !loaderDefined )
277         {
278             return createDefaultLoaderMetaData();
279         }
280         else
281         {
282             final Configuration loaderConfig = environment.getChild(
283                 CLASSLOADERS_ELEMENT );
284             final Element JavaDoc element = ConfigurationUtil.toElement( loaderConfig );
285             return m_reader.build( element );
286         }
287     }
288
289     /**
290      * Create the default {@link ClassLoaderSetMetaData}. The default metadata
291      * includes all jars in the /SAR-INF/lib/ directory in addition to the
292      * /SAR-INF/classes/ directory.
293      *
294      * @return the default {@link ClassLoaderSetMetaData} object
295      */

296     private ClassLoaderSetMetaData createDefaultLoaderMetaData()
297     {
298         final String JavaDoc[] includes = new String JavaDoc[]{"SAR-INF/lib/*.jar"};
299         final String JavaDoc[] excludes = new String JavaDoc[ 0 ];
300         final FileSetMetaData fileSet = new FileSetMetaData( ".",
301                                                              includes,
302                                                              excludes );
303         final String JavaDoc name = "default";
304         final String JavaDoc parent = "*system*";
305         final String JavaDoc[] entrys = new String JavaDoc[]{"SAR-INF/classes/"};
306         final Extension[] extensions = new Extension[ 0 ];
307         final FileSetMetaData[] filesets = new FileSetMetaData[]{fileSet};
308         final ClassLoaderMetaData loader = new ClassLoaderMetaData( name,
309                                                                     parent,
310                                                                     entrys,
311                                                                     extensions,
312                                                                     filesets );
313         final String JavaDoc[] predefined = new String JavaDoc[]{parent};
314         final ClassLoaderMetaData[] classLoaders = new ClassLoaderMetaData[]{
315             loader};
316         final JoinMetaData[] joins = new JoinMetaData[ 0 ];
317         return new ClassLoaderSetMetaData( name,
318                                            predefined,
319                                            classLoaders,
320                                            joins );
321     }
322
323     /**
324      * Return true if environment config defines "classloader" element, false
325      * otherwise.
326      *
327      * @param environment the environment config
328      * @return true if environment config defines "classloader" element, false
329      * otherwise.
330      */

331     private boolean isClassLoaderDefined( final Configuration environment )
332     {
333         return null != environment.getChild( CLASSLOADERS_ELEMENT, false );
334     }
335
336     /**
337      * Setup policy based on configuration data.
338      *
339      * @param configuration the configuration data
340      * @param data the context data used to expand policy file
341      * @param baseDirectory the applications base directory
342      * @throws ConfigurationException if an error occurs
343      */

344     private Policy JavaDoc configurePolicy( final Configuration configuration,
345                                     final Map JavaDoc data,
346                                     final File JavaDoc baseDirectory,
347                                     final File JavaDoc workDirectory )
348         throws Exception JavaDoc
349     {
350         final SarPolicyResolver resolver = new SarPolicyResolver(
351             baseDirectory, workDirectory );
352         setupLogger( resolver );
353         final PolicyBuilder builder = new PolicyBuilder();
354         final PolicyReader reader = new PolicyReader();
355         final SarPolicyVerifier verifier = new SarPolicyVerifier();
356         setupLogger( verifier );
357
358         final Element JavaDoc element = ConfigurationUtil.toElement( configuration );
359         final HashMap JavaDoc newData = new HashMap JavaDoc();
360         newData.putAll( m_data );
361         newData.putAll( data );
362         newData.put( "/", File.separator );
363
364         m_expander.expandValues( element, newData );
365
366         element.setAttribute( "version", "1.0" );
367         try
368         {
369             final PolicyMetaData policy = reader.readPolicy( element );
370             verifier.verifyPolicy( policy );
371             return builder.buildPolicy( policy, resolver );
372         }
373         catch( final Exception JavaDoc e )
374         {
375             throw new ConfigurationException( e.getMessage(), e );
376         }
377     }
378 }
379
Popular Tags