aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/ClassPoolTail.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/ClassPoolTail.java')
-rw-r--r--src/main/javassist/ClassPoolTail.java307
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");
+ }
+}