Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / xwalk / tools / reflection_generator / bridge_generator.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2014 Intel Corporation. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 from string import Template
8
9 from code_generator import CodeGenerator
10 from java_method import Method
11
12 class BridgeGenerator(CodeGenerator):
13   """ Generator class that generates bridge layer code."""
14   def __init__(self, java_data, class_loader):
15     super(BridgeGenerator, self).__init__(java_data, class_loader)
16
17   def RunTask(self):
18     self._generated_class_name = self._java_data.bridge_name
19     self._generated_code = self.GenerateBridgeClass()
20
21   def GenerateBridgeClass(self):
22     bridge_class_template = Template("""\
23 ${PACKAGE_SECTION}
24
25 ${IMPORT_SECTION}
26 public class ${CLASS_NAME} extends ${PARENT_CLASS} {
27     private final static String WRAPPER_CLASS = "org.xwalk.core.Object";
28     private Object wrapper;
29
30     public Object getWrapper() {
31         return wrapper;
32     }
33 ${CREATE_INTERNALLY_CONSTRUCTOR}
34 ${ENUMS_SECTION}
35 ${METHODS_SECTION}
36
37 ${REFLECTION_INIT_SECTION}
38 ${STATIC_INITIALIZER}
39 }
40 """)
41     package_name = ''
42     if self._java_data.package_name != '':
43       package_name = 'package ' + self._java_data.package_name + ";"
44     imports_string = self.GenerateImportRules()
45     internal_class_name = self._java_data.class_name
46     bridge_class_name = self._generated_class_name
47     create_internally_constructor = self.GenerateCreateInternallyConstructor()
48     bridge_enums = self.GenerateBridgeEnums()
49     bridge_methods = self.GenerateBridgeMethods()
50     reflection_init = self.GenerateReflectionInitString()
51     static_initializer = self.GenerateStaticInitializerString()
52     value = {'PACKAGE_SECTION': package_name,
53              'IMPORT_SECTION': imports_string,
54              'CLASS_NAME': bridge_class_name,
55              'PARENT_CLASS': internal_class_name,
56              'ENUMS_SECTION': bridge_enums,
57              'METHODS_SECTION': bridge_methods,
58              'REFLECTION_INIT_SECTION': reflection_init,
59              'CREATE_INTERNALLY_CONSTRUCTOR': create_internally_constructor,
60              'STATIC_INITIALIZER': static_initializer}
61     class_content = bridge_class_template.substitute(value)
62     return class_content
63
64   def GenerateCreateInternallyConstructor(self):
65     if not self._java_data.HasCreateInternallyAnnotation():
66       return ''
67     constructor_template = Template("""\
68     private ${INTERNAL_CLASS_NAME} internal = null;
69     ${BRIDGE_CLASS_NAME}(${INTERNAL_CLASS_NAME} internal) {
70         this.internal = internal;
71         this.wrapper = ReflectionHelper.createInstance(\
72 "${STATIC_CONSTRUCTOR_NAME}", this);
73         try {
74           reflectionInit();
75         } catch (Exception e) {
76           ReflectionHelper.handleException(e);
77         }
78     }
79 """)
80     internal_class_name = self._java_data.class_name
81     bridge_class_name = self._generated_class_name
82     constructor_method = Method(self._java_data.class_name, self._class_loader,
83         True, False, False, bridge_class_name, '', '', '')
84     static_constructor_name = constructor_method.GetMethodDeclareName()
85     value = {'INTERNAL_CLASS_NAME': internal_class_name,
86              'BRIDGE_CLASS_NAME': bridge_class_name,
87              'STATIC_CONSTRUCTOR_NAME': static_constructor_name}
88     return constructor_template.substitute(value)
89
90   def GenerateBridgeEnums(self):
91     enums_string = ''
92     enum_template = Template("""\
93     private Class<?> ${ENUM_CLASS_NAME};
94     private Method ${ENUM_VALUE_OF_METHOD};
95     private Object Convert${ENUM_TYPE}(${ENUM_TYPE} type) {
96         return ReflectionHelper.invokeMethod(${ENUM_VALUE_OF_METHOD}, \
97 null, type.toString());
98     }
99 """)
100     for enum in self._java_data.enums.values():
101       value = {'ENUM_CLASS_NAME': enum.EnumClassName(),
102                'ENUM_VALUE_OF_METHOD': enum.EnumMethodValueOfName(),
103                'ENUM_TYPE': enum.enum_name}
104       enums_string += enum_template.substitute(value)
105     return enums_string
106
107   def GenerateBridgeMethods(self):
108     methods_string = ''
109     for method in self._java_data.methods:
110       methods_string += method.GenerateMethodsStringForBridge()
111     return methods_string
112
113   def GenerateReflectionInitString(self):
114     ref_methods_string = ''
115
116     ref_enum_template = Template("""\
117         ${ENUM} = clazz.getClassLoader().loadClass("${ENUM_CLASS}");
118         ${METHOD} = ${ENUM}.getMethod("valueOf", String.class);
119 """)
120     for enum in self._java_data.enums.values():
121       value = { 'ENUM': enum.EnumClassName(),
122                 'ENUM_CLASS': self._java_data.GetFullWrapperName(
123                     enum.enum_name),
124                 'METHOD': enum.EnumMethodValueOfName()}
125       ref_methods_string += ref_enum_template.substitute(value)
126
127     ref_method_template = Template("""\
128         ${METHOD_DECLARE_NAME} = ReflectionHelper.loadMethod(\
129 clazz, \"${METHOD}\"${PARAMS});
130 """)
131     for method in self._java_data.methods:
132       if method.is_constructor or method.is_static:
133         continue
134       value = { 'METHOD_DECLARE_NAME': method.GetMethodDeclareName(),
135                 'METHOD': method.method_name,
136                 'PARAMS': method.GetBridgeParamsStringDeclareForWrapper()}
137       ref_methods_string += ref_method_template.substitute(value)
138
139     ref_init_template = Template("""\
140     private void reflectionInit() throws NoSuchMethodException,
141             ClassNotFoundException {
142         Class<?> clazz = wrapper.getClass();
143 ${REF_METHODS}
144     }
145 """)
146     value = {'REF_METHODS': ref_methods_string}
147     ref_init_string = ref_init_template.substitute(value)
148     return ref_init_string
149
150   def GenerateStaticInitializerString(self):
151     if not self._java_data.HasCreateInternallyAnnotation():
152       return ''
153     static_initializer_template = Template("""\
154     static {
155         ReflectionHelper.registerConstructor("${STATIC_CONSTRUCTOR_NAME}", \
156 "${FULL_CLASS_NAME}", Object.class);
157     }
158 """)
159     bridge_class_name = self._java_data.bridge_name
160     constructor_method = Method(self._java_data.class_name, self._class_loader,
161         True, False, False, bridge_class_name, '', '', '')
162     static_constructor_name = constructor_method.GetMethodDeclareName()
163     full_class_name = self._java_data.GetFullWrapperName()
164     value = {'STATIC_CONSTRUCTOR_NAME': static_constructor_name,
165              'FULL_CLASS_NAME': full_class_name}
166     return static_initializer_template.substitute(value)