001: /**
002: * InstantJ
003: *
004: * Copyright (C) 2002 Nils Meier
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */package instantj.compile.sun;
017:
018: import instantj.compile.CompiledClass;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.File;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.util.Collection;
025: import java.util.HashSet;
026: import java.util.Map;
027: import java.util.Set;
028:
029: /**
030: * A classloader-fed ClassPath - we need this to hand byte-code to
031: * the javac environment for classes that are not in the classpath
032: * (e.g. from a servlet container)
033: */
034: /*package*/class ContextClassPath extends sun.tools.java.ClassPath {
035:
036: /** the context classloader */
037: private ClassLoader cl;
038:
039: /** other compiled classes */
040: private Map deps;
041:
042: /** used dependencies */
043: private Set usedDeps = new HashSet();
044:
045: /**
046: * Constructor
047: * @param cl the classloader to use for byte-code lookups
048: * @param deps dependencies to other compiled classes
049: */
050: /*package*/ContextClassPath(ClassLoader cl, Map deps) {
051: // init
052: super (System.getProperty("java.class.path")
053: + File.pathSeparatorChar
054: + System.getProperty("sun.boot.class.path"));
055: this .cl = cl;
056: this .deps = deps;
057: // done
058: }
059:
060: /**
061: * Returns used dependencies
062: */
063: /*package*/Collection getUsedDeps() {
064: return usedDeps;
065: }
066:
067: /**
068: * Accessor - get a file
069: */
070: public sun.tools.java.ClassFile getFile(String file) {
071:
072: // Try to load it as a resource from context's classloader
073: String s = file.replace('\\', '/');
074: if (cl.getResource(s) != null) {
075: return new ClasspathClassFile(s);
076: }
077:
078: // Check if the dependencies can help
079: if (deps != null && s.endsWith(".class")) {
080: s = s.substring(0, s.lastIndexOf(".class"));
081: CompiledClass cc = (CompiledClass) deps.get(s);
082: if (cc != null)
083: return new DependencyClassFile(s, cc);
084: }
085:
086: // super might help
087: return super .getFile(file);
088: }
089:
090: /**
091: * A ClassFile that is fed from one of the compiled classes in
092: * the dependencies
093: */
094: protected class DependencyClassFile extends
095: sun.tools.java.ClassFile {
096:
097: /** the compiled class representing */
098: private CompiledClass cc;
099:
100: /**
101: * Constructor
102: */
103: protected DependencyClassFile(String file, CompiledClass cc) {
104: super (new File(file));
105: this .cc = cc;
106: usedDeps.add(cc);
107: }
108:
109: public boolean isZipped() {
110: return false;
111: }
112:
113: public InputStream getInputStream() throws IOException {
114: return new ByteArrayInputStream(cc.getByteCode());
115: }
116:
117: public boolean exists() {
118: return true;
119: }
120:
121: public boolean isDirectory() {
122: return false;
123: }
124:
125: public long lastModified() {
126: return 0;
127: }
128:
129: } //LibraryClassFile
130:
131: /**
132: * A ClassFile that is fed from a classloader - we simply
133: * override getInputStream() which will read the byte-code
134: * as a resource from a classloader
135: */
136: protected class ClasspathClassFile extends sun.tools.java.ClassFile {
137:
138: /** the file we're representing */
139: private String file;
140:
141: /**
142: * Constructor
143: */
144: protected ClasspathClassFile(String file) {
145: super (new File(file));
146: this .file = file;
147: }
148:
149: public boolean isZipped() {
150: return false;
151: }
152:
153: public InputStream getInputStream() throws IOException {
154: return cl.getResourceAsStream(file);
155: }
156:
157: public boolean exists() {
158: return true;
159: }
160:
161: public boolean isDirectory() {
162: return false;
163: }
164:
165: public long lastModified() {
166: return 0;
167: }
168:
169: } //ClasspathClassFile
170:
171: } //ContextClassPath
|