/* *******************************************************************
 * 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.
/** * Load classes as File from File[] dirs or URL[] jars. */
public class UtilClassLoader extends URLClassLoader {
seek classes in dirs first
/** seek classes in dirs first */
List<File> dirs;
save URL[] only for toString
/** 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; }
Returns:null if class not found or byte[] of class otherwise
/** @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; }
Returns:String with debug info: urls and classes used
/** @return String with debug info: urls and classes used */
public String toString() { return "UtilClassLoader(urls=" + Arrays.asList(urlsForDebugString) + ", dirs=" + dirs + ")"; } }