View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.discovery.jdk;
18  
19  import java.io.IOException;
20  import java.net.URL;
21  import java.util.Enumeration;
22  
23  
24  /***
25   * @author Richard A. Sitze
26   */
27  public class JDK11Hooks extends JDKHooks {
28      private static final ClassLoader systemClassLoader
29          = new PsuedoSystemClassLoader();
30  
31      /***
32       * Get the system property
33       *
34       * @param propName name of the property
35       * @return value of the property
36       */
37      public String getSystemProperty(final String propName) {
38          return System.getProperty(propName);
39      }
40  
41      /***
42       * The thread context class loader is available for JDK 1.2
43       * or later, if certain security conditions are met.
44       * 
45       * @return The thread context class loader, if available.
46       *         Otherwise return null.
47       */
48      public ClassLoader getThreadContextClassLoader() {
49          return null;
50      }
51      
52      /***
53       * The system class loader is available for JDK 1.2
54       * or later, if certain security conditions are met.
55       * 
56       * @return The system class loader, if available.
57       *         Otherwise return null.
58       */
59      public ClassLoader getSystemClassLoader() {
60          return systemClassLoader;
61      }
62  
63      /***
64       * Implement ClassLoader.getResources for JDK 1.1
65       * 
66       * On JDK1.1 there is no getResources() method. We emulate this by
67       * using introspection and doing the lookup ourself, using the list
68       * of URLs, via getURLs().
69       */
70      public Enumeration getResources(ClassLoader loader,
71                                      String resourceName)
72          throws IOException
73      {
74          /***
75           * The simple answer is/was:
76           *    return loader.getResources(resourceName);
77           * 
78           * However, some classloaders overload the behavior of getResource
79           * (loadClass, etc) such that the order of returned results changes
80           * from normally expected behavior.
81           * 
82           * Example: locate classes/resources from child ClassLoaders first,
83           *          parents last (in some J2EE environs).
84           * 
85           * The resource returned by getResource() should be the same as the
86           * first resource returned by getResources().  Unfortunately, this
87           * is not, and cannot be: getResources() is 'final' in the current
88           * JDK's (1.2, 1.3, 1.4).
89           * 
90           * To address this, the implementation of this method will
91           * return an Enumeration such that the first element is the
92           * results of getResource, and all trailing elements are
93           * from getResources.  On each iteration, we check so see
94           * if the resource (from getResources) matches the first resource,
95           * and eliminate the redundent element.
96           */
97          
98          final URL first = (URL)loader.getResource(resourceName);
99          final Enumeration rest = loader.getResources(resourceName);
100         
101         return new Enumeration() {
102             private boolean firstDone = (first == null);
103             private URL next = getNext();
104             
105             public Object nextElement() {
106                 URL o = next;
107                 next = getNext();
108                 return o;
109             }
110 
111             public boolean hasMoreElements() {
112                 return next != null;
113             }
114             
115             private URL getNext() {
116                 URL n;
117                 
118                 if (!firstDone) {
119                     /***
120                      * First time through, use results of getReference()
121                      * if they were non-null.
122                      */
123                     firstDone = true;
124                     n = first;
125                 } else {
126                     /***
127                      * Subsequent times through,
128                      * use results of getReferences()
129                      * but take out anything that matches 'first'.
130                      * 
131                      * Iterate through list until we find one that
132                      * doesn't match 'first'.
133                      */
134                     n = null;
135                     while (rest.hasMoreElements()  &&  n == null) {
136                         n = (URL)rest.nextElement();
137                         if (first != null &&
138                             n != null &&
139                             n.equals(first))
140                         {
141                             n = null;
142                         }
143                     }
144                 }
145                 
146                 return n;
147             }
148         };
149     }
150 }