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.xbean.finder; 018 019 import java.net.URL; 020 import java.net.MalformedURLException; 021 import java.util.Collection; 022 import java.util.List; 023 import java.util.ArrayList; 024 import java.util.Collections; 025 import java.util.Map; 026 import java.util.HashMap; 027 import java.util.Arrays; 028 import java.io.IOException; 029 import java.io.File; 030 031 /** 032 * @version $Rev$ $Date$ 033 */ 034 public class UrlSet { 035 036 private final Map<String,URL> urls; 037 038 public UrlSet(ClassLoader classLoader) throws IOException { 039 this(getUrls(classLoader)); 040 } 041 042 public UrlSet(URL... urls){ 043 this(Arrays.asList(urls)); 044 } 045 /** 046 * Ignores all URLs that are not "jar" or "file" 047 * @param urls 048 */ 049 public UrlSet(Collection<URL> urls){ 050 this.urls = new HashMap<String,URL>(); 051 for (URL location : urls) { 052 try { 053 // if (location.getProtocol().equals("file")) { 054 // try { 055 // // See if it's actually a jar 056 // URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/"); 057 // JarURLConnection juc = (JarURLConnection) jarUrl.openConnection(); 058 // juc.getJarFile(); 059 // location = jarUrl; 060 // } catch (IOException e) { 061 // } 062 // this.urls.put(location.toExternalForm(), location); 063 // } 064 this.urls.put(location.toExternalForm(), location); 065 } catch (Exception e) { 066 e.printStackTrace(); 067 } 068 } 069 } 070 071 private UrlSet(Map<String, URL> urls) { 072 this.urls = urls; 073 } 074 075 public UrlSet include(UrlSet urlSet){ 076 Map<String, URL> urls = new HashMap<String, URL>(this.urls); 077 urls.putAll(urlSet.urls); 078 return new UrlSet(urls); 079 } 080 081 public UrlSet exclude(UrlSet urlSet) { 082 Map<String, URL> urls = new HashMap<String, URL>(this.urls); 083 Map<String, URL> parentUrls = urlSet.urls; 084 for (String url : parentUrls.keySet()) { 085 urls.remove(url); 086 } 087 return new UrlSet(urls); 088 } 089 090 public UrlSet exclude(ClassLoader parent) throws IOException { 091 return exclude(new UrlSet(parent)); 092 } 093 094 public UrlSet exclude(File file) throws MalformedURLException { 095 return exclude(relative(file)); 096 } 097 098 public UrlSet exclude(String pattern) throws MalformedURLException { 099 return exclude(matching(pattern)); 100 } 101 102 /** 103 * Calls excludePaths(System.getProperty("java.ext.dirs")) 104 * @return 105 * @throws MalformedURLException 106 */ 107 public UrlSet excludeJavaExtDirs() throws MalformedURLException { 108 return excludePaths(System.getProperty("java.ext.dirs", "")); 109 } 110 111 /** 112 * Calls excludePaths(System.getProperty("java.endorsed.dirs")) 113 * 114 * @return 115 * @throws MalformedURLException 116 */ 117 public UrlSet excludeJavaEndorsedDirs() throws MalformedURLException { 118 return excludePaths(System.getProperty("java.endorsed.dirs", "")); 119 } 120 121 public UrlSet excludeJavaHome() throws MalformedURLException { 122 String path = System.getProperty("java.home"); 123 124 File java = new File(path); 125 126 if (path.matches("/System/Library/Frameworks/JavaVM.framework/Versions/[^/]+/Home")){ 127 java = java.getParentFile(); 128 } 129 130 return exclude(java); 131 } 132 133 public UrlSet excludePaths(String pathString) throws MalformedURLException { 134 String[] paths = pathString.split(File.pathSeparator); 135 UrlSet urlSet = this; 136 for (String path : paths) { 137 File file = new File(path); 138 urlSet = urlSet.exclude(file); 139 } 140 return urlSet; 141 } 142 143 public UrlSet matching(String pattern) { 144 Map<String, URL> urls = new HashMap<String, URL>(); 145 for (Map.Entry<String, URL> entry : this.urls.entrySet()) { 146 String url = entry.getKey(); 147 if (url.matches(pattern)){ 148 urls.put(url, entry.getValue()); 149 } 150 } 151 return new UrlSet(urls); 152 } 153 154 public UrlSet relative(File file) throws MalformedURLException { 155 String urlPath = file.toURL().toExternalForm(); 156 Map<String, URL> urls = new HashMap<String, URL>(); 157 for (Map.Entry<String, URL> entry : this.urls.entrySet()) { 158 String url = entry.getKey(); 159 if (url.startsWith(urlPath) || url.startsWith("jar:"+urlPath)){ 160 urls.put(url, entry.getValue()); 161 } 162 } 163 return new UrlSet(urls); 164 } 165 166 public List<URL> getUrls() { 167 return new ArrayList<URL>(urls.values()); 168 } 169 170 private static List<URL> getUrls(ClassLoader classLoader) throws IOException { 171 List<URL> list = new ArrayList<URL>(); 172 ArrayList<URL> urls = Collections.list(classLoader.getResources("META-INF")); 173 for (URL url : urls) { 174 String externalForm = url.toExternalForm(); 175 int i = externalForm.lastIndexOf("META-INF"); 176 externalForm = externalForm.substring(0, i); 177 url = new URL(externalForm); 178 list.add(url); 179 } 180 list.addAll(Collections.list(classLoader.getResources(""))); 181 return list; 182 } 183 }