001: /**
002: * InstantJ
003: *
004: * Copyright (C) 2002 Nils Meier
005: * Additional changes (C) 2002 Andy Thomas
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: */package instantj.compile.pizza;
018:
019: import instantj.compile.CompilationFailedException;
020: import instantj.compile.CompiledClass;
021:
022: import java.io.ByteArrayInputStream;
023: import java.io.InputStream;
024: import java.util.Map;
025:
026: import net.sf.pizzacompiler.compiler.ClassReader;
027:
028: /**
029: * A patched ClassReader that reads resouces from
030: * classpath (e.g. class file). This allows to compile
031: * classes that reference class-bytes in the current
032: * context-classloader but not available through the
033: * global classpath
034: */
035: /*package*/class ContextClassReader extends ClassReader {
036:
037: /** the context classloader */
038: private ClassLoader cl;
039:
040: /** the library */
041: private Map lib;
042:
043: /**
044: * Constructor
045: */
046: /*package*/ContextClassReader(ClassLoader classloader, Map library)
047: throws CompilationFailedException {
048:
049: // remember
050: cl = classloader;
051: lib = library;
052:
053: // 20030305 o.k. at this point I don't understand how class-bytes that
054: // are not in the classpath can be fed to Pizza. find() seems to be
055: // called for well known java.lang. classes only and classes that I want
056: // to load dynamically from classloader/library don't get triggered.
057: // Tried to play with loadClass() but am no optimistic :(
058: // Won't support library at this point ...
059: if (library != null && !library.isEmpty())
060: throw new CompilationFailedException(
061: "Pizza integration doesn't support library");
062:
063: // // publish libary names
064: // try {
065: // Iterator it = library.getAll().iterator();
066: // while (it.hasNext()) {
067: // CompiledClass cc = (CompiledClass)it.next();
068: // loadClass(Name.fromString(cc.getName()));
069: // }
070: // } catch (IOException e) {
071: // e.printStackTrace();
072: // }
073:
074: // done
075: }
076:
077: // /**
078: // * @see net.sf.pizzacompiler.compiler.ClassReader#loadClass(net.sf.pizzacompiler.compiler.Name)
079: // */
080: // public ClassSymbol loadClass(Name arg0) throws IOException {
081: // System.out.println("Load "+arg0);
082: // return super.loadClass(arg0);
083: // }
084:
085: /**
086: * Override to find class-bytes in local classpath if available
087: * @see instantj.compile.pizza.PizzaSourceCompiler#find(java.lang.String)
088: */
089: protected InputStream find(String name) {
090:
091: // patch path
092: String s = name.replace('\\', '/');
093:
094: // try to load from classloader
095: InputStream result = cl.getResourceAsStream(s);
096: if (result != null)
097: return result;
098:
099: // Check if the library is sufficient
100: if (s.endsWith(".class")) {
101: s = s.substring(0, s.lastIndexOf(".class"));
102: CompiledClass cc = (CompiledClass) lib.get(s);
103: if (cc != null)
104: return new ByteArrayInputStream(cc.getByteCode());
105: }
106:
107: // super might do
108: return super .find(name);
109: }
110:
111: } //InstantClassReader
|