001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.discovery.jdk;
018    
019    import java.io.IOException;
020    import java.net.URL;
021    import java.util.Enumeration;
022    
023    /**
024     * JDK 1.1 Style Hooks implementation.
025     */
026    public class JDK11Hooks extends JDKHooks {
027    
028        private static final ClassLoader systemClassLoader = new PsuedoSystemClassLoader();
029    
030        /**
031         * {@inheritDoc}
032         */
033        @Override
034        public String getSystemProperty(final String propName) {
035            return System.getProperty(propName);
036        }
037    
038        /**
039         * {@inheritDoc}
040         */
041        @Override
042        public ClassLoader getThreadContextClassLoader() {
043            return null;
044        }
045    
046        /**
047         * {@inheritDoc}
048         */
049        @Override
050        public ClassLoader getSystemClassLoader() {
051            return systemClassLoader;
052        }
053    
054        /**
055         * {@inheritDoc}
056         */
057        @Override
058        public Enumeration<URL> getResources(ClassLoader loader, String resourceName) throws IOException {
059            /*
060             * The simple answer is/was:
061             *    return loader.getResources(resourceName);
062             * 
063             * However, some classloaders overload the behavior of getResource
064             * (loadClass, etc) such that the order of returned results changes
065             * from normally expected behavior.
066             * 
067             * Example: locate classes/resources from child ClassLoaders first,
068             *          parents last (in some J2EE environs).
069             * 
070             * The resource returned by getResource() should be the same as the
071             * first resource returned by getResources().  Unfortunately, this
072             * is not, and cannot be: getResources() is 'final' in the current
073             * JDK's (1.2, 1.3, 1.4).
074             * 
075             * To address this, the implementation of this method will
076             * return an Enumeration such that the first element is the
077             * results of getResource, and all trailing elements are
078             * from getResources.  On each iteration, we check so see
079             * if the resource (from getResources) matches the first resource,
080             * and eliminate the redundent element.
081             */
082    
083            final URL first = loader.getResource(resourceName);
084    
085            final Enumeration<URL> rest = loader.getResources(resourceName);
086    
087            return new Enumeration<URL>() {
088    
089                private boolean firstDone = (first == null);
090    
091                private URL next = getNext();
092    
093                public URL nextElement() {
094                    URL o = next;
095                    next = getNext();
096                    return o;
097                }
098    
099                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    }