# Copyright (c) Corporation for National Research Initiatives import os import jarray from java.util.zip import * from java.io import * from util import lookup from util import listAllClasses, openResource DOT = '.' SLASH = '/' def copy(instream, outstream): data = jarray.zeros(1024*4, 'b') while 1: if instream.available() == 0: break n = instream.read(data) if n == -1: break outstream.write(data, 0, n) class JavaArchive: def __init__(self, packages=[]): self.files = [] self.entries = [] self.packages = packages self.manifest = [] self.jar_entries = {} def addFile(self, rootdir, filename): self.files.append( (rootdir, filename) ) def addClass(self, rootdir, classname, properties=None): filename = apply(os.path.join, classname.split('.'))+'.class' outfile = SLASH.join(filename.split(os.sep)) if self.jar_entries.has_key(outfile): return self.jar_entries[outfile] = 1 self.addFile(rootdir, filename) if properties is not None: self.manifest.append("Name: "+ SLASH.join(classname.split('.'))) self.addToManifest(properties) def addEntry(self, entry): outfile = entry.getZipName() if self.jar_entries.has_key(outfile): return self.jar_entries[outfile] = 1 self.entries.append(entry) def addToManifest(self, properties=None, **kw): if properties is None: properties = {} properties.update(kw) for name, value in properties.items(): self.manifest.append(name+": "+value) self.manifest.append("") def dumpManifest(self): if len(self.manifest) == 0: return outfile = "META-INF/MANIFEST.MF" NL = '\n' self.zipfile.putNextEntry(ZipEntry(outfile)) self.zipfile.write(NL.join(self.manifest)) def dumpFiles(self): for rootdir, filename in self.files: infile = os.path.join(rootdir, filename) outfile = SLASH.join(filename.split(os.sep)) instream = FileInputStream(infile) self.zipfile.putNextEntry(ZipEntry(outfile)) copy(instream, self.zipfile) instream.close() for entry in self.entries: outfile = entry.getZipName() instream = entry.getInputStream() self.zipfile.putNextEntry(ZipEntry(outfile)) copy(instream, self.zipfile) instream.close() for package, skiplist in self.packages: self.addPackage(package, skiplist) self.dumpManifest() def dump(self, filename): self.zipfile = ZipOutputStream(FileOutputStream(filename)) self.dumpFiles() self.zipfile.close() # handle packages (typically org.python.core, ...) def addPackage(self, package, skiplist = []): pkg = lookup(package) base = package.replace(DOT,SLASH) for cl in listAllClasses(pkg): name = package+ '.' +cl if name in skiplist: # print 'skipping',name # ?? dbg continue entryname = base +'/' + cl + '.class' self.zipfile.putNextEntry(ZipEntry(entryname)) instream = openResource(entryname) copy(instream, self.zipfile) instream.close() ## # add just one class from a package ## def addOneClass(self, pkgclass): ## parts = pkgclass.split('.') ## package = DOT.join(parts[:-1]) ## pkg = lookup(package) ## filename = os.path.join(pkg.__path__[0], parts[-1]) + '.class' ## entryname = '/'.join(parts) + '.class' ## self.zipfile.putNextEntry(ZipEntry(entryname)) ## instream = FileInputStream(filename) ## copy(instream, self.zipfile) ## instream.close() ## ## # The next three methods handle packages (typically org.python.core, ...) ## def addPackage(self, package, skiplist=[]): ## pkg = lookup(package) ## if hasattr(pkg, '__file__'): ## return self.addZipPackage(package+'.', pkg.__file__, skiplist) ## elif hasattr(pkg, '__path__') and len(pkg.__path__) == 1: ## return self.addDirectoryPackage(package+'.', ## pkg.__path__[0], skiplist) ## raise ValueError, "can't find package: "+repr(package) ## ## def addZipPackage(self, package, zipfile, skiplist): ## zf = ZipFile(zipfile) ## for entry in zf.entries(): ## filename = entry.name ## if filename[-6:] != '.class': ## continue ## name = filename[:-6].replace(SLASH, DOT) ## ## if name[:len(package)] != package: ## continue ## self.zipfile.putNextEntry(ZipEntry(filename)) ## copy(zf.getInputStream(entry), self.zipfile) ## zf.close() ## ## def addDirectoryPackage(self, package, directory, skiplist): ## for file in os.listdir(directory): ## if file[-6:] != '.class': ## continue ## name = package+file[:-6] ## if name in skiplist: ## continue ## entryname = SLASH.join(name.split('.')) + '.class' ## self.zipfile.putNextEntry(ZipEntry(entryname)) ## instream = FileInputStream(os.path.join(directory, file)) ## copy(instream, self.zipfile) ## instream.close() if __name__ == '__main__': root = "c:\\jpython\\tools\\jpythonc2" ja = JavaArchive() ja.addFile(root, "jar.py") ja.addFile(root, "proxies.py") ja.addClass(root, "jast.Statement$py") print ja.files ja.dump(os.path.join(root, "test\\t.jar"))