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.
7 from string import Template
9 from code_generator import CodeGenerator
10 from java_method import Method
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)
18 self._generated_class_name = self._java_data.bridge_name
19 self._generated_code = self.GenerateBridgeClass()
21 def GenerateBridgeClass(self):
22 bridge_class_template = Template("""\
26 public class ${CLASS_NAME} extends ${PARENT_CLASS} {
27 private final static String WRAPPER_CLASS = "org.xwalk.core.Object";
28 private Object wrapper;
30 public Object getWrapper() {
33 ${CREATE_INTERNALLY_CONSTRUCTOR}
37 ${REFLECTION_INIT_SECTION}
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)
64 def GenerateCreateInternallyConstructor(self):
65 if not self._java_data.HasCreateInternallyAnnotation():
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);
75 } catch (Exception e) {
76 ReflectionHelper.handleException(e);
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)
90 def GenerateBridgeEnums(self):
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());
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)
107 def GenerateBridgeMethods(self):
109 for method in self._java_data.methods:
110 methods_string += method.GenerateMethodsStringForBridge()
111 return methods_string
113 def GenerateReflectionInitString(self):
114 ref_methods_string = ''
116 ref_enum_template = Template("""\
117 ${ENUM} = clazz.getClassLoader().loadClass("${ENUM_CLASS}");
118 ${METHOD} = ${ENUM}.getMethod("valueOf", String.class);
120 for enum in self._java_data.enums.values():
121 value = { 'ENUM': enum.EnumClassName(),
122 'ENUM_CLASS': self._java_data.GetFullWrapperName(
124 'METHOD': enum.EnumMethodValueOfName()}
125 ref_methods_string += ref_enum_template.substitute(value)
127 ref_method_template = Template("""\
128 ${METHOD_DECLARE_NAME} = ReflectionHelper.loadMethod(\
129 clazz, \"${METHOD}\"${PARAMS});
131 for method in self._java_data.methods:
132 if method.is_constructor or method.is_static:
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)
139 ref_init_template = Template("""\
140 private void reflectionInit() throws NoSuchMethodException,
141 ClassNotFoundException {
142 Class<?> clazz = wrapper.getClass();
146 value = {'REF_METHODS': ref_methods_string}
147 ref_init_string = ref_init_template.substitute(value)
148 return ref_init_string
150 def GenerateStaticInitializerString(self):
151 if not self._java_data.HasCreateInternallyAnnotation():
153 static_initializer_template = Template("""\
155 ReflectionHelper.registerConstructor("${STATIC_CONSTRUCTOR_NAME}", \
156 "${FULL_CLASS_NAME}", Object.class);
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)