1 /** 2 * The utillib library. 3 * More information is available at http://www.jinchess.com/. 4 * Copyright (C) 2003 Alexander Maryanovsky. 5 * All rights reserved. 6 * 7 * The utillib library is free software; you can redistribute 8 * it and/or modify it under the terms of the GNU Lesser General Public License 9 * as published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * The utillib library is distributed in the hope that it will 13 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with utillib library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 package free.util; 23 24 import java.util.Vector; 25 import java.util.Hashtable; 26 import java.util.Enumeration; 27 import java.io.InputStream; 28 import java.net.URL; 29 30 31 /** 32 * A class loader which delegates loading to other classloaders. 33 */ 34 35 public class DelegatingClassLoader extends ChildClassLoader{ 36 37 38 39 /** 40 * A list of <code>ChildClassLoaders</code> to which we delegate. 41 */ 42 43 private final Vector delegates = new Vector(); 44 45 46 47 /** 48 * The set of class/resource names we are currently in the process of loading. 49 * This is needed to avoid endless recursion in case of delegate 50 * ChildClassLoaders that have this classloader as their parent. 51 */ 52 53 private final Hashtable beingLoaded = new Hashtable(); 54 55 56 57 /** 58 * Creates a new <code>DelegatingClassLoader</code> with the specified parent 59 * class loader. 60 */ 61 DelegatingClassLoader(ChildClassLoader parent)62 public DelegatingClassLoader(ChildClassLoader parent){ 63 super(parent); 64 } 65 66 67 68 /** 69 * Creates a new <code>DelegatingClassLoader</code> with no parent. 70 */ 71 DelegatingClassLoader()72 public DelegatingClassLoader(){ 73 super(); 74 } 75 76 77 78 /** 79 * Adds a delegate class loader. 80 */ 81 addDelegate(ChildClassLoader classLoader)82 public void addDelegate(ChildClassLoader classLoader){ 83 delegates.addElement(classLoader); 84 } 85 86 87 88 /** 89 * Removes the specified delegate class loader. 90 */ 91 removeDelegate(ChildClassLoader classLoader)92 public void removeDelegate(ChildClassLoader classLoader){ 93 delegates.removeElement(classLoader); 94 } 95 96 97 98 /** 99 * Loads and optionally resolves the specified class. 100 */ 101 loadClassImpl(String name, boolean resolve)102 protected Class loadClassImpl(String name, boolean resolve){ 103 if (beingLoaded.containsKey(name)) // Avoid endless recursion 104 return null; 105 106 beingLoaded.put(name, name); 107 Class c = null; 108 Enumeration loaders = delegates.elements(); 109 while (loaders.hasMoreElements()){ 110 ChildClassLoader loader = (ChildClassLoader)loaders.nextElement(); 111 try{ 112 c = loader.loadClass(name, resolve); 113 if (c != null) 114 break; 115 } catch (ClassNotFoundException e){} 116 } 117 118 beingLoaded.remove(name); 119 return c; 120 } 121 122 123 124 /** 125 * Returns an <code>InputStream</code> for reading the resource with the 126 * specified name. 127 */ 128 getResourceAsStreamImpl(String name)129 protected InputStream getResourceAsStreamImpl(String name){ 130 if (beingLoaded.containsKey(name)) // Avoid endless recursion 131 return null; 132 133 beingLoaded.put(name, name); 134 InputStream in = null; 135 Enumeration loaders = delegates.elements(); 136 while (loaders.hasMoreElements()){ 137 ChildClassLoader loader = (ChildClassLoader)loaders.nextElement(); 138 in = loader.getResourceAsStream(name); 139 if (in != null) 140 break; 141 } 142 143 beingLoaded.remove(name); 144 return in; 145 } 146 147 148 149 /** 150 * Returns a <code>URL</code> pointing to the resource with the specified 151 * name. 152 */ 153 getResourceImpl(String name)154 protected URL getResourceImpl(String name){ 155 if (beingLoaded.containsKey(name)) // Avoid endless recursion 156 return null; 157 158 beingLoaded.put(name, name); 159 URL url = null; 160 Enumeration loaders = delegates.elements(); 161 while (loaders.hasMoreElements()){ 162 ChildClassLoader loader = (ChildClassLoader)loaders.nextElement(); 163 url = loader.getResource(name); 164 if (url != null) 165 break; 166 } 167 168 beingLoaded.remove(name); 169 return url; 170 } 171 172 173 174 }