org.python.core.SyspathJavaLoader Maven / Gradle / Ivy
// Copyright (c) Corporation for National Research Initiatives
// Copyright 2000 Samuele Pedroni
package org.python.core;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;
public class SyspathJavaLoader extends ClassLoader {
private static final char SLASH_CHAR = '/';
public InputStream getResourceAsStream(String res) {
Py.writeDebug("resource", "trying resource: " + res);
ClassLoader classLoader = Py.getSystemState().getClassLoader();
if (classLoader != null) {
return classLoader.getResourceAsStream(res);
}
classLoader = this.getClass().getClassLoader();
InputStream ret;
if (classLoader != null) {
ret = classLoader.getResourceAsStream(res);
} else {
ret = ClassLoader.getSystemResourceAsStream(res);
}
if (ret != null) {
return ret;
}
if (res.charAt(0) == SLASH_CHAR) {
res = res.substring(1);
}
String entryRes = res;
if (File.separatorChar != SLASH_CHAR) {
res = res.replace(SLASH_CHAR, File.separatorChar);
entryRes = entryRes.replace(File.separatorChar, SLASH_CHAR);
}
PyList path = Py.getSystemState().path;
for (int i = 0; i < path.__len__(); i++) {
PyObject entry = path.__getitem__(i);
if (entry instanceof SyspathArchive) {
SyspathArchive archive = (SyspathArchive) entry;
ZipEntry ze = archive.getEntry(entryRes);
if (ze != null) {
try {
return archive.getInputStream(ze);
} catch (IOException e) {
;
}
}
continue;
}
String dir = entry.__str__().toString();
if (dir.length() == 0) {
dir = null;
}
try {
return new BufferedInputStream(new FileInputStream(new File(
dir, res)));
} catch (IOException e) {
continue;
}
}
return null;
}
// override from abstract base class
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// First, if the Python runtime system has a default class loader,
// defer to it.
ClassLoader classLoader = Py.getSystemState().getClassLoader();
if (classLoader != null) {
return classLoader.loadClass(name);
}
// Search the sys.path for a .class file matching the named class.
try {
return Class.forName(name);
} catch(ClassNotFoundException e) {}
Class c = findLoadedClass(name);
if(c != null) {
return c;
}
PyList path = Py.getSystemState().path;
for(int i = 0; i < path.__len__(); i++) {
InputStream fis = null;
File file = null;
int size = 0;
PyObject entry = path.__getitem__(i);
if(entry instanceof SyspathArchive) {
SyspathArchive archive = (SyspathArchive)entry;
String entryname = name.replace('.', SLASH_CHAR) + ".class";
ZipEntry ze = archive.getEntry(entryname);
if(ze != null) {
try {
fis = archive.getInputStream(ze);
size = (int)ze.getSize();
} catch(IOException exc) {
;
}
}
} else {
String dir = entry.__str__().toString();
file = getFile(dir, name);
if(file != null) {
size = (int)file.length();
try {
fis = new FileInputStream(file);
} catch(FileNotFoundException e) {
;
}
}
}
if(fis == null) {
continue;
}
try {
byte[] buffer = new byte[size];
int nread = 0;
while(nread < size) {
nread += fis.read(buffer, nread, size - nread);
}
fis.close();
return loadClassFromBytes(name, buffer);
} catch(IOException e) {
continue;
} finally {
try {
fis.close();
} catch(IOException e) {
continue;
}
}
}
// couldn't find the .class file on sys.path
throw new ClassNotFoundException(name);
}
private File getFile(String dir, String name) {
String accum = "";
boolean first = true;
for (StringTokenizer t = new StringTokenizer(name, "."); t
.hasMoreTokens();) {
String token = t.nextToken();
if (!first) {
accum += File.separator;
}
accum += token;
first = false;
}
if (dir.length() == 0) {
dir = null;
}
return new File(dir, accum + ".class");
}
private Class loadClassFromBytes(String name, byte[] data) {
// System.err.println("loadClassFromBytes("+name+", byte[])");
Class c = defineClass(name, data, 0, data.length);
resolveClass(c);
// This method has caused much trouble. Using it breaks jdk1.2rc1
// Not using it can make SUN's jdk1.1.6 JIT slightly unhappy.
// Don't use by default, but allow python.options.compileClass to
// override
if (!Options.skipCompile) {
// System.err.println("compile: "+name);
Compiler.compileClass(c);
}
return c;
}
}