blob: 38adc4947477cd1a445e9c158041ec52f783bc69 [file] [log] [blame]
/*
* 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.river.container;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
/**
* Extends URLClassLoader to allow alteration of the codebase annotation that
* will be extracted from the class loader. Essentially, allows you to use
* one source for the actual classpath, and then have a marshalled object
* return an arbitrary codebase.
* @author trasukg
*/
public class SettableCodebaseClassLoader extends URLClassLoader {
/** Stores the codebase that will be returned as the codebase annotation.
*
*/
private URL codebaseURLs[] = new URL[0];
/**
* Construct using a list of urls and the parent classloader.
* @param urlList A list of URLs (which may point to directories or
* jar files) to form the classpath.
* @param extensionClassloader Class loader to use as parent of this
* class loader.
*/
SettableCodebaseClassLoader(URL urlList[], ClassLoader extensionClassloader) {
super(urlList, extensionClassloader);
}
/**
* Get the list of URLs that are used for the codebase annotation.
* Note that this list is not the actual classpath (that is in the
* superclass). The codebase URLs are imposed to match whatever the Jini
* service wants to expose as its codebase annotation.
* @return
*/
@Override
public URL[] getURLs() {
return codebaseURLs;
}
/** Add a URL to this classpath.
*/
@Override
public void addURL(URL url) {
URL[] currentURLS = super.getURLs();
for (int i = 0; i < currentURLS.length; i++) {
if (url.equals(currentURLS[i])) {
return;
}
}
super.addURL(url);
}
/**
* Set the codebase URLs to an arbitrary list of URLs. These URLs form the
* codebase annotation for classes loaded through this classloader.
* For the sake of general paranoia, sets the codebase to a copy of the
* provided array.
* @param codebase
*/
public void setCodebase(URL[] codebase) {
if (codebase == null || codebase.length==0) {
codebaseURLs = new URL[]{};
return;
}
codebaseURLs = new URL[codebase.length];
System.arraycopy(codebase, 0, codebaseURLs, 0, codebase.length);
}
static SettableCodebaseClassLoader createLoader(ClassLoader parent,
File commonDirectory)
throws MalformedURLException, IOException {
List urlList = new ArrayList();
if (!commonDirectory.isDirectory()) {
/* There's no common directory, so we'll just use an empty url list
to create the classloader.
*/
} else {
/* Create based around the unpacked directory.
* TODO: Maybe later; seems to me this would make a decent idea,
* but the Surrogate spec specifically disallows the use of the
* codebase attribute, and seems to require that all classes be
* in the root of the surrogate package jar file.
urlList.add(commonDirectory.toURI().toURL());
/* Add all jar files in the directory. * /
FileFilter filter = new JarFilter();
File[] jars = commonDirectory.listFiles(filter);
for (int i = 0; i < jars.length; i++) {
urlList.add(jars[i].toURI().toURL());
}
*/
}
URL[] urlArray = new URL[urlList.size()];
for (int i = 0; i < urlArray.length; i++) {
urlArray[i] = (URL) urlList.get(i);
}
SettableCodebaseClassLoader loader = null;
loader = new SettableCodebaseClassLoader(urlArray, parent);
return loader;
}
@Override
public String toString() {
StringBuffer listString = new StringBuffer();
listString.append(getClass().getName() + " [");
URL[] urlArray = super.getURLs();
for (int i = 0; i < urlArray.length; i++) {
listString.append(" ");
listString.append(urlArray[i]);
}
listString.append("], codebase [");
urlArray = getURLs();
for (int i = 0; i < urlArray.length; i++) {
listString.append(" ");
listString.append(urlArray[i]);
}
listString.append("]");
return listString.toString();
}
}