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   * JDK 1.1 Style Hooks implementation.
25   */
26  public class JDK11Hooks extends JDKHooks {
27  
28      private static final ClassLoader systemClassLoader = new PsuedoSystemClassLoader();
29  
30      /**
31       * {@inheritDoc}
32       */
33      @Override
34      public String getSystemProperty(final String propName) {
35          return System.getProperty(propName);
36      }
37  
38      /**
39       * {@inheritDoc}
40       */
41      @Override
42      public ClassLoader getThreadContextClassLoader() {
43          return null;
44      }
45  
46      /**
47       * {@inheritDoc}
48       */
49      @Override
50      public ClassLoader getSystemClassLoader() {
51          return systemClassLoader;
52      }
53  
54      /**
55       * {@inheritDoc}
56       */
57      @Override
58      public Enumeration<URL> getResources(ClassLoader loader, String resourceName) throws IOException {
59          /*
60           * The simple answer is/was:
61           *    return loader.getResources(resourceName);
62           * 
63           * However, some classloaders overload the behavior of getResource
64           * (loadClass, etc) such that the order of returned results changes
65           * from normally expected behavior.
66           * 
67           * Example: locate classes/resources from child ClassLoaders first,
68           *          parents last (in some J2EE environs).
69           * 
70           * The resource returned by getResource() should be the same as the
71           * first resource returned by getResources().  Unfortunately, this
72           * is not, and cannot be: getResources() is 'final' in the current
73           * JDK's (1.2, 1.3, 1.4).
74           * 
75           * To address this, the implementation of this method will
76           * return an Enumeration such that the first element is the
77           * results of getResource, and all trailing elements are
78           * from getResources.  On each iteration, we check so see
79           * if the resource (from getResources) matches the first resource,
80           * and eliminate the redundent element.
81           */
82  
83          final URL first = loader.getResource(resourceName);
84  
85          final Enumeration<URL> rest = loader.getResources(resourceName);
86  
87          return new Enumeration<URL>() {
88  
89              private boolean firstDone = (first == null);
90  
91              private URL next = getNext();
92  
93              public URL nextElement() {
94                  URL o = next;
95                  next = getNext();
96                  return o;
97              }
98  
99              public boolean hasMoreElements() {
100                 return next != null;
101             }
102 
103             private URL getNext() {
104                 URL n;
105 
106                 if (!firstDone) {
107                     /*
108                      * First time through, use results of getReference()
109                      * if they were non-null.
110                      */
111                     firstDone = true;
112                     n = first;
113                 } else {
114                     /*
115                      * Subsequent times through,
116                      * use results of getReferences()
117                      * but take out anything that matches 'first'.
118                      * 
119                      * Iterate through list until we find one that
120                      * doesn't match 'first'.
121                      */
122                     n = null;
123                     while (rest.hasMoreElements()  &&  n == null) {
124                         n = rest.nextElement();
125                         if (first != null &&
126                             n != null &&
127                             n.equals(first))
128                         {
129                             n = null;
130                         }
131                     }
132                 }
133 
134                 return n;
135             }
136         };
137     }
138 
139 }