3 # Copyright (c) 2016 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from string import Template
23 type_template = Template("""
24 package $plugin_package.$type_package;
27 * <p>This class represents $c_type_name type definition.
28 * <br>It was generated by types_gen.py based on $inputfile preparsed data:
33 public final class $java_type_name {
39 field_template = Template(""" public $type $name;\n""")
42 def generate_type_fields(type_definition):
44 Generates fields for class representing typeonly definition
45 :param type_definition: python representation of typeonly definition
46 :return: string representing class fields
49 for t in zip(type_definition['types'], type_definition['args']):
50 field_name = util.underscore_to_camelcase(t[1])
51 fields += field_template.substitute(type=util.jni_2_java_type_mapping[t[0]],
55 object_struct_setter_template = Template("""
57 jclass ${field_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
58 memset (&(mp->${c_name}), 0, sizeof (mp->${c_name}));
59 ${struct_initialization}
63 object_array_struct_setter_template = Template("""
65 jclass ${field_reference_name}ArrayElementClass = (*env)->FindClass(env, "${class_FQN}");
66 if (${field_reference_name}) {
68 jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
70 for (_i = 0; _i < cnt; _i++) {
71 jobject ${field_reference_name}ArrayElement = (*env)->GetObjectArrayElement(env, ${field_reference_name}, _i);
72 memset (&(mp->${c_name}[_i]), 0, sizeof (mp->${c_name}[_i]));
73 ${struct_initialization}
79 object_dto_field_setter_template = Template("""
81 jclass ${field_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
82 jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V");
83 jobject ${field_reference_name} = (*env)->NewObject(env, ${field_reference_name}Class, ${field_reference_name}Constructor);
84 ${type_initialization}
85 (*env)->SetObjectField(env, dto, ${field_reference_name}FieldId, ${field_reference_name});
89 object_array_dto_field_setter_template = Template("""
91 jclass ${field_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
92 jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
94 for (_i = 0; _i < ${field_length}; _i++) {
95 jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V");
96 jobject ${field_reference_name}ArrayElement = (*env)->NewObject(env, ${field_reference_name}Class, ${field_reference_name}Constructor);
97 ${type_initialization}
98 (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
100 (*env)->SetObjectField(env, dto, ${field_reference_name}FieldId, ${field_reference_name});
105 def generate_struct_initialization(type_def, c_name_prefix, object_name, indent):
106 struct_initialization = ""
108 for t in zip(type_def['types'], type_def['args'], type_def['lengths']):
109 field_reference_name = "${c_name}" + util.underscore_to_camelcase_upper(t[1])
110 field_name = util.underscore_to_camelcase(t[1])
111 struct_initialization += jni_gen.jni_request_identifiers_for_type(field_type=t[0],
112 field_reference_name=field_reference_name,
113 field_name=field_name,
114 object_name=object_name)
115 struct_initialization += jni_gen.jni_request_binding_for_type(field_type=t[0], c_name=c_name_prefix + t[1],
116 field_reference_name=field_reference_name,
117 field_length=t[2][0],
118 is_variable_len_array=t[2][1])
119 return indent + struct_initialization.replace('\n', '\n' + indent)
122 def generate_type_setter(handler_name, type_def, c_name_prefix, object_name, indent):
123 type_initialization = ""
124 for t in zip(type_def['types'], type_def['args'], type_def['lengths']):
125 field_length = t[2][0]
126 is_variable_len_array = t[2][1]
127 length_field_type = None
128 if is_variable_len_array:
129 length_field_type = type_def['types'][type_def['args'].index(field_length)]
130 type_initialization += jni_gen.jni_reply_handler_for_type(handler_name=handler_name,
131 ref_name="${field_reference_name}",
132 field_type=t[0], c_name=c_name_prefix + t[1],
133 field_reference_name="${c_name}" + util.underscore_to_camelcase_upper(t[1]),
134 field_name=util.underscore_to_camelcase(t[1]),
135 field_length=field_length,
136 is_variable_len_array=is_variable_len_array,
137 length_field_type=length_field_type,
138 object_name=object_name)
139 return indent + type_initialization.replace('\n', '\n' + indent)
142 def generate_types(types_list, plugin_package, types_package, inputfile):
144 Generates Java representation of custom types defined in api file.
149 print "Skipping custom types generation (%s does not define custom types)." % inputfile
152 print "Generating custom types"
154 if not os.path.exists(types_package):
155 os.mkdir(types_package)
157 for type in types_list:
158 c_type_name = type['name']
159 java_type_name = util.underscore_to_camelcase_upper(type['name'])
160 dto_path = os.path.join(types_package, java_type_name + ".java")
162 fields = generate_type_fields(type)
164 dto_file = open(dto_path, 'w')
165 dto_file.write(type_template.substitute(plugin_package=plugin_package,
166 type_package=types_package,
167 c_type_name=c_type_name,
169 docs=util.api_message_to_javadoc(type),
170 java_type_name=java_type_name,
172 methods=dto_gen.generate_dto_base_methods(java_type_name, type)
175 # update type mappings:
176 # todo fix vpe.api to use type_name instead of vl_api_type_name_t
177 type_name = "vl_api_" + c_type_name + "_t"
178 java_fqn = "%s.%s.%s" % (plugin_package, types_package, java_type_name)
179 util.vpp_2_jni_type_mapping[type_name] = "jobject"
180 util.vpp_2_jni_type_mapping[type_name + "[]"] = "jobjectArray"
181 util.jni_2_java_type_mapping[type_name] = java_fqn
182 util.jni_2_java_type_mapping[type_name + "[]"] = java_fqn + "[]"
183 jni_name = java_fqn.replace('.', "/")
184 jni_signature = "L" + jni_name + ";"
185 util.jni_2_signature_mapping[type_name] = "L" + jni_name + ";"
186 util.jni_2_signature_mapping[type_name + "[]"] = "[" + jni_signature
187 util.jni_field_accessors[type_name] = "ObjectField"
188 util.jni_field_accessors[type_name + "[]"] = "ObjectField"
190 jni_gen.struct_setter_templates[type_name] = Template(
191 object_struct_setter_template.substitute(
193 field_reference_name="${field_reference_name}",
195 struct_initialization=generate_struct_initialization(type, "${c_name}.",
196 "${field_reference_name}", ' ' * 4))
199 jni_gen.struct_setter_templates[type_name+ "[]"] = Template(
200 object_array_struct_setter_template.substitute(
202 field_reference_name="${field_reference_name}",
203 field_length_check="${field_length_check}",
205 struct_initialization=generate_struct_initialization(type, "${c_name}[_i].",
206 "${field_reference_name}ArrayElement", ' ' * 8))
209 jni_gen.dto_field_setter_templates[type_name] = Template(
210 object_dto_field_setter_template.substitute(
211 field_reference_name="${field_reference_name}",
212 field_length="${field_length}",
214 type_initialization=generate_type_setter(c_type_name, type, "${c_name}.",
215 "${field_reference_name}", ' ' * 4))
218 jni_gen.dto_field_setter_templates[type_name + "[]"] = Template(
219 object_array_dto_field_setter_template.substitute(
220 field_reference_name="${field_reference_name}",
221 field_length="${field_length}",
223 type_initialization=generate_type_setter(c_type_name, type, "${c_name}[_i].",
224 "${field_reference_name}ArrayElement", ' ' * 8))