View Javadoc

1   /*
2    * Copyright 2002-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.clazz.common;
17  
18  import java.lang.reflect.Constructor;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.clazz.ClazzAccessException;
23  import org.apache.commons.clazz.ClazzLoader;
24  import org.apache.commons.clazz.ClazzLoaderFactory;
25  import org.apache.commons.clazz.ModelClazzLoader;
26  import org.apache.commons.collections.ReferenceMap;
27  
28  /**
29   * 
30   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
31   * @version $Id: ClazzLoaderFactorySupport.java 155436 2005-02-26 13:17:48Z dirkv $
32   */
33  public abstract class ClazzLoaderFactorySupport implements ClazzLoaderFactory {
34  
35      private List clazzLoaderClasses = new ArrayList();
36  
37      private ClazzLoader defaultClazzLoader;
38  
39      private ReferenceMap clazzLoaders =
40          new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD);
41  
42      /**
43       * Constructor for ClazzLoaderFactorySupport.
44       */
45      protected ClazzLoaderFactorySupport() {
46      }
47  
48      /**
49       * @see ClazzLoaderFactory#getClazzLoader(ClassLoader)
50       */
51      public synchronized ClazzLoader getClazzLoader(
52              ClassLoader contextClassLoader) 
53      {
54          if (contextClassLoader == null) {
55              if (defaultClazzLoader == null) {
56                  defaultClazzLoader = createClazzLoader(null);
57              }
58              return defaultClazzLoader;
59          }
60          else {
61              ClazzLoader loader =
62                  (ClazzLoader) clazzLoaders.get(contextClassLoader);
63              if (loader == null) {
64                  loader = createClazzLoader(contextClassLoader);
65                  clazzLoaders.put(contextClassLoader, loader);
66              }
67              return loader;
68          }
69      }
70  
71      protected ClazzLoader createClazzLoader(ClassLoader contextClassLoader) {
72          ModelClazzLoader modelClazzLoader =
73              new ModelClazzLoader(getClazzModel());
74  
75          for (int i = 0; i < clazzLoaderClasses.size(); i++) {
76              Class javaClass = (Class) clazzLoaderClasses.get(i);
77              ClazzLoader clazzLoader =
78                  allocateClazzLoader(
79                      modelClazzLoader,
80                      javaClass,
81                      contextClassLoader);
82              modelClazzLoader.addClazzLoader(clazzLoader);
83          }
84  
85          return modelClazzLoader;
86      }
87  
88      protected ClazzLoader allocateClazzLoader(
89          ModelClazzLoader modelClazzLoader,
90          Class javaClass,
91          ClassLoader contextClassLoader) 
92      {
93          try {
94              Constructor constructor = null;
95              try {
96                  constructor =
97                      javaClass.getConstructor(
98                          new Class[] {
99                              ModelClazzLoader.class,
100                             ClassLoader.class });
101             }
102             catch (NoSuchMethodException e) {
103                 // Won't happen
104             }
105             if (constructor != null) {
106                 return (ClazzLoader) constructor.newInstance(
107                     new Object[] { modelClazzLoader, contextClassLoader });
108             }
109 
110             try {
111                 constructor =
112                     javaClass.getConstructor(
113                         new Class[] { ModelClazzLoader.class });
114             }
115             catch (NoSuchMethodException e) {
116                 // Won't happen
117             }
118             if (constructor != null) {
119                 return (ClazzLoader) constructor.newInstance(
120                     new Object[] { modelClazzLoader });
121             }
122             throw new IllegalArgumentException("Missing constructor");
123         }
124         catch (Exception e) {
125             throw new ClazzAccessException(
126                 "Cannot allocate ClazzLoader " + javaClass.getName(),
127                 e);
128         }
129     }
130 
131     public void addClazzLoaderClass(Class clazzLoaderClass) {
132         clazzLoaderClasses.add(clazzLoaderClass);
133     }
134 }