javaclass

tools/wrap.py

158:a52e70c3f294
2005-01-23 Paul Boddie Added "safety measures" for exception offset insertion, although better measures are necessary to avoid bizarre JDK 1.4 exception tables.
     1 #!/usr/bin/env python     2      3 """     4 Wrap Java packages, converting the skeleton Java classes to Python modules which     5 connect to concrete Python implementation classes.     6 """     7      8 import javaclass.classfile     9 import glob    10 import sys    11 import os    12     13 if __name__ == "__main__":    14     if len(sys.argv) < 2:    15         print "wrap.py <package directory> <wrapped package>"    16         print "For example:"    17         print "wrap.py qtjava qt"    18         sys.exit(1)    19     20     # Process all directories in the list, producing for each a Python source    21     # file containing the classes found in the given directory.    22     23     directory, package = sys.argv[1:3]    24     f = open(os.path.join(directory, "__init__.py"), "w")    25     f.write("import %s\n" % package)    26     f.write("import java.lang\n")    27     28     # Process each class file.    29     30     for filename in glob.glob(os.path.join(directory, "*.class")):    31         print "Processing", filename    32         cf = open(filename, "rb")    33         c = javaclass.classfile.ClassFile(cf.read())    34         cf.close()    35     36         # Write the class into the source file.    37     38         full_name = c.this_class.get_python_name()    39         class_name = full_name.split(".")[-1]    40         f.write("class %s(%s.%s, java.lang.Object):\n" % (class_name, package, class_name))    41     42         # Process methods in the class, writing wrapper code.    43     44         method_names = []    45         for method in c.methods:    46             wrapped_method_name = method.get_unqualified_python_name()    47     48             # Find out more about the parameters, introducing special    49             # conversions where appropriate.    50     51             parameter_names = ["self"]    52             parameter_index = 1    53             conversions = []    54     55             for parameter in method.get_descriptor()[0]:    56                 parameter_name = "p" + str(parameter_index)    57                 base_type, object_type, array_type = parameter    58     59                 # Special cases.    60     61                 if object_type == "java/lang/String":    62                     conversions.append("%s = unicode(%s)" % (parameter_name, parameter_name))    63                 # elif object_type == "java/util/Map":    64                     # NOTE: Using special private interface.    65                     # conversions.append("%s = %s.as_dict()" % (parameter_name, parameter_name))    66     67                 parameter_names.append(parameter_name)    68                 parameter_index += 1    69     70             # Write the signature.    71     72             f.write("    def %s(%s):\n" % (wrapped_method_name, ", ".join(parameter_names)))    73     74             # Write any conversions.    75     76             for conversion in conversions:    77                 f.write("        %s\n" % conversion)    78     79             # Write the call to the wrapped method.    80     81             f.write("        return %s.%s.%s(%s)\n" % (package, class_name, wrapped_method_name, ", ".join(parameter_names)))    82     83             # Record the correspondence between the Java-accessible and wrapped    84             # method names.    85     86             method_name = method.get_python_name()    87             method_names.append((method_name, wrapped_method_name))    88     89         # Produce method entries for the specially named methods.    90     91         for method_name, wrapped_method_name in method_names:    92             f.write("setattr(%s, '%s', %s.%s)\n" % (class_name, method_name, class_name, wrapped_method_name))    93     94         # Remove the original class.    95     96         print "Removing", filename    97         os.remove(filename)    98     99     f.close()   100    101 # vim: tabstop=4 expandtab shiftwidth=4