HONEYCOMB-10: jVpp - the new java API. C code and jar file generation

Added comments generation for C and Java files.

Change-Id: Ifb670a5592eb871bfe68804f0a8d8f9b5b14f00a
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Signed-off-by: Ed Warnicke <eaw@cisco.com>
This commit is contained in:
Marek Gradzki
2016-04-26 12:09:05 +02:00
committed by Ed Warnicke
parent c5e8681b32
commit d85036fd6b
15 changed files with 997 additions and 34 deletions

View File

@ -25,7 +25,11 @@ callback_template = Template("""
package $base_package.$callback_package;
/**
* $docs
* <p>Represents callback for vpe.api message.
* <br>It was generated by callback_gen.py based on $inputfile preparsed data:
* <pre>
$docs
* </pre>
*/
public interface $cls_name extends $base_package.$callback_package.JVppCallback {
@ -38,16 +42,16 @@ global_callback_template = Template("""
package $base_package.$callback_package;
/**
*
*
* Global aggregated callback interface
* <p>Global aggregated callback interface.
* <br>It was generated by callback_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public interface JVppGlobalCallback extends $callbacks {
}
""")
def generate_callbacks(func_list, base_package, callback_package, dto_package):
def generate_callbacks(func_list, base_package, callback_package, dto_package, inputfile):
""" Generates callback interfaces """
print "Generating Callback interfaces"
@ -73,7 +77,8 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package):
reply_type = "%s.%s.%s" % (base_package, dto_package, camel_case_name_with_suffix)
method = "void on{0}({1} reply);".format(camel_case_name_with_suffix, reply_type)
callback_file.write(
callback_template.substitute(docs='Generated from ' + str(func),
callback_template.substitute(inputfile=inputfile,
docs=util.api_message_to_javadoc(func),
cls_name=camel_case_name + callback_suffix,
callback_method=method,
base_package=base_package,
@ -82,7 +87,8 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package):
callback_file.close()
callback_file = open(os.path.join(callback_package, "JVppGlobalCallback.java"), 'w')
callback_file.write(global_callback_template.substitute(callbacks=", ".join(callbacks),
callback_file.write(global_callback_template.substitute(inputfile=inputfile,
callbacks=", ".join(callbacks),
base_package=base_package,
callback_package=callback_package))
callback_file.flush()

View File

@ -20,7 +20,11 @@ dto_template = Template("""
package $base_package.$dto_package;
/**
* $docs
* <p>This class represents $description.
* <br>It was generated by dto_gen.py based on $inputfile preparsed data:
* <pre>
$docs
* </pre>
*/
public final class $cls_name implements $base_package.$dto_package.$base_type {
@ -36,8 +40,7 @@ send_template = Template(""" @Override
return jvpp.$method_name($args);
}\n""")
def generate_dtos(func_list, base_package, dto_package):
def generate_dtos(func_list, base_package, dto_package, inputfile):
""" Generates dto objects in a dedicated package """
print "Generating DTOs"
@ -60,6 +63,7 @@ def generate_dtos(func_list, base_package, dto_package):
methods = ""
base_type = ""
if util.is_reply(camel_case_dto_name):
description = "vpe.api reply DTO"
request_dto_name = get_request_name(camel_case_dto_name, func['name'])
if util.is_details(camel_case_dto_name):
# FIXME assumption that dump calls end with "Dump" suffix. Not enforced in vpe.api
@ -75,11 +79,15 @@ def generate_dtos(func_list, base_package, dto_package):
args=args)
if util.is_dump(camel_case_dto_name):
base_type += "JVppDump"
description = "vpe.api dump request DTO"
else:
base_type += "JVppRequest"
description = "vpe.api request DTO"
dto_file = open(dto_path, 'w')
dto_file.write(dto_template.substitute(docs='Generated from ' + str(func),
dto_file.write(dto_template.substitute(inputfile=inputfile,
description=description,
docs=util.api_message_to_javadoc(func),
cls_name=camel_case_dto_name,
fields=fields,
methods=methods,
@ -89,13 +97,12 @@ def generate_dtos(func_list, base_package, dto_package):
dto_file.flush()
dto_file.close()
flush_dump_reply_dtos()
flush_dump_reply_dtos(inputfile)
dump_dto_suffix = "ReplyDump"
dump_reply_artificial_dtos = {}
# Returns request name or special one from unconventional_naming_rep_req map
def get_request_name(camel_case_dto_name, func_name):
return util.underscore_to_camelcase_upper(
@ -103,12 +110,14 @@ def get_request_name(camel_case_dto_name, func_name):
else util.remove_reply_suffix(camel_case_dto_name)
def flush_dump_reply_dtos():
def flush_dump_reply_dtos(inputfile):
for dump_reply_artificial_dto in dump_reply_artificial_dtos.values():
dto_path = os.path.join(dump_reply_artificial_dto['dto_package'],
dump_reply_artificial_dto['cls_name'] + ".java")
dto_file = open(dto_path, 'w')
dto_file.write(dto_template.substitute(docs=dump_reply_artificial_dto['docs'],
dto_file.write(dto_template.substitute(inputfile=inputfile,
description="vpe.api dump reply wrapper",
docs=dump_reply_artificial_dto['docs'],
cls_name=dump_reply_artificial_dto['cls_name'],
fields=dump_reply_artificial_dto['fields'],
methods=dump_reply_artificial_dto['methods'],
@ -133,7 +142,7 @@ def generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_c
dump_reply_artificial_dtos[request_dto_name]['fields'] = \
dump_reply_artificial_dtos[request_dto_name]['fields'] + '\n' + fields
else:
dump_reply_artificial_dtos[request_dto_name] = ({'docs': 'Dump reply wrapper generated from ' + str(func),
dump_reply_artificial_dtos[request_dto_name] = ({'docs': util.api_message_to_javadoc(func),
'cls_name': cls_name,
'fields': fields,
'methods': "",

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,11 @@ import dto_gen
jvpp_ifc_template = Template("""
package $base_package.$callback_facade_package;
/**
* <p>Callback Java API representation of vpe.api.
* <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public interface CallbackJVpp extends java.lang.AutoCloseable {
@Override
@ -36,6 +41,11 @@ $methods
jvpp_impl_template = Template("""
package $base_package.$callback_facade_package;
/**
* <p>Default implementation of CallbackJVpp interface.
* <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public final class CallbackJVppFacade implements $base_package.$callback_facade_package.CallbackJVpp {
private final $base_package.JVpp jvpp;
@ -78,7 +88,7 @@ no_arg_method_impl_template = Template(""" public final void $name($base_pack
""")
def generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package):
def generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile):
""" Generates callback facade """
print "Generating JVpp callback facade"
@ -131,7 +141,8 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
join = os.path.join(callback_facade_package, "CallbackJVpp.java")
jvpp_file = open(join, 'w')
jvpp_file.write(
jvpp_ifc_template.substitute(methods="\n".join(methods),
jvpp_ifc_template.substitute(inputfile=inputfile,
methods="\n".join(methods),
base_package=base_package,
dto_package=dto_package,
callback_facade_package=callback_facade_package))
@ -139,7 +150,8 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
jvpp_file.close()
jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacade.java"), 'w')
jvpp_file.write(jvpp_impl_template.substitute(methods="\n".join(methods_impl),
jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
methods="\n".join(methods_impl),
base_package=base_package,
dto_package=dto_package,
callback_package=callback_package,
@ -147,14 +159,16 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
jvpp_file.flush()
jvpp_file.close()
generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package)
generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile)
jvpp_facade_callback_template = Template("""
package $base_package.$callback_facade_package;
/**
* Async facade callback setting values to future objects
* <p>JVppGlobalCallback implementation for Java Callback API.
* <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public final class CallbackJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
@ -185,7 +199,7 @@ jvpp_facade_callback_method_template = Template("""
""")
def generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package):
def generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile):
callbacks = []
for func in func_list:
@ -204,7 +218,8 @@ def generate_callback(func_list, base_package, dto_package, callback_package, ca
callback_dto=camel_case_name_with_suffix))
jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacadeCallback.java"), 'w')
jvpp_file.write(jvpp_facade_callback_template.substitute(base_package=base_package,
jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
base_package=base_package,
dto_package=dto_package,
callback_package=callback_package,
methods="".join(callbacks),

View File

@ -22,7 +22,9 @@ jvpp_facade_callback_template = Template("""
package $base_package.$future_package;
/**
* Async facade callback setting values to future objects
* <p>Async facade callback setting values to future objects
* <br>It was generated by jvpp_future_facade_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public final class FutureJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
@ -119,7 +121,7 @@ jvpp_facade_details_callback_method_template = Template("""
""")
def generate_jvpp(func_list, base_package, dto_package, callback_package, future_facade_package):
def generate_jvpp(func_list, base_package, dto_package, callback_package, future_facade_package, inputfile):
""" Generates JVpp interface and JNI implementation """
print "Generating JVpp future facade"
@ -159,7 +161,8 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, future
callback_dto=camel_case_name_with_suffix))
jvpp_file = open(os.path.join(future_facade_package, "FutureJVppFacadeCallback.java"), 'w')
jvpp_file.write(jvpp_facade_callback_template.substitute(base_package=base_package,
jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
base_package=base_package,
dto_package=dto_package,
callback_package=callback_package,
methods="".join(callbacks),

131
vpp-api/java/jvpp/gen/jvpp_gen.py Executable file
View File

@ -0,0 +1,131 @@
#!/usr/bin/env python
#
# Copyright (c) 2016 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
# l
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import argparse
import importlib
import sys
import callback_gen
import dto_gen
import jvpp_callback_facade_gen
import jvpp_future_facade_gen
import jvpp_impl_gen
import jvpp_c_gen
import util
# Invocation:
# ~/Projects/vpp/vpp-api/jvpp/gen$ mkdir -p java/org/openvpp/jvpp && cd java/org/openvpp/jvpp
# ~/Projects/vpp/vpp-api/jvpp/gen/java/org/openvpp/jvpp$ ../../../../jvpp_gen.py -idefs_api_vpp_papi.py
#
# Compilation:
# ~/Projects/vpp/vpp-api/jvpp/gen/java/org/openvpp/jvpp$ javac *.java dto/*.java callback/*.java
#
# where
# defs_api_vpp_papi.py - vpe.api in python format (generated by vppapigen)
from util import vpp_2_jni_type_mapping
parser = argparse.ArgumentParser(description='VPP Java API generator')
parser.add_argument('-i', action="store", dest="inputfile")
args = parser.parse_args()
sys.path.append(".")
inputfile = args.inputfile.replace('.py', '')
cfg = importlib.import_module(inputfile, package=None)
# FIXME: functions unsupported due to problems with vpe.api
def is_supported(f_name):
return f_name not in {'vnet_ip4_fib_counters', 'vnet_ip6_fib_counters'}
def is_request_field(field_name):
return field_name not in {'_vl_msg_id', 'client_index', 'context'}
def is_response_field(field_name):
return field_name not in {'_vl_msg_id'}
def get_args(t, filter):
arg_list = []
for i in t:
if not filter(i[1]):
continue
arg_list.append(i[1])
return arg_list
def get_types(t, filter):
types_list = []
c_types_list = []
for i in t:
if not filter(i[1]):
continue
if len(i) is 3: # array type
types_list.append(vpp_2_jni_type_mapping[i[0]] + 'Array')
c_types_list.append(i[0] + '[]')
else: # primitive type
types_list.append(vpp_2_jni_type_mapping[i[0]])
c_types_list.append(i[0])
return types_list, c_types_list
def get_definitions():
# Pass 1
func_list = []
func_name = {}
for a in cfg.vppapidef:
if not is_supported(a[0]):
continue
java_name = util.underscore_to_camelcase(a[0])
# For replies include all the arguments except message_id
if util.is_reply(java_name):
types, c_types = get_types(a[1:], is_response_field)
func_name[a[0]] = dict(
[('name', a[0]), ('java_name', java_name),
('args', get_args(a[1:], is_response_field)), ('full_args', get_args(a[1:], lambda x: True)),
('types', types), ('c_types', c_types)])
# For requests skip message_id, client_id and context
else:
types, c_types = get_types(a[1:], is_request_field)
func_name[a[0]] = dict(
[('name', a[0]), ('java_name', java_name),
('args', get_args(a[1:], is_request_field)), ('full_args', get_args(a[1:], lambda x: True)),
('types', types), ('c_types', c_types)])
# Indexed by name
func_list.append(func_name[a[0]])
return func_list, func_name
func_list, func_name = get_definitions()
base_package = 'org.openvpp.jvpp'
dto_package = 'dto'
callback_package = 'callback'
future_package = 'future'
# TODO find better package name
callback_facade_package = 'callfacade'
dto_gen.generate_dtos(func_list, base_package, dto_package, args.inputfile)
jvpp_impl_gen.generate_jvpp(func_list, base_package, dto_package, args.inputfile)
callback_gen.generate_callbacks(func_list, base_package, callback_package, dto_package, args.inputfile)
jvpp_c_gen.generate_jvpp(func_list, args.inputfile)
jvpp_future_facade_gen.generate_jvpp(func_list, base_package, dto_package, callback_package, future_package, args.inputfile)
jvpp_callback_facade_gen.generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package, args.inputfile)

View File

@ -19,6 +19,12 @@ from string import Template
jvpp_ifc_template = Template("""
package $base_package;
/**
* <p>Java representation of vpe.api.
* <br>It was generated by jvpp_impl_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public interface JVpp extends java.lang.AutoCloseable {
/**
@ -36,6 +42,11 @@ $methods
jvpp_impl_template = Template("""
package $base_package;
/**
* <p>Default implementation of JVpp interface.
* <br>It was generated by jvpp_impl_gen.py based on $inputfile
* <br>(python representation of vpe.api generated by vppapigen).
*/
public final class JVppImpl implements $base_package.JVpp {
private final $base_package.VppConnection connection;
@ -82,7 +93,7 @@ no_arg_method_impl_template = Template(""" public final int $name() {
""")
def generate_jvpp(func_list, base_package, dto_package):
def generate_jvpp(func_list, base_package, dto_package, inputfile):
""" Generates JVpp interface and JNI implementation """
print "Generating JVpp"
@ -126,14 +137,16 @@ def generate_jvpp(func_list, base_package, dto_package):
jvpp_file = open("JVpp.java", 'w')
jvpp_file.write(
jvpp_ifc_template.substitute(methods="\n".join(methods),
jvpp_ifc_template.substitute(inputfile=inputfile,
methods="\n".join(methods),
base_package=base_package,
dto_package=dto_package))
jvpp_file.flush()
jvpp_file.close()
jvpp_file = open("JVppImpl.java", 'w')
jvpp_file.write(jvpp_impl_template.substitute(methods="\n".join(methods_impl),
jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
methods="\n".join(methods_impl),
base_package=base_package,
dto_package=dto_package))
jvpp_file.flush()

View File

@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import os, pprint
from os import removedirs
@ -171,3 +171,8 @@ def remove_suffix(camel_case_name_with_suffix, suffix):
def is_control_ping(camel_case_name_with_suffix):
return "controlping" in camel_case_name_with_suffix.lower()
def api_message_to_javadoc(api_message):
""" Converts vpe.api message description to javadoc """
str = pprint.pformat(api_message, indent=4, width=120, depth=None)
return " * " + str.replace("\n", "\n * ")