diff options
Diffstat (limited to 'src/main/javassist/ClassPoolTail.java')
-rw-r--r-- | src/main/javassist/ClassPoolTail.java | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/src/main/javassist/ClassPoolTail.java b/src/main/javassist/ClassPoolTail.java new file mode 100644 index 00000000..1c6c7058 --- /dev/null +++ b/src/main/javassist/ClassPoolTail.java @@ -0,0 +1,307 @@ +/* + * This file is part of the Javassist toolkit. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * either http://www.mozilla.org/MPL/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Javassist. + * + * The Initial Developer of the Original Code is Shigeru Chiba. Portions + * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. + * All Rights Reserved. + * + * Contributor(s): + * + * The development of this software is supported in part by the PRESTO + * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + */ + +package javassist; + +import java.io.*; +import java.util.zip.*; + +final class ClassPathList { + ClassPathList next; + ClassPath path; + + ClassPathList(ClassPath p, ClassPathList n) { + next = n; + path = p; + } +} + + +final class SystemClassPath implements ClassPath { + Class thisClass; + + SystemClassPath() { + /* The value of thisClass was this.getClass() in early versions: + * + * thisClass = this.getClass(); + * + * However, this made openClassfile() not search all the system + * class paths if javassist.jar is put in jre/lib/ext/ + * (with JDK1.4). + */ + thisClass = java.lang.Object.class; + } + + public InputStream openClassfile(String classname) { + String jarname = "/" + classname.replace('.', '/') + ".class"; + return thisClass.getResourceAsStream(jarname); + } + + public String toString() { + return "*system class path*"; + } +} + + +final class DirClassPath implements ClassPath { + String directory; + + DirClassPath(String dirName) { + directory = dirName; + } + + public InputStream openClassfile(String classname) { + try { + char sep = File.separatorChar; + String filename = directory + sep + + classname.replace('.', sep) + ".class"; + return new FileInputStream(filename.toString()); + } + catch (FileNotFoundException e) {} + catch (SecurityException e) {} + return null; + } + + public String toString() { + return directory; + } +} + + +final class JarClassPath implements ClassPath { + ZipFile jarfile; + + JarClassPath(String pathname) throws NotFoundException { + try { + jarfile = new ZipFile(pathname); + return; + } + catch (ZipException e) {} + catch (IOException e) {} + throw new NotFoundException(pathname); + } + + public InputStream openClassfile(String classname) + throws NotFoundException + { + try { + String jarname = classname.replace('.', '/') + ".class"; + ZipEntry ze = jarfile.getEntry(jarname); + if (ze != null) + return jarfile.getInputStream(ze); + else + return null; // not found + } + catch (ZipException e) {} + catch (IOException e) {} + throw new NotFoundException("broken jar file?: " + + jarfile.getName()); + } + + public String toString() { + return jarfile.toString(); + } +} + +final class ClassPoolTail extends ClassPool { + protected ClassPathList pathList; + private Class thisClass; + + public ClassPoolTail() { + pathList = null; + thisClass = getClass(); + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("[class path: "); + ClassPathList list = pathList; + while (list != null) { + buf.append(list.path.toString()); + buf.append(File.pathSeparatorChar); + list = list.next; + } + + buf.append(']'); + return buf.toString(); + } + + public byte[] write(String classname) + throws NotFoundException, IOException + { + return readClassfile(classname); + } + + public void write(String classname, DataOutputStream out) + throws NotFoundException, CannotCompileException, IOException + { + byte[] b = write(classname); + out.write(b, 0, b.length); + } + + public CtClass get(String classname) throws NotFoundException { + throw new RuntimeException("fatal error"); + } + + public CtClass makeClass(String classname) { + throw new RuntimeException("fatal error"); + } + + void checkClassName(String classname) + throws NotFoundException + { + InputStream fin = openClassfile(classname); + try { + fin.close(); + } + catch (IOException e) { /* ignore */ } + } + + public synchronized void insertClassPath(ClassPath cp) { + pathList = new ClassPathList(cp, pathList); + } + + public synchronized void appendClassPath(ClassPath cp) { + ClassPathList tail = new ClassPathList(cp, null); + ClassPathList list = pathList; + if (list == null) + pathList = tail; + else { + while (list.next != null) + list = list.next; + + list.next = tail; + } + } + + public void appendSystemPath() { + appendClassPath(new SystemClassPath()); + } + + public void insertClassPath(String pathname) + throws NotFoundException + { + insertClassPath(makePathObject(pathname)); + } + + public void appendClassPath(String pathname) + throws NotFoundException + { + appendClassPath(makePathObject(pathname)); + } + + private static ClassPath makePathObject(String pathname) + throws NotFoundException + { + if (pathname.endsWith(".jar") || pathname.endsWith(".zip") + || pathname.endsWith(".JAR") || pathname.endsWith(".ZIP")) + return new JarClassPath(pathname); + else + return new DirClassPath(pathname); + } + + /** + * Obtains the contents of the class file for the class + * specified by <code>classname</code>. + * + * @param classname a fully-qualified class name + */ + byte[] readClassfile(String classname) + throws NotFoundException, IOException + { + InputStream fin = openClassfile(classname); + byte[] b = readStream(fin); + fin.close(); + return b; + } + + /** + * Opens the class file for the class specified by + * <code>classname</code>. + * + * @param classname a fully-qualified class name + */ + public InputStream openClassfile(String classname) + throws NotFoundException + { + ClassPathList list = pathList; + InputStream ins = null; + NotFoundException error = null; + while (list != null) { + try { + ins = list.path.openClassfile(classname); + } + catch (NotFoundException e) { + if (error == null) + error = e; + } + + if (ins == null) + list = list.next; + else + return ins; + } + + if (error != null) + throw error; + else + throw new NotFoundException(classname); + } + + /** + * Reads an input stream until it reaches the end. + * + * @return the contents of that input stream + */ + public static byte[] readStream(InputStream fin) throws IOException { + byte[][] bufs = new byte[8][]; + int bufsize = 4096; + + for (int i = 0; i < 8; ++i) { + bufs[i] = new byte[bufsize]; + int size = 0; + int len = 0; + do { + len = fin.read(bufs[i], size, bufsize - size); + if (len >= 0) + size += len; + else { + byte[] result = new byte[bufsize - 4096 + size]; + int s = 0; + for (int j = 0; j < i; ++j) { + System.arraycopy(bufs[j], 0, result, s, s + 4096); + s = s + s + 4096; + } + + System.arraycopy(bufs[i], 0, result, s, size); + return result; + } + } while (size < bufsize); + bufsize *= 2; + } + + throw new IOException("too much data"); + } +} |