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