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 }