/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomee.loader; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.tomee.loader.filter.Filter; import static org.apache.tomee.loader.filter.Filters.invert; import static org.apache.tomee.loader.filter.Filters.patterns; /** * @version $Rev$ $Date$ */ public class UrlSet implements Iterable<URL> { private final Map<String,URL> urls; public UrlSet(final ClassLoader classLoader) throws IOException { this(getUrls(classLoader)); } public UrlSet(final URL... urls){ this(Arrays.asList(urls)); } /** * Ignores all URLs that are not "jar" or "file" * @param urls */ public UrlSet(final Collection<URL> urls){ this.urls = new HashMap<String,URL>(); for (final URL location : urls) { try { // if (location.getProtocol().equals("file")) { // try { // // See if it's actually a jar // URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/"); // JarURLConnection juc = (JarURLConnection) jarUrl.openConnection(); // juc.getJarFile(); // location = jarUrl; // } catch (IOException e) { // } // this.urls.put(location.toExternalForm(), location); // } this.urls.put(location.toExternalForm(), location); } catch (final Exception e) { e.printStackTrace(); } } } private UrlSet(final Map<String, URL> urls) { this.urls = urls; } public UrlSet include(final UrlSet urlSet){ final Map<String, URL> urls = new HashMap<String, URL>(this.urls); urls.putAll(urlSet.urls); return new UrlSet(urls); } public UrlSet include(final URL url){ final Map<String, URL> urls = new HashMap<String, URL>(this.urls); urls.put(url.toExternalForm(), url); return new UrlSet(urls); } public UrlSet exclude(final UrlSet urlSet) { final Map<String, URL> urls = new HashMap<String, URL>(this.urls); final Map<String, URL> parentUrls = urlSet.urls; for (final String url : parentUrls.keySet()) { urls.remove(url); } return new UrlSet(urls); } public UrlSet exclude(final URL url) { final Map<String, URL> urls = new HashMap<String, URL>(this.urls); urls.remove(url.toExternalForm()); return new UrlSet(urls); } public UrlSet exclude(final ClassLoader parent) throws IOException { return exclude(new UrlSet(parent)); } public UrlSet exclude(final File file) throws MalformedURLException { return exclude(relative(file)); } public UrlSet exclude(final String pattern) throws MalformedURLException { return filter(invert(patterns(pattern))); } /** * Calls excludePaths(System.getProperty("java.ext.dirs")) * @return * @throws MalformedURLException */ public UrlSet excludeJavaExtDirs() throws MalformedURLException { final String extDirs = System.getProperty("java.ext.dirs"); return extDirs == null ? this : excludePaths(extDirs); } /** * Calls excludePaths(System.getProperty("java.endorsed.dirs")) * * @return * @throws MalformedURLException */ public UrlSet excludeJavaEndorsedDirs() throws MalformedURLException { final String endorsedDirs = System.getProperty("java.endorsed.dirs"); return endorsedDirs == null ? this : excludePaths(endorsedDirs); } public UrlSet excludeJavaHome() throws MalformedURLException { final String path = System.getProperty("java.home"); File java = new File(path); if (path.matches("/System/Library/Frameworks/JavaVM.framework/Versions/[^/]+/Home")){ java = java.getParentFile(); } return exclude(java); } public UrlSet excludePaths(final String pathString) throws MalformedURLException { final String[] paths = pathString.split(File.pathSeparator); UrlSet urlSet = this; for (final String path : paths) { final File file = new File(path); urlSet = urlSet.exclude(file); } return urlSet; } public UrlSet filter(final Filter filter) { final Map<String, URL> urls = new HashMap<String, URL>(); for (final Map.Entry<String, URL> entry : this.urls.entrySet()) { final String url = entry.getKey(); if (filter.accept(url)){ urls.put(url, entry.getValue()); } } return new UrlSet(urls); } public UrlSet matching(final String pattern) { return filter(patterns(pattern)); } public UrlSet relative(final File file) throws MalformedURLException { final String urlPath = file.toURI().toURL().toExternalForm(); final Map<String, URL> urls = new HashMap<String, URL>(); for (final Map.Entry<String, URL> entry : this.urls.entrySet()) { final String url = entry.getKey(); if (url.startsWith(urlPath) || url.startsWith("jar:"+urlPath)){ urls.put(url, entry.getValue()); } } return new UrlSet(urls); } public List<URL> getUrls() { return new ArrayList<URL>(urls.values()); } public int size() { return urls.size(); } public Iterator<URL> iterator() { return getUrls().iterator(); } private static List<URL> getUrls(final ClassLoader classLoader) throws IOException { final List<URL> list = new ArrayList<URL>(); final ArrayList<URL> urls = Collections.list(classLoader.getResources("META-INF")); for (URL url : urls) { String externalForm = url.toExternalForm(); final int i = externalForm.lastIndexOf("META-INF"); externalForm = externalForm.substring(0, i); url = new URL(externalForm); list.add(url); } list.addAll(Collections.list(classLoader.getResources(""))); return list; } @Override public String toString() { return super.toString() + "[" + urls.size() + "]"; } }