KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > core > ZipFileImporter


1 package org.python.core;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.util.zip.ZipEntry JavaDoc;
6
7 /**
8  * Load python source from jar or zip files.
9  */

10 public class ZipFileImporter extends PyObject {
11
12     private SyspathArchive archive;
13
14     /**
15      * If this path is not an archive (.zip or .jar) then raise
16      * an ImportError, otherwise this instance will handle this
17      * path.
18      * @param path the path to check for modules
19      */

20     public ZipFileImporter(PyObject path) {
21         if(!(path instanceof SyspathArchive)) {
22             throw Py.ImportError(path.toString());
23         }
24         this.archive = (SyspathArchive)path;
25     }
26
27     /**
28      * Find the module for the fully qualified name.
29      * @param name the fully qualified name of the module
30      * @return a loader instance if this importer can load the module, None otherwise
31      */

32     public PyObject find_module(String JavaDoc name) {
33         return find_module(name, Py.None);
34     }
35
36     /**
37      * Find the module for the fully qualified name.
38      * @param name the fully qualified name of the module
39      * @param path if installed on the meta-path None or a module path
40      * @return a loader instance if this importer can load the module, None otherwise
41      */

42     public PyObject find_module(String JavaDoc name, PyObject path) {
43         ZipModuleInfo zip = getModuleInfo(name, this.archive);
44         return (zip == null) ? Py.None : new ZipFileLoader(zip);
45     }
46
47     /**
48      * Returns a string representation of the object.
49      *
50      * @return a string representation of the object.
51      */

52     public String JavaDoc toString() {
53         return this.getType().toString();
54     }
55
56     /**
57      * Returns the last part of a fully qualified name. For example, the name
58      * <p>
59      * <code>
60      * a.b.c
61      * </code>
62      * </p>
63      * would return <code>c</code>.
64      * @param name a fully qualified name
65      * @return the last part of a fully qualified name
66      */

67     private String JavaDoc getSubName(String JavaDoc name) {
68         int x = name.lastIndexOf(".");
69         if (x >= 0) {
70             return name.substring(x+1);
71         }
72         return name;
73     }
74
75     /**
76      * Find the module name starting at the zipArchive root. This method will
77      * look for both package and non-package names in the archive. If the name
78      * is not found null will be returned.
79      * @param name the fully qualified module name
80      * @param zipArchive the root of the path to begin looking
81      * @return null if the module is not found, a ZipModuleInfo instance otherwise
82      */

83     private ZipModuleInfo getModuleInfo(String JavaDoc name, SyspathArchive zipArchive) {
84         String JavaDoc entryName = getSubName(name);
85
86         String JavaDoc sourceName = entryName + "/__init__.py";
87         String JavaDoc compiledName = entryName + "/__init__$py.class";
88         ZipEntry JavaDoc sourceEntry = zipArchive.getEntry(sourceName);
89         ZipEntry JavaDoc compiledEntry = zipArchive.getEntry(compiledName);
90
91         boolean pkg = (sourceEntry != null || compiledEntry != null);
92         if(!pkg) {
93             sourceName = entryName + ".py";
94             compiledName = entryName + "$py.class";
95             sourceEntry = zipArchive.getEntry(sourceName);
96             compiledEntry = zipArchive.getEntry(compiledName);
97         } else {
98            zipArchive = zipArchive.makeSubfolder(entryName);
99         }
100
101         ZipModuleInfo info = null;
102         if (sourceEntry != null) {
103             Py.writeDebug("import", "trying source entry: " + sourceName
104               + " from jar/zip file " + zipArchive);
105             if (compiledEntry != null) {
106                 Py.writeDebug("import", "trying precompiled entry "
107                         + compiledName + " from jar/zip file " + zipArchive);
108                 long pyTime = sourceEntry.getTime();
109                 long classTime = compiledEntry.getTime();
110                 if (classTime >= pyTime) {
111                     info = new ZipModuleInfo(zipArchive, compiledEntry, true);
112                 }
113             }
114             info = new ZipModuleInfo(zipArchive, sourceEntry, false);
115         }
116
117         if(pkg && info != null) {
118             info.path = new PyList(new PyObject[]{zipArchive});
119         }
120
121         return info;
122     }
123
124     /**
125      * Loader for zipfile python sources.
126      */

127     public class ZipFileLoader extends PyObject {
128
129         private ZipModuleInfo _info;
130
131         public ZipFileLoader(ZipModuleInfo info) {
132             this._info = info;
133         }
134
135         /**
136          * A loaded module for the fully qualified name.
137          * @param moduleName the fully qualified name
138          * @return a loaded module (added to sys.path)
139          */

140         public PyObject load_module(String JavaDoc moduleName) {
141             PyModule m = null;
142             if(this._info.path != null) {
143                 m = imp.addModule(moduleName);
144                 m.__dict__.__setitem__("__path__", this._info.path);
145                 m.__dict__.__setitem__("__loader__", this);
146             }
147
148             InputStream JavaDoc is = null; // should this be closed?
149
ZipEntry JavaDoc entry = this._info.zipEntry;
150             try {
151                 is = this._info.archive.getInputStream(entry);
152             } catch (IOException JavaDoc e) {
153                 Py.writeDebug("import", "loadFromZipFile exception: " + e.toString());
154                 throw Py.ImportError("error loading from zipfile");
155             }
156             if (this._info.compiled) {
157                 PyObject o = imp.createFromPyClass(moduleName, is, true, entry.getName());
158                 return (m == null) ? o : m;
159             } else {
160                 PyObject o = imp.createFromSource(moduleName, is, entry.getName(), null);
161                 return (m == null) ? o : m;
162             }
163         }
164
165         /**
166          * Returns a string representation of the object.
167          *
168          * @return a string representation of the object.
169          */

170         public String JavaDoc toString() {
171             return this.getType().toString();
172         }
173     }
174
175     private class ZipModuleInfo {
176         /** The path of the package if it is a package. */
177         public PyObject path;
178         /** Whether the code is already compiled. */
179         public boolean compiled;
180         /** The zip entry for the file to load. */
181         public ZipEntry JavaDoc zipEntry;
182         /** The archive in which the zip entry resides. */
183         public SyspathArchive archive;
184
185         public ZipModuleInfo(SyspathArchive archive, ZipEntry JavaDoc zipEntry, boolean compiled) {
186             this(archive, zipEntry, compiled, null);
187         }
188
189         public ZipModuleInfo(SyspathArchive archive, ZipEntry JavaDoc zipEntry, boolean compiled, PyObject path) {
190             this.path = path;
191             this.archive = archive;
192             this.zipEntry = zipEntry;
193             this.compiled = compiled;
194         }
195     }
196 }
197
198
Popular Tags