001 /*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014 package org.apache.commons.classscan.builtin;
015
016 import java.io.IOException;
017 import java.net.URL;
018 import java.net.URLClassLoader;
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.Collections;
022 import java.util.HashMap;
023 import java.util.List;
024 import java.util.Map;
025
026 import org.apache.commons.classscan.ClassPathElement;
027 import org.apache.commons.classscan.ResourceFile;
028 import org.apache.commons.classscan.spi.model.SpiClassPath;
029 import org.apache.commons.classscan.spi.model.SpiClassPathElement;
030 import org.apache.commons.classscan.spi.model.SpiMetaClassLoader;
031 import org.apache.commons.classscan.spi.model.SpiMetaRegistry;
032 import org.slf4j.Logger;
033 import org.slf4j.LoggerFactory;
034
035 public class UrlClassPath implements SpiClassPath {
036
037 private static final Logger logger = LoggerFactory.getLogger(UrlClassPath.class);
038
039 private final SpiMetaRegistry registry;
040 private final List<SpiClassPathElement> classPathElements;
041
042 public UrlClassPath(SpiMetaRegistry registry, URLClassLoader urlClassLoader) {
043 this.registry = registry;
044 classPathElements = Collections.unmodifiableList(getClassPathElements(registry, urlClassLoader.getURLs()));
045 }
046
047 static List<SpiClassPathElement> getClassPathElements(SpiMetaRegistry registry, URL[] urls) {
048 List<SpiClassPathElement> elements = new ArrayList<SpiClassPathElement>();
049 Map<String, URL> locations = new HashMap<String, URL>();
050 for(URL url : urls) {
051 String baseLocation= url.toExternalForm();
052 if( locations.containsKey(baseLocation) ) {
053 continue;
054 }
055 locations.put(baseLocation, url);
056
057 try {
058 SpiClassPathElement element= registry.createClassPathElement(url);
059 elements.add(element);
060 } catch (IOException e) {
061 logger.info("Problem with URL "+url, e);
062 }
063 }
064 return elements;
065 }
066
067 @Override
068 public List<? extends ClassPathElement> getClassPathElements() {
069 return classPathElements;
070 }
071
072 @Override
073 public SpiMetaClassLoader createMetaClassLoader(SpiMetaRegistry registry, ClassLoader classLoader) {
074 return new UrlMetaClassLoader(registry, classLoader);
075 }
076
077 @Override
078 public Map<ClassPathElement, ResourceFile> getResources(String fileName) {
079 Map<ClassPathElement, ResourceFile> resources = new HashMap<ClassPathElement, ResourceFile>();
080 Map<String,ClassPathElement> visited = new HashMap<String,ClassPathElement>();
081 searchElements(visited, resources, classPathElements, fileName);
082 return resources;
083 }
084
085 public void searchElements(Map<String,ClassPathElement> visited, Map<ClassPathElement, ResourceFile> resources, Collection<SpiClassPathElement> elements, String fileName) {
086 for(SpiClassPathElement element : elements) {
087 String location = element.getLocation();
088 if(visited.put(location, element)!=null) {
089 continue;
090 }
091
092 ResourceFile resource= element.getResource(fileName);
093 if(resource!=null) {
094 resources.put(element, resource);
095 }
096
097 Collection<SpiClassPathElement> additionalLocations = element.getAdditionalLocations(registry);
098 if(additionalLocations!=null) {
099 searchElements(visited, resources, additionalLocations, fileName);
100 }
101 }
102 }
103 }