blob: 091e022a3ecb795f7c3dbf603f5549cdfda2399e [file] [log] [blame]
/* *******************************************************************
* Copyright (c) 2003 Contributors.
* 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:
* Isberg initial implementation
* ******************************************************************/
package org.aspectj.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Load classes as File from File[] dirs or URL[] jars.
*/
public class UtilClassLoader extends URLClassLoader {
/** seek classes in dirs first */
List<File> dirs;
/** save URL[] only for toString */
private URL[] urlsForDebugString;
public UtilClassLoader(URL[] urls, File[] dirs) {
super(urls);
LangUtil.throwIaxIfNotAssignable(dirs, File.class, "dirs");
this.urlsForDebugString = urls;
ArrayList<File> dcopy = new ArrayList<File>();
if (!LangUtil.isEmpty(dirs)) {
dcopy.addAll(Arrays.asList(dirs));
}
this.dirs = Collections.unmodifiableList(dcopy);
}
public URL getResource(String name) {
return ClassLoader.getSystemResource(name);
}
public InputStream getResourceAsStream(String name) {
return ClassLoader.getSystemResourceAsStream(name);
}
public synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// search the cache, our dirs (if maybe test),
// the system, the superclass (URL[]),
// and our dirs again (if not maybe test)
ClassNotFoundException thrown = null;
Class<?> result = findLoadedClass(name);
if (null != result) {
resolve = false;
} else {
try {
result = findSystemClass(name);
} catch (ClassNotFoundException e) {
thrown = e;
}
}
if (null == result) {
try {
result = super.loadClass(name, resolve);
} catch (ClassNotFoundException e) {
thrown = e;
}
if (null != result) { // resolved by superclass
return result;
}
}
if (null == result) {
byte[] data = readClass(name);
if (data != null) {
result = defineClass(name, data, 0, data.length);
} // handle ClassFormatError?
}
if (null == result) {
throw (null != thrown ? thrown : new ClassNotFoundException(name));
}
if (resolve) {
resolveClass(result);
}
return result;
}
/** @return null if class not found or byte[] of class otherwise */
private byte[] readClass(String className) throws ClassNotFoundException {
final String fileName = className.replace('.', '/')+".class";
for (Iterator<File> iter = dirs.iterator(); iter.hasNext();) {
File file = new File(iter.next(), fileName);
if (file.canRead()) {
return getClassData(file);
}
}
return null;
}
private byte[] getClassData(File f) {
try {
FileInputStream stream= new FileInputStream(f);
ByteArrayOutputStream out= new ByteArrayOutputStream(1000);
byte[] b= new byte[4096];
int n;
while ((n= stream.read(b)) != -1) {
out.write(b, 0, n);
}
stream.close();
out.close();
return out.toByteArray();
} catch (IOException e) {
}
return null;
}
/** @return String with debug info: urls and classes used */
public String toString() {
return "UtilClassLoader(urls="
+ Arrays.asList(urlsForDebugString)
+ ", dirs="
+ dirs
+ ")";
}
}