javaclass

Annotated classhook.py

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