001 /*
002 * Copyright 2002-2004 The Apache Software Foundation
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.apache.commons.clazz.common;
017
018 import java.lang.reflect.Constructor;
019 import java.util.ArrayList;
020 import java.util.List;
021
022 import org.apache.commons.clazz.ClazzAccessException;
023 import org.apache.commons.clazz.ClazzLoader;
024 import org.apache.commons.clazz.ClazzLoaderFactory;
025 import org.apache.commons.clazz.ModelClazzLoader;
026 import org.apache.commons.collections.ReferenceMap;
027
028 /**
029 *
030 * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
031 * @version $Id: ClazzLoaderFactorySupport.java 155436 2005-02-26 13:17:48Z dirkv $
032 */
033 public abstract class ClazzLoaderFactorySupport implements ClazzLoaderFactory {
034
035 private List clazzLoaderClasses = new ArrayList();
036
037 private ClazzLoader defaultClazzLoader;
038
039 private ReferenceMap clazzLoaders =
040 new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD);
041
042 /**
043 * Constructor for ClazzLoaderFactorySupport.
044 */
045 protected ClazzLoaderFactorySupport() {
046 }
047
048 /**
049 * @see ClazzLoaderFactory#getClazzLoader(ClassLoader)
050 */
051 public synchronized ClazzLoader getClazzLoader(
052 ClassLoader contextClassLoader)
053 {
054 if (contextClassLoader == null) {
055 if (defaultClazzLoader == null) {
056 defaultClazzLoader = createClazzLoader(null);
057 }
058 return defaultClazzLoader;
059 }
060 else {
061 ClazzLoader loader =
062 (ClazzLoader) clazzLoaders.get(contextClassLoader);
063 if (loader == null) {
064 loader = createClazzLoader(contextClassLoader);
065 clazzLoaders.put(contextClassLoader, loader);
066 }
067 return loader;
068 }
069 }
070
071 protected ClazzLoader createClazzLoader(ClassLoader contextClassLoader) {
072 ModelClazzLoader modelClazzLoader =
073 new ModelClazzLoader(getClazzModel());
074
075 for (int i = 0; i < clazzLoaderClasses.size(); i++) {
076 Class javaClass = (Class) clazzLoaderClasses.get(i);
077 ClazzLoader clazzLoader =
078 allocateClazzLoader(
079 modelClazzLoader,
080 javaClass,
081 contextClassLoader);
082 modelClazzLoader.addClazzLoader(clazzLoader);
083 }
084
085 return modelClazzLoader;
086 }
087
088 protected ClazzLoader allocateClazzLoader(
089 ModelClazzLoader modelClazzLoader,
090 Class javaClass,
091 ClassLoader contextClassLoader)
092 {
093 try {
094 Constructor constructor = null;
095 try {
096 constructor =
097 javaClass.getConstructor(
098 new Class[] {
099 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 }