001: package org.python.modules;
002:
003: import org.python.core.Py;
004: import org.python.core.PyFile;
005: import org.python.core.PyList;
006: import org.python.core.PyModule;
007: import org.python.core.PyObject;
008: import org.python.core.PyString;
009: import org.python.core.PyTuple;
010: import org.python.core.PyInteger;
011:
012: import java.io.File;
013: import java.io.FileInputStream;
014: import java.io.IOException;
015: import java.io.InputStream;
016:
017: /*
018: * A bogus implementation of the CPython builtin module "imp".
019: * Only the functions required by IDLE and PMW are implemented.
020: * Luckily these function are also the only function that IMO can
021: * be implemented under JPython.
022: */
023:
024: public class imp {
025: public static PyString __doc__ = new PyString(
026: "This module provides the components needed to build your own\n"
027: + "__import__ function. Undocumented functions are obsolete.\n");
028:
029: public static final int PY_SOURCE = 1;
030: public static final int PY_COMPILED = 2;
031: public static final int PKG_DIRECTORY = 5;
032: public static final int PY_FROZEN = 7;
033: public static final int IMP_HOOK = 9;
034:
035: private static class ModuleInfo {
036: PyObject file;
037: String filename;
038: String suffix;
039: String mode;
040: int type;
041:
042: ModuleInfo(PyObject file, String filename, String suffix,
043: String mode, int type) {
044: this .file = file;
045: this .filename = filename;
046: this .suffix = suffix;
047: this .mode = mode;
048: this .type = type;
049: }
050: }
051:
052: private static PyObject newFile(File file) {
053: try {
054: return new PyFile(new FileInputStream(file));
055: } catch (IOException ioe) {
056: throw Py.IOError(ioe);
057: }
058: }
059:
060: private static boolean caseok(File file, String filename,
061: int namelen) {
062: return org.python.core.imp.caseok(file, filename, namelen);
063: }
064:
065: /**
066: * This needs to be consolidated with the code in (@see org.python.core.imp).
067: *
068: * @param name module name
069: * @param entry an iterable of paths
070: * @param findingPackage if looking for a package only try to locate __init__
071: * @return null if no module found otherwise module information
072: */
073: static ModuleInfo findFromSource(String name, PyObject entry,
074: boolean findingPackage) {
075: int nlen = name.length();
076: String sourceName = "__init__.py";
077: String compiledName = "__init__$py.class";
078: String directoryName = org.python.core.imp
079: .defaultEmptyPathDirectory(entry.toString());
080:
081: // First check for packages
082: File dir = findingPackage ? new File(directoryName) : new File(
083: directoryName, name);
084: File sourceFile = new File(dir, sourceName);
085: File compiledFile = new File(dir, compiledName);
086:
087: boolean pkg = (dir.isDirectory() && caseok(dir, name, nlen) && (sourceFile
088: .isFile() || compiledFile.isFile()));
089:
090: if (!findingPackage) {
091: if (pkg) {
092: return new ModuleInfo(Py.None, dir.getPath(), "", "",
093: PKG_DIRECTORY);
094: } else {
095: Py.writeDebug("import", "trying source "
096: + dir.getPath());
097: sourceName = name + ".py";
098: compiledName = name + "$py.class";
099: sourceFile = new File(directoryName, sourceName);
100: compiledFile = new File(directoryName, compiledName);
101: }
102: }
103:
104: if (sourceFile.isFile() && caseok(sourceFile, sourceName, nlen)) {
105: if (compiledFile.isFile()
106: && caseok(compiledFile, compiledName, nlen)) {
107: Py.writeDebug("import", "trying precompiled "
108: + compiledFile.getPath());
109: long pyTime = sourceFile.lastModified();
110: long classTime = compiledFile.lastModified();
111: if (classTime >= pyTime) {
112: return new ModuleInfo(newFile(compiledFile),
113: compiledFile.getPath(), ".class", "rb",
114: PY_COMPILED);
115: }
116: }
117: return new ModuleInfo(newFile(sourceFile), sourceFile
118: .getPath(), ".py", "r", PY_SOURCE);
119: }
120:
121: // If no source, try loading precompiled
122: Py.writeDebug("import", "trying " + compiledFile.getPath());
123: if (compiledFile.isFile()
124: && caseok(compiledFile, compiledName, nlen)) {
125: return new ModuleInfo(newFile(compiledFile), compiledFile
126: .getPath(), ".class", "rb", PY_COMPILED);
127: }
128: return null;
129: }
130:
131: public static PyObject find_module(String name) {
132: return find_module(name, null);
133: }
134:
135: public static PyObject load_source(String modname, String filename) {
136: PyObject mod = Py.None;
137: //XXX: bufsize is ignored in PyFile now, but look 3rd arg if this ever changes.
138: PyFile file = new PyFile(filename, "r", 1024);
139: Object o = file.__tojava__(InputStream.class);
140: if (o == Py.NoConversion) {
141: throw Py.TypeError("must be a file-like object");
142: }
143: mod = org.python.core.imp.createFromSource(modname.intern(),
144: (InputStream) o, filename.toString());
145: PyObject modules = Py.getSystemState().modules;
146: modules.__setitem__(modname.intern(), mod);
147: return mod;
148: }
149:
150: public static PyObject find_module(String name, PyObject path) {
151: if (path == null || path == Py.None) {
152: path = Py.getSystemState().path;
153: }
154:
155: PyObject iter = path.__iter__();
156: for (PyObject p = null; (p = iter.__iternext__()) != null;) {
157: ModuleInfo mi = findFromSource(name, p, false);
158: if (mi == null) {
159: continue;
160: }
161: return new PyTuple(new PyObject[] {
162: mi.file,
163: new PyString(mi.filename),
164: new PyTuple(new PyObject[] {
165: new PyString(mi.suffix),
166: new PyString(mi.mode),
167: Py.newInteger(mi.type) }), });
168: }
169: throw Py.ImportError("No module named " + name);
170: }
171:
172: public static PyObject load_module(String name, PyObject file,
173: PyObject filename, PyTuple data) {
174: PyObject mod = Py.None;
175: int type = ((PyInteger) data.__getitem__(2).__int__())
176: .getValue();
177: while (mod == Py.None) {
178: Object o = file.__tojava__(InputStream.class);
179: if (o == Py.NoConversion) {
180: throw Py.TypeError("must be a file-like object");
181: }
182: switch (type) {
183: case PY_SOURCE:
184: mod = org.python.core.imp
185: .createFromSource(name.intern(),
186: (InputStream) o, filename.toString());
187: break;
188: case PY_COMPILED:
189: mod = org.python.core.imp
190: .loadFromCompiled(name.intern(),
191: (InputStream) o, filename.toString());
192: break;
193: case PKG_DIRECTORY:
194: PyModule m = org.python.core.imp.addModule(name);
195: m.__dict__.__setitem__("__path__", new PyList(
196: new PyObject[] { filename }));
197: m.__dict__.__setitem__("__file__", filename);
198: ModuleInfo mi = findFromSource(name, filename, true);
199: type = mi.type;
200: file = mi.file;
201: filename = new PyString(mi.filename);
202: break;
203: default:
204: throw Py.ImportError("No module named " + name);
205: }
206: }
207: PyObject modules = Py.getSystemState().modules;
208: modules.__setitem__(name.intern(), mod);
209: return mod;
210: }
211:
212: public static PyObject get_suffixes() {
213: return new PyList(
214: new PyObject[] {
215: new PyTuple(new PyObject[] {
216: new PyString(".py"), new PyString("r"),
217: Py.newInteger(PY_SOURCE), }),
218: new PyTuple(new PyObject[] {
219: new PyString(".class"),
220: new PyString("rb"),
221: Py.newInteger(PY_COMPILED), }), });
222: }
223:
224: public static PyModule new_module(String name) {
225: return new PyModule(name, null);
226: }
227: }
|