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.xbean.finder; 018 019import org.apache.xbean.finder.filter.Filter; 020 021import java.net.URL; 022import java.net.MalformedURLException; 023import java.net.URLClassLoader; 024import java.util.Collection; 025import java.util.Iterator; 026import java.util.List; 027import java.util.ArrayList; 028import java.util.Collections; 029import java.util.Map; 030import java.util.HashMap; 031import java.util.Arrays; 032import java.io.IOException; 033import java.io.File; 034 035import static org.apache.xbean.finder.filter.Filters.invert; 036import static org.apache.xbean.finder.filter.Filters.patterns; 037 038/** 039 * @version $Rev$ $Date$ 040 */ 041public class UrlSet implements Iterable<URL> { 042 043 private final Map<String,URL> urls; 044 045 public UrlSet(ClassLoader classLoader) throws IOException { 046 this(ClassLoaders.findUrls(classLoader)); 047 } 048 049 public UrlSet(URL... urls){ 050 this(Arrays.asList(urls)); 051 } 052 /** 053 * Ignores all URLs that are not "jar" or "file" 054 * @param urls 055 */ 056 public UrlSet(Collection<URL> urls){ 057 this.urls = new HashMap<String,URL>(); 058 for (URL location : urls) { 059 try { 060// if (location.getProtocol().equals("file")) { 061// try { 062// // See if it's actually a jar 063// URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/"); 064// JarURLConnection juc = (JarURLConnection) jarUrl.openConnection(); 065// juc.getJarFile(); 066// location = jarUrl; 067// } catch (IOException e) { 068// } 069// this.urls.put(location.toExternalForm(), location); 070// } 071 this.urls.put(location.toExternalForm(), location); 072 } catch (Exception e) { 073 e.printStackTrace(); 074 } 075 } 076 } 077 078 private UrlSet(Map<String, URL> urls) { 079 this.urls = urls; 080 } 081 082 public UrlSet include(UrlSet urlSet){ 083 Map<String, URL> urls = new HashMap<String, URL>(this.urls); 084 urls.putAll(urlSet.urls); 085 return new UrlSet(urls); 086 } 087 088 089 public UrlSet include(URL url){ 090 Map<String, URL> urls = new HashMap<String, URL>(this.urls); 091 urls.put(url.toExternalForm(), url); 092 return new UrlSet(urls); 093 } 094 095 public UrlSet exclude(UrlSet urlSet) { 096 Map<String, URL> urls = new HashMap<String, URL>(this.urls); 097 Map<String, URL> parentUrls = urlSet.urls; 098 for (String url : parentUrls.keySet()) { 099 urls.remove(url); 100 } 101 return new UrlSet(urls); 102 } 103 104 public UrlSet exclude(URL url) { 105 Map<String, URL> urls = new HashMap<String, URL>(this.urls); 106 urls.remove(url.toExternalForm()); 107 return new UrlSet(urls); 108 } 109 110 public UrlSet exclude(ClassLoader parent) throws IOException { 111 return exclude(new UrlSet(parent)); 112 } 113 114 public UrlSet exclude(File file) throws MalformedURLException { 115 return exclude(relative(file)); 116 } 117 118 public UrlSet exclude(String pattern) throws MalformedURLException { 119 return filter(invert(patterns(pattern))); 120 } 121 122 /** 123 * Calls excludePaths(System.getProperty("java.ext.dirs")) 124 * @return 125 * @throws MalformedURLException 126 */ 127 public UrlSet excludeJavaExtDirs() throws MalformedURLException { 128 String extDirs = System.getProperty("java.ext.dirs"); 129 return extDirs == null ? this : excludePaths(extDirs); 130 } 131 132 /** 133 * Calls excludePaths(System.getProperty("java.endorsed.dirs")) 134 * 135 * @return 136 * @throws MalformedURLException 137 */ 138 public UrlSet excludeJavaEndorsedDirs() throws MalformedURLException { 139 String endorsedDirs = System.getProperty("java.endorsed.dirs"); 140 return endorsedDirs == null ? this : excludePaths(endorsedDirs); 141 } 142 143 public UrlSet excludeJavaHome() throws MalformedURLException { 144 String path = System.getProperty("java.home"); 145 146 File java = new File(path); 147 148 if (isOsx() && path.endsWith("/Contents/Home")) { 149 java = java.getParentFile().getParentFile(); 150 } 151 152 return exclude(java); 153 } 154 155 public UrlSet excludeJvm() throws MalformedURLException { 156 UrlSet urls = excludeJavaHome().excludeJavaExtDirs().excludeJavaEndorsedDirs(); 157 if (isOsx()) { 158 urls = urls.exclude(new File("/System/Library/Java/Support")); 159 } 160 return urls; 161 } 162 163 public UrlSet excludePaths(String pathString) throws MalformedURLException { 164 String[] paths = pathString.split(File.pathSeparator); 165 UrlSet urlSet = this; 166 for (String path : paths) { 167 File file = new File(path); 168 urlSet = urlSet.exclude(file); 169 } 170 return urlSet; 171 } 172 173 public UrlSet filter(Filter filter) { 174 Map<String, URL> urls = new HashMap<String, URL>(); 175 for (Map.Entry<String, URL> entry : this.urls.entrySet()) { 176 String url = entry.getKey(); 177 if (filter.accept(url)){ 178 urls.put(url, entry.getValue()); 179 } 180 } 181 return new UrlSet(urls); 182 } 183 184 public UrlSet matching(String pattern) { 185 return filter(patterns(pattern)); 186 } 187 188 public UrlSet relative(File file) throws MalformedURLException { 189 String urlPath = file.toURI().toURL().toExternalForm(); 190 Map<String, URL> urls = new HashMap<String, URL>(); 191 for (Map.Entry<String, URL> entry : this.urls.entrySet()) { 192 String url = entry.getKey(); 193 if (url.startsWith(urlPath) || url.startsWith("jar:"+urlPath)){ 194 urls.put(url, entry.getValue()); 195 } 196 } 197 return new UrlSet(urls); 198 } 199 200 public List<URL> getUrls() { 201 return new ArrayList<URL>(urls.values()); 202 } 203 204 public int size() { 205 return urls.size(); 206 } 207 208 public Iterator<URL> iterator() { 209 return getUrls().iterator(); 210 } 211 212 @Override 213 public String toString() { 214 return super.toString() + "[" + urls.size() + "]"; 215 } 216 217 public boolean isOsx() { 218 return "Mac OS X".equals(System.getProperty("os.name")); 219 } 220}