# Copyright (c) Corporation for National Research Initiatives import sys import os from types import TypeType from java import io from java.util.zip import ZipFile def fix(n): DOT = '.' return DOT.join(n.split('/')) def unfix(n): SLASH = '/' return SLASH.join(n.split('.')) def getClass(t, names): #print t, names if t[0] == '(': index = 1 while index < len(t) and t[index] != ')': off, value = getClass(t[index:], names) index = index+off getClass(t[index+1:], names) elif t[0] == 'L': end = t.index(';') value = t[1:end] names[fix(value)] = 1 return end, t[1:end] elif t[0] == '[': off, ret = getClass(t[1:], names) return off+1, ret else: return 1, None def dependencies(file): data = io.DataInputStream(file) data.readInt() data.readShort() data.readShort() n = data.readShort() strings = [None]*n classes = [] types = [] i = 0 while i < n-1: tag = data.readByte() if tag == 1: name = data.readUTF() strings[i] = name elif tag == 7: classes.append(data.readShort()) elif tag == 9 or tag == 10 or tag == 11: data.readShort() data.readShort() elif tag == 8: data.readShort() elif tag == 3: data.readInt() elif tag == 4: data.readFloat() elif tag == 5: data.readLong() i = i+1 elif tag == 6: data.readDouble() i = i+1 elif tag == 12: data.readShort() types.append(data.readShort()) i = i+1 data.readShort() # access_flags data.readShort() # this_class data.readShort() # super_class interfaces_count = data.readShort() for i in range(interfaces_count): data.readShort() fields_count = data.readShort() for i in range(fields_count): data.readShort() # access_flags data.readShort() # name_index types.append(data.readShort()) attributes_count = data.readShort() for j in range(attributes_count): data.readShort() # attribute_name_index attribute_length = data.readInt() data.skip(attribute_length) names = {} for c in classes: #print c, strings[c-1] name = fix(strings[c-1]) if name[0] == '[': continue names[name]= 1 for t in types: getClass(strings[t-1], names) return filter(defaultFilter, names.keys()) def defaultFilter(name): return not (name[:5] == 'java.' or name[:16] == 'org.python.core.') from org.python.core import PyJavaPackage from util import lookup, getzip from util import openResource def getFile(name): dot = name.rfind('.') if dot == -1: return PkgEntry(name) ## return topFile(name) package = lookup(name[:dot]) if isinstance(package, PyJavaPackage): return PkgEntry(name) ## if hasattr(package, '__file__'): ## return ZipEntry(package.__file__, name) ## elif hasattr(package, '__path__') and len(package.__path__) == 1: ## return DirEntry(package.__path__[0], name) elif isinstance(package, TypeType): # this 'package' is a java class f = getFile(name[:dot]) if f: return f class PkgEntry: def __init__(self, classname): self.classname = classname def __repr__(self): return "PkgEntry(%s)" % (self.classname) def getInputStream(self): res = unfix(self.classname) + '.class' return openResource(res) def getZipName(self): return '/'.join(self.classname.split('.')) + '.class' class ResourceEntry: def __init__(self, name): self.name = name def __repr__(self): return "ResourceEntry(%s)" % (self.name) def getInputStream(self): import java return java.lang.Class.getResourceAsStream("".__class__, self.name) def getZipName(self): return self.name[1:] ##class ZipEntry: ## def __init__(self, filename, classname): ## self.filename = filename ## self.classname = classname ## ## def __repr__(self): ## return "ZipEntry(%s, %s)" % (self.filename, self.classname) ## ## def getInputStream(self): ## zf = getzip(self.filename) ## zfilename = unfix(self.classname) + '.class' ## entry = zf.getEntry(zfilename) ## return zf.getInputStream(entry) ## ## ##class DirEntry: ## def __init__(self, dirname, classname): ## self.dirname = dirname ## self.classname = classname ## ## def __repr__(self): ## return "DirEntry(%s, %s)" % (self.dirname, self.classname) ## ## def getInputStream(self): ## lastname = self.classname.split('.')[-1] ## fullname = os.path.join(self.dirname, lastname+'.class') ## return io.FileInputStream(fullname) def depends(name): if name[0] == '/': return ResourceEntry(name), [] ze = getFile(name) ip = ze.getInputStream() ret = dependencies(ip) ip.close() return ze, ret if __name__ == '__main__': #print getFile('org.python.modules.strop') #print getFile('java.lang.String') #print depend('com.oroinc.text.regex.Perl5Matcher') for name in ['javax.swing.JButton', 'java.lang.String']: print depends(name)