001: // Copyright (c) Corporation for National Research Initiatives
002: // Copyright 2000 Samuele Pedroni
003:
004: package org.python.core;
005:
006: import java.io.BufferedInputStream;
007: import java.io.File;
008: import java.io.FileInputStream;
009: import java.io.FileNotFoundException;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.util.StringTokenizer;
013: import java.util.zip.ZipEntry;
014:
015: public class SyspathJavaLoader extends ClassLoader {
016:
017: private static final char SLASH_CHAR = '/';
018:
019: public InputStream getResourceAsStream(String res) {
020: Py.writeDebug("resource", "trying resource: " + res);
021: ClassLoader classLoader = Py.getSystemState().getClassLoader();
022: if (classLoader != null) {
023: return classLoader.getResourceAsStream(res);
024: }
025:
026: classLoader = this .getClass().getClassLoader();
027:
028: InputStream ret;
029:
030: if (classLoader != null) {
031: ret = classLoader.getResourceAsStream(res);
032: } else {
033: ret = ClassLoader.getSystemResourceAsStream(res);
034: }
035: if (ret != null) {
036: return ret;
037: }
038:
039: if (res.charAt(0) == SLASH_CHAR) {
040: res = res.substring(1);
041: }
042: String entryRes = res;
043: if (File.separatorChar != SLASH_CHAR) {
044: res = res.replace(SLASH_CHAR, File.separatorChar);
045: entryRes = entryRes.replace(File.separatorChar, SLASH_CHAR);
046: }
047:
048: PyList path = Py.getSystemState().path;
049: for (int i = 0; i < path.__len__(); i++) {
050: PyObject entry = path.__getitem__(i);
051: if (entry instanceof SyspathArchive) {
052: SyspathArchive archive = (SyspathArchive) entry;
053: ZipEntry ze = archive.getEntry(entryRes);
054: if (ze != null) {
055: try {
056: return archive.getInputStream(ze);
057: } catch (IOException e) {
058: ;
059: }
060: }
061: continue;
062: }
063: String dir = entry.__str__().toString();
064: if (dir.length() == 0) {
065: dir = null;
066: }
067: try {
068: return new BufferedInputStream(new FileInputStream(
069: new File(dir, res)));
070: } catch (IOException e) {
071: continue;
072: }
073: }
074:
075: return null;
076: }
077:
078: // override from abstract base class
079: protected Class loadClass(String name, boolean resolve)
080: throws ClassNotFoundException {
081: // First, if the Python runtime system has a default class loader,
082: // defer to it.
083: ClassLoader classLoader = Py.getSystemState().getClassLoader();
084: if (classLoader != null) {
085: return classLoader.loadClass(name);
086: }
087:
088: // Search the sys.path for a .class file matching the named class.
089: try {
090: return Class.forName(name);
091: } catch (ClassNotFoundException e) {
092: }
093:
094: Class c = findLoadedClass(name);
095: if (c != null) {
096: return c;
097: }
098:
099: PyList path = Py.getSystemState().path;
100: for (int i = 0; i < path.__len__(); i++) {
101: InputStream fis = null;
102: File file = null;
103: int size = 0;
104: PyObject entry = path.__getitem__(i);
105: if (entry instanceof SyspathArchive) {
106: SyspathArchive archive = (SyspathArchive) entry;
107: String entryname = name.replace('.', SLASH_CHAR)
108: + ".class";
109: ZipEntry ze = archive.getEntry(entryname);
110: if (ze != null) {
111: try {
112: fis = archive.getInputStream(ze);
113: size = (int) ze.getSize();
114: } catch (IOException exc) {
115: ;
116: }
117: }
118: } else {
119: String dir = entry.__str__().toString();
120: file = getFile(dir, name);
121: if (file != null) {
122: size = (int) file.length();
123: try {
124: fis = new FileInputStream(file);
125: } catch (FileNotFoundException e) {
126: ;
127: }
128: }
129: }
130: if (fis == null) {
131: continue;
132: }
133: try {
134: byte[] buffer = new byte[size];
135: int nread = 0;
136: while (nread < size) {
137: nread += fis.read(buffer, nread, size - nread);
138: }
139: fis.close();
140: return loadClassFromBytes(name, buffer);
141: } catch (IOException e) {
142: continue;
143: } finally {
144: try {
145: fis.close();
146: } catch (IOException e) {
147: continue;
148: }
149: }
150: }
151:
152: // couldn't find the .class file on sys.path
153: throw new ClassNotFoundException(name);
154: }
155:
156: private File getFile(String dir, String name) {
157: String accum = "";
158: boolean first = true;
159: for (StringTokenizer t = new StringTokenizer(name, "."); t
160: .hasMoreTokens();) {
161: String token = t.nextToken();
162: if (!first) {
163: accum += File.separator;
164: }
165: accum += token;
166: first = false;
167: }
168: if (dir.length() == 0) {
169: dir = null;
170: }
171: return new File(dir, accum + ".class");
172: }
173:
174: private Class loadClassFromBytes(String name, byte[] data) {
175: // System.err.println("loadClassFromBytes("+name+", byte[])");
176: Class c = defineClass(name, data, 0, data.length);
177: resolveClass(c);
178: // This method has caused much trouble. Using it breaks jdk1.2rc1
179: // Not using it can make SUN's jdk1.1.6 JIT slightly unhappy.
180: // Don't use by default, but allow python.options.compileClass to
181: // override
182: if (!Options.skipCompile) {
183: // System.err.println("compile: "+name);
184: Compiler.compileClass(c);
185: }
186: return c;
187: }
188:
189: }
|