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 *
115 * @return
116 * @throws MalformedURLException
117 */
118 public UrlSet excludeJavaEndorsedDirs() throws MalformedURLException {
119 return excludePaths(System.getProperty("java.endorsed.dirs", ""));
120 }
121
122 public UrlSet excludeJavaHome() throws MalformedURLException {
123 String path = System.getProperty("java.home");
124 return exclude(new File(path));
125 }
126
127 public UrlSet excludePaths(String pathString) throws MalformedURLException {
128 String[] paths = pathString.split(File.pathSeparator);
129 UrlSet urlSet = this;
130 for (String path : paths) {
131 File file = new File(path);
132 urlSet = urlSet.exclude(file);
133 }
134 return urlSet;
135 }
136
137 public UrlSet matching(String pattern) {
138 Map<String, URL> urls = new HashMap<String, URL>();
139 for (Map.Entry<String, URL> entry : this.urls.entrySet()) {
140 String url = entry.getKey();
141 if (url.matches(pattern)){
142 urls.put(url, entry.getValue());
143 }
144 }
145 return new UrlSet(urls);
146 }
147
148 public UrlSet relative(File file) throws MalformedURLException {
149 String urlPath = file.toURL().toExternalForm();
150 Map<String, URL> urls = new HashMap<String, URL>();
151 for (Map.Entry<String, URL> entry : this.urls.entrySet()) {
152 String url = entry.getKey();
153 if (url.startsWith(urlPath) || url.startsWith("jar:"+urlPath)){
154 urls.put(url, entry.getValue());
155 }
156 }
157 return new UrlSet(urls);
158 }
159
160 public List<URL> getUrls() {
161 return new ArrayList<URL>(urls.values());
162 }
163
164 private static List<URL> getUrls(ClassLoader classLoader) throws IOException {
165 List<URL> list = new ArrayList<URL>();
166 ArrayList<URL> urls = Collections.list(classLoader.getResources("META-INF"));
167 for (URL url : urls) {
168 String externalForm = url.toExternalForm();
169 int i = externalForm.lastIndexOf("META-INF");
170 externalForm = externalForm.substring(0, i);
171 url = new URL(externalForm);
172 list.add(url);
173 }
174 list.addAll(Collections.list(classLoader.getResources("")));
175 return list;
176 }
177 }