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 }