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 }