1 package org.python.core; 2 3 import java.io.IOException ; 4 import java.io.InputStream ; 5 import java.util.zip.ZipEntry ; 6 7 10 public class ZipFileImporter extends PyObject { 11 12 private SyspathArchive archive; 13 14 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 32 public PyObject find_module(String name) { 33 return find_module(name, Py.None); 34 } 35 36 42 public PyObject find_module(String name, PyObject path) { 43 ZipModuleInfo zip = getModuleInfo(name, this.archive); 44 return (zip == null) ? Py.None : new ZipFileLoader(zip); 45 } 46 47 52 public String toString() { 53 return this.getType().toString(); 54 } 55 56 67 private String getSubName(String name) { 68 int x = name.lastIndexOf("."); 69 if (x >= 0) { 70 return name.substring(x+1); 71 } 72 return name; 73 } 74 75 83 private ZipModuleInfo getModuleInfo(String name, SyspathArchive zipArchive) { 84 String entryName = getSubName(name); 85 86 String sourceName = entryName + "/__init__.py"; 87 String compiledName = entryName + "/__init__$py.class"; 88 ZipEntry sourceEntry = zipArchive.getEntry(sourceName); 89 ZipEntry 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 127 public class ZipFileLoader extends PyObject { 128 129 private ZipModuleInfo _info; 130 131 public ZipFileLoader(ZipModuleInfo info) { 132 this._info = info; 133 } 134 135 140 public PyObject load_module(String 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 is = null; ZipEntry entry = this._info.zipEntry; 150 try { 151 is = this._info.archive.getInputStream(entry); 152 } catch (IOException 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 170 public String toString() { 171 return this.getType().toString(); 172 } 173 } 174 175 private class ZipModuleInfo { 176 177 public PyObject path; 178 179 public boolean compiled; 180 181 public ZipEntry zipEntry; 182 183 public SyspathArchive archive; 184 185 public ZipModuleInfo(SyspathArchive archive, ZipEntry zipEntry, boolean compiled) { 186 this(archive, zipEntry, compiled, null); 187 } 188 189 public ZipModuleInfo(SyspathArchive archive, ZipEntry 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 |