1. /*
  2. * $Header$
  3. * $Revision$
  4. * $Date$
  5. *
  6. * ====================================================================
  7. *
  8. * The Apache Software License, Version 1.1
  9. *
  10. * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
  11. * reserved.
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. *
  20. * 2. Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in
  22. * the documentation and/or other materials provided with the
  23. * distribution.
  24. *
  25. * 3. The end-user documentation included with the redistribution, if
  26. * any, must include the following acknowlegement:
  27. * "This product includes software developed by the
  28. * Apache Software Foundation (http://www.apache.org/)."
  29. * Alternately, this acknowlegement may appear in the software itself,
  30. * if and wherever such third-party acknowlegements normally appear.
  31. *
  32. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  33. * Foundation" must not be used to endorse or promote products derived
  34. * from this software without prior written permission. For written
  35. * permission, please contact apache@apache.org.
  36. *
  37. * 5. Products derived from this software may not be called "Apache"
  38. * nor may "Apache" appear in their names without prior written
  39. * permission of the Apache Group.
  40. *
  41. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  42. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  43. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  45. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  47. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  48. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  49. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  50. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  51. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52. * SUCH DAMAGE.
  53. * ====================================================================
  54. *
  55. * This software consists of voluntary contributions made by many
  56. * individuals on behalf of the Apache Software Foundation. For more
  57. * information on the Apache Software Foundation, please see
  58. * <http://www.apache.org/>.
  59. *
  60. */
  61. package org.apache.commons.discovery.jdk;
  62. import java.io.IOException;
  63. import java.net.URL;
  64. import java.util.Enumeration;
  65. /**
  66. * @author Richard A. Sitze
  67. */
  68. class JDK12Hooks extends JDKHooks {
  69. private static final ClassLoader systemClassLoader
  70. = findSystemClassLoader();
  71. /**
  72. * The thread context class loader is available for JDK 1.2
  73. * or later, if certain security conditions are met.
  74. *
  75. * @return The thread context class loader, if available.
  76. * Otherwise return null.
  77. */
  78. public ClassLoader getThreadContextClassLoader() {
  79. ClassLoader classLoader;
  80. try {
  81. classLoader = Thread.currentThread().getContextClassLoader();
  82. } catch (SecurityException e) {
  83. /**
  84. * SecurityException is thrown when
  85. * a) the context class loader isn't an ancestor of the
  86. * calling class's class loader, or
  87. * b) if security permissions are restricted.
  88. *
  89. * For (a), ignore and keep going. We cannot help but also
  90. * ignore (b) with the logic below, but other calls elsewhere
  91. * (to obtain a class loader) will re-trigger this exception
  92. * where we can make a distinction.
  93. */
  94. classLoader = null; // ignore
  95. }
  96. // Return the selected class loader
  97. return classLoader;
  98. }
  99. /**
  100. * The system class loader is available for JDK 1.2
  101. * or later, if certain security conditions are met.
  102. *
  103. * @return The system class loader, if available.
  104. * Otherwise return null.
  105. */
  106. public ClassLoader getSystemClassLoader() {
  107. return systemClassLoader;
  108. }
  109. /**
  110. * Implement ClassLoader.getResources for JDK 1.2
  111. */
  112. public Enumeration getResources(ClassLoader loader,
  113. String resourceName)
  114. throws IOException
  115. {
  116. /**
  117. * The simple answer is/was:
  118. * return loader.getResources(resourceName);
  119. *
  120. * However, some classloaders overload the behavior of getResource
  121. * (loadClass, etc) such that the order of returned results changes
  122. * from normally expected behavior.
  123. *
  124. * Example: locate classes/resources from child ClassLoaders first,
  125. * parents last (in some J2EE environs).
  126. *
  127. * The resource returned by getResource() should be the same as the
  128. * first resource returned by getResources(). Unfortunately, this
  129. * is not, and cannot be: getResources() is 'final' in the current
  130. * JDK's (1.2, 1.3, 1.4).
  131. *
  132. * To address this, the implementation of this method will
  133. * return an Enumeration such that the first element is the
  134. * results of getResource, and all trailing elements are
  135. * from getResources. On each iteration, we check so see
  136. * if the resource (from getResources) matches the first resource,
  137. * and eliminate the redundent element.
  138. */
  139. final URL first = (URL)loader.getResource(resourceName);
  140. final Enumeration rest = loader.getResources(resourceName);
  141. return new Enumeration() {
  142. private boolean firstDone = (first == null);
  143. private URL next = getNext();
  144. public Object nextElement() {
  145. URL o = next;
  146. next = getNext();
  147. return o;
  148. }
  149. public boolean hasMoreElements() {
  150. return next != null;
  151. }
  152. private URL getNext() {
  153. URL n;
  154. if (!firstDone) {
  155. /**
  156. * First time through, use results of getReference()
  157. * if they were non-null.
  158. */
  159. firstDone = true;
  160. n = first;
  161. } else {
  162. /**
  163. * Subsequent times through,
  164. * use results of getReferences()
  165. * but take out anything that matches 'first'.
  166. *
  167. * Iterate through list until we find one that
  168. * doesn't match 'first'.
  169. */
  170. n = null;
  171. while (rest.hasMoreElements() && n == null) {
  172. n = (URL)rest.nextElement();
  173. if (first != null &&
  174. n != null &&
  175. n.equals(first))
  176. {
  177. n = null;
  178. }
  179. }
  180. }
  181. return n;
  182. }
  183. };
  184. }
  185. static private ClassLoader findSystemClassLoader() {
  186. ClassLoader classLoader;
  187. try {
  188. classLoader = ClassLoader.getSystemClassLoader();
  189. } catch (SecurityException e) {
  190. /**
  191. * Ignore and keep going.
  192. */
  193. classLoader = null;
  194. }
  195. if (classLoader == null) {
  196. classLoader = new PsuedoSystemClassLoader();
  197. }
  198. // Return the selected class loader
  199. return classLoader;
  200. }
  201. }