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.resource;
018    
019    import java.io.IOException;
020    import java.net.URL;
021    import java.util.Enumeration;
022    
023    import org.apache.commons.discovery.Resource;
024    import org.apache.commons.discovery.ResourceDiscover;
025    import org.apache.commons.discovery.ResourceIterator;
026    import org.apache.commons.discovery.jdk.JDKHooks;
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    /**
030     * 
031     */
032    public class DiscoverResources extends ResourceDiscoverImpl implements ResourceDiscover {
033    
034        private static Log log = LogFactory.getLog(DiscoverResources.class);
035    
036        /**
037         * Sets the {@code Log} for this class.
038         *
039         * @param _log This class {@code Log}
040         * @deprecated This method is not thread-safe
041         */
042        @Deprecated
043        public static void setLog(Log _log) {
044            log = _log;
045        }
046    
047        /**
048         * Construct a new resource discoverer.
049         */
050        public DiscoverResources() {
051            super();
052        }
053    
054        /**
055         * Construct a new resource discoverer.
056         *
057         * @param classLoaders The class loaders holder
058         */
059        public DiscoverResources(ClassLoaders classLoaders) {
060            super(classLoaders);
061        }
062    
063        /**
064         * {@inheritDoc}
065         */
066        @Override
067        public ResourceIterator findResources(final String resourceName) {
068            if (log.isDebugEnabled()) {
069                log.debug("find: resourceName='" + resourceName + "'");
070            }
071    
072            return new ResourceIterator() {
073    
074                private int idx = 0;
075    
076                private ClassLoader loader = null;
077    
078                private Enumeration<URL> resources = null;
079    
080                private Resource resource = null;
081    
082                public boolean hasNext() {
083                    if (resource == null) {
084                        resource = getNextResource();
085                    }
086                    return resource != null;
087                }
088    
089                @Override
090                public Resource nextResource() {
091                    Resource element = resource;
092                    resource = null;
093                    return element;
094                }
095    
096                private Resource getNextResource() {
097                    if (resources == null || !resources.hasMoreElements()) {
098                        resources = getNextResources();
099                    }
100    
101                    Resource resourceInfo;
102                    if (resources != null) {
103                        URL url = resources.nextElement();
104    
105                        if (log.isDebugEnabled()) {
106                            log.debug("getNextResource: next URL='" + url + "'");
107                        }
108    
109                        resourceInfo = new Resource(resourceName, url, loader);
110                    } else {
111                        resourceInfo = null;
112                    }
113    
114                    return resourceInfo;
115                }
116    
117                private Enumeration<URL> getNextResources() {
118                    while (idx < getClassLoaders().size()) {
119                        loader = getClassLoaders().get(idx++);
120                        if (log.isDebugEnabled()) {
121                            log.debug("getNextResources: search using ClassLoader '" + loader + "'");
122                        }
123                        try {
124                            Enumeration<URL> e = JDKHooks.getJDKHooks().getResources(loader, resourceName);
125                            if (e != null && e.hasMoreElements()) {
126                                return e;
127                            }
128                        } catch( IOException ex ) {
129                            log.warn("getNextResources: Ignoring Exception", ex);
130                        }
131                    }
132                    return null;
133                }
134            };
135        }
136    
137    }