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 */
017package org.apache.commons.discovery.resource;
018
019import java.io.IOException;
020import java.net.URL;
021import java.util.Enumeration;
022
023import org.apache.commons.discovery.Resource;
024import org.apache.commons.discovery.ResourceDiscover;
025import org.apache.commons.discovery.ResourceIterator;
026import org.apache.commons.discovery.jdk.JDKHooks;
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029/**
030 * 
031 */
032public 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}