1 #!/usr/bin/env python 2 3 import ihooks 4 import os, glob 5 from imp import PY_SOURCE, PKG_DIRECTORY, C_BUILTIN 6 import classfile, bytecode 7 import new 8 9 JAVA_PACKAGE = 20041113 10 JAVA_CLASS = 20041114 11 12 class ClassHooks(ihooks.Hooks): 13 14 "A filesystem hooks class providing information about supported files." 15 16 def get_suffixes(self): 17 18 "Return the recognised suffixes." 19 20 return ihooks.Hooks.get_suffixes(self) + [("", "", JAVA_PACKAGE), (os.extsep + "class", "r", JAVA_CLASS)] 21 22 class ClassLoader(ihooks.ModuleLoader): 23 24 "A class providing support for searching directories for supported files." 25 26 def find_module_in_dir(self, name, dir, allow_packages=1): 27 28 """ 29 Find the module with the given 'name' in the given directory 'dir'. 30 Since Java packages/modules are directories containing class files, 31 return the required information tuple only when the path constructed 32 from 'dir' and 'name' refers to a directory containing class files. 33 """ 34 35 result = ihooks.ModuleLoader.find_module_in_dir(self, name, dir, allow_packages) 36 if result is not None: 37 return result 38 39 # Provide a special name for the current directory. 40 41 if name == "__this__": 42 path = "." 43 elif dir is None: 44 return None 45 else: 46 path = os.path.join(dir, name) 47 48 #print "Processing name", name, "in", dir, "producing", path 49 50 if self._find_module_at_path(path): 51 return (None, path, ("", "", JAVA_PACKAGE)) 52 else: 53 return None 54 55 def _find_module_at_path(self, path): 56 if os.path.isdir(path): 57 58 # Look for classes in the directory. 59 60 if len(glob.glob(os.path.join(path, "*" + os.extsep + "class"))) != 0: 61 return 1 62 63 # Otherwise permit importing where directories containing classes exist. 64 65 for filename in os.listdir(path): 66 pathname = os.path.join(path, filename) 67 result = self._find_module_at_path(pathname) 68 if result is not None: 69 return result 70 71 return None 72 73 def load_module(self, name, stuff): 74 75 """ 76 Load the module with the given 'name', whose 'stuff' which describes the 77 location of the module is a tuple of the form (file, filename, (suffix, 78 mode, data type)). Return a module object or raise an ImportError if a 79 problem occurred in the import operation. 80 """ 81 82 # Just go into the directory and find the class files. 83 84 file, filename, info = stuff 85 suffix, mode, datatype = info 86 if datatype != JAVA_PACKAGE: 87 return ihooks.ModuleLoader.load_module(self, name, stuff) 88 89 print "Loading", file, filename, info 90 91 # Prepare a dictionary of globals. 92 93 global_names = {} 94 global_names.update(__builtins__.__dict__) 95 96 # Set up the module. 97 98 module = self.hooks.add_module(name) 99 module.__path__ = [filename] 100 101 # Process each class file, producing a genuine Python class. 102 103 class_files = [] 104 classes = [] 105 for class_filename in glob.glob(os.path.join(filename, "*" + os.extsep + "class")): 106 print "Importing class", class_filename 107 f = open(class_filename, "rb") 108 s = f.read() 109 f.close() 110 class_file = classfile.ClassFile(s) 111 translator = bytecode.ClassTranslator(class_file) 112 cls = translator.process(global_names) 113 module.__dict__[cls.__name__] = cls 114 classes.append(cls) 115 116 # Finally, call __clinit__ methods for all relevant classes. 117 118 #for cls in classes: 119 # if hasattr(cls, "__clinit__"): 120 # cls.__clinit__() 121 122 return module 123 124 importer = ihooks.ModuleImporter(loader=ClassLoader(hooks=ClassHooks())) 125 importer.install() 126 127 # vim: tabstop=4 expandtab shiftwidth=4