blob: 06a1dc20bee7bda7cd7820ea5362e3bf34a4d3c0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Tromey (tromey@redhat.com) - patch for bug 40972
*******************************************************************************/
package org.eclipse.ant.internal.core;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
public class AntClassLoader extends URLClassLoader {
private static final String ANT_PACKAGES_PREFIX = "org.apache.tools"; //$NON-NLS-1$
private static final String ANT_URL_PREFIX = "org/apache/tools"; //$NON-NLS-1$
private boolean fAllowPluginLoading = false;
protected ClassLoader[] fPluginLoaders;
private ClassLoader fContextClassloader = null;
public AntClassLoader(URL[] urls, ClassLoader[] pluginLoaders) {
super(urls, ClassLoader.getSystemClassLoader());
fPluginLoaders = pluginLoaders;
}
/*
* @see java.net.URLClassLoader#findClass(java.lang.String)
*/
protected Class findClass(String name) throws ClassNotFoundException {
Class result = null;
//check whether to load the Apache Ant classes from the plug-in class loaders
//or to only load from the URLs specified from the Ant runtime classpath preferences setting
if (fAllowPluginLoading || !(name.startsWith(ANT_PACKAGES_PREFIX))) {
result = loadClassPlugins(name);
}
if (result != null) {
return result;
}
return super.findClass(name);
}
protected Class loadClassPlugins(String name) {
//remove this class loader as the context class loader
//when loading classes from plug-ins...see bug 94471
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
if (fContextClassloader != null) {
Thread.currentThread().setContextClassLoader(fContextClassloader);
}
try {
Class result = null;
if (fPluginLoaders != null) {
for (int i = 0; (i < fPluginLoaders.length) && (result == null); i++) {
try {
result = fPluginLoaders[i].loadClass(name);
} catch (ClassNotFoundException e) {
// Ignore exception now. If necessary we'll throw
// a ClassNotFoundException in loadClass(String)
}
}
}
return result;
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}
/*
* @see java.net.URLClassLoader#findResource(java.lang.String)
*/
public URL findResource(String name) {
if (fAllowPluginLoading || !(name.startsWith(ANT_URL_PREFIX))) {
URL result = findResourcePlugins(name);
if (result != null) {
return result;
}
}
return super.findResource(name);
}
private URL findResourcePlugins(String name) {
//remove this class loader as the context class loader
//when loading resources from plug-ins...see bug 94471
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
if (fContextClassloader != null) {
Thread.currentThread().setContextClassLoader(fContextClassloader);
}
try {
URL result = null;
if (fPluginLoaders != null) {
for (int i = 0; i < fPluginLoaders.length; i++) {
result = fPluginLoaders[i].getResource(name);
if (result != null) {
return result;
}
}
}
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
return null;
}
/*
* @see java.net.URLClassLoader#findResources(java.lang.String)
*/
public Enumeration findResources(String name) throws IOException {
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
if (fContextClassloader != null) {
Thread.currentThread().setContextClassLoader(fContextClassloader);
}
List all = new ArrayList();
try {
if (fAllowPluginLoading || !(name.startsWith(ANT_URL_PREFIX) || name.startsWith(ANT_URL_PREFIX, 1))) {
if (fPluginLoaders != null) {
Enumeration result = null;
for (int i = 0; i < fPluginLoaders.length; i++) {
result = fPluginLoaders[i].getResources(name);
while (result.hasMoreElements()) {
all.add(result.nextElement());
}
}
}
}
Enumeration superResources = super.findResources(name);
if (all.isEmpty()) {
return superResources;
}
while (superResources.hasMoreElements()) {
all.add(superResources.nextElement());
}
return Collections.enumeration(all);
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}
/**
* Sets whether this class loader will allow Apache Ant classes or resources to be found or
* loaded from its set of plug-in class loaders.
*
* @param allowLoading whether or not to allow the plug-in class loaders
* to load the Apache Ant classes or resources
*/
public void allowPluginClassLoadersToLoadAnt(boolean allowLoading) {
fAllowPluginLoading = allowLoading;
}
public void setPluginContextClassloader(ClassLoader classLoader) {
fContextClassloader = classLoader;
}
}